text:
<?xml version="1.0" encoding="utf-8"?><Search><pages Count="15"><page Index="1"><![CDATA[Master of Professional Studies in
       Organization Development and Change

                       (MPS-OD&C)

    A Guidebook
           for

MPS-OD&C Students

                                                                                PAGE 1]]></page><page Index="2"><![CDATA[Table of Contents

• Overview

• Key Concept 1: What is Organization Development & Change

• Key Concept 2: Vision and Goals of MPS-OD&C

• Key Concept 3: Program Structure: Courses, Certificates, and Digital badges

• Key Concept 4: Online Course Structure

• Key Concept 5: Completion of SARI Online Course Requirement

• Key Concept 6: Faculty/Staff & About WF ED Doctoral Program

• Key Concept 7: Area of Focus and Career Options

• Key Concept 8: Career Map of OD Practitioners

• Key Concept 9: Formulation of e-Portfolio

• Key Concept 10: Social Networking Opportunities

• Key Concept 11: Organization Development Resources

• Summary

• Further Resources & FAQ

• Knowledge Check

                                                               PAGE 2]]></page><page Index="3"><![CDATA[Overview

Welcome to MPS-OD&C Program!

The purpose of student guidebook for MPS-OD&C is to better prepare you
for the first semester and acclimate students into the community of Penn
State's Organization Development and Change Community by providing
comprehensive introduction to the MPS-OD&C program. The course aims
to familiarize you with the basic knowledge of organization development
as well as the basic information of the MPS-OD&C program.
At the end of this information-packed course, you will be able to:

   • Differentiate 'Organization Development (OD)' from 'Organizational
      Development'.

   • Attribute OD Effectiveness ModelTM as a basic OD&C process.
   • Internalize the vision and goals of the MPS-OD&C program.
   • Summarize the program, course structure, requirements, and

      suggestion of course sequence.
   • Recognize the importance of research ethics and how to meet the

      SARI (Scholarship and Research Integrity) requirement.
   • Develop strategies to share your information through e-Portfolio, and

      network with other OD professional via social media such as LinkedIn
      and Facebook.

                                                                                PAGE 3]]></page><page Index="4"><![CDATA[Key Concept

             1

 What is Organization
 Development & Change?

    "You must be the change you wish to see in the world."
                                                       - Mahatma Gandhi

The ability to manage change is becoming the most important skill for workers
and managers in the future. To quote Mahatma Gandhi, 'You must be the
change you wish to see in the world.' That means that leaders, managers, and
workers of the future must be capable of serving as outstanding role models
of what they wish to see the world be and become.

What is Organization Development (OD)?

First, let us start by explaining that Organization Development (OD) is all
about a humanistic approach to changing organizations. It is a bottoms-
up vs. top-down approach. To put it a different way, consider that the
traditional top-down organizational structure is where many employees' goals
are often to please the boss.

                                                                                PAGE 4]]></page><page Index="5"><![CDATA[Figure 1.1. Traditional top-down organizational structure

Consider now if we flipped our approach and placed the customer on top
and structured our organizations so that work groups were empowered to
think innovatively about how to better serve customers and improve
processes. This is the focus of Organization Development (OD).
Organization Development (OD) is a "bottoms-up" facilitative approach but
Organizational Development is a "top- down" directive approach.

           Figure 1.2. Bottoms-up Organization Development (OD) approach

                                                                                PAGE 5]]></page><page Index="6"><![CDATA[How is Organization Development (OD) defined?

Organization Development (OD) is a change effort that is carried out in a
participative way, involving those affected by the change, and that uses action
research as a key roadmap for the change. While OD change efforts can be
focused on individuals, most OD efforts are geared to changing groups or
entire organizations. (Rothwell, 2014)
Here are FOUR main characteristics of OD adapted from Dr. William J. Rothwell
(2014):

       OD focuses on group change.

It thus differs from other change efforts, like training, that are directed toward
changing individuals. Like training, however, OD seeks to bring about change
by equipping people with new knowledge, skills and attitudes. Unlike training,
however, OD often seeks to create a new organizational culture. Culture can
be understood to mean the often taken-for-granted expectations of people in
organizations about the right way to do things. Training is seldom able to
change culture because it brings about change one-person-at-a-time, which
does not create a critical mass (a sufficient number of people at one time) for
change in the same way that OD efforts are intended to do.

                                                                                PAGE 6]]></page><page Index="7"><![CDATA[OD usually focuses on long-term change.

It thus differs from training, which seeks short-term change by giving people
new knowledge and skills that they can apply immediately on their jobs.
Unlike training, however, OD focuses on changing groups or organizations.
Since groups and organizations simply take longer to change than individuals
do, OD efforts are often necessarily long-term. Some authorities have
estimated, for instance, that, to install a large-scale change in a major
corporation, timeframes of 4-6 years should not be considered unusual.
Generally speaking, the larger the group or organization that is to undergo the
change and the more radical the change effort, the longer it will take.

       OD often relies on assistance from external or internal
       OD consultants.

An OD consultant, individuals from outside or inside the immediate area in
which the change is to occur and whose role is to facilitate, rather than direct,
the change effort. An OD consultant may, for instance, be hired from outside
the organization. Alternatively, an internal consultant may be brought into the
setting from another division--such as the HRD department or the HR
department. OD consultants who do work in OD have a special name and are
called change agents because they are agents of change.

       OD is inherently participative in nature.

Individuals in the group or organization needing change are involved in all
phases of the change process. Often they define and frame the problems
calling for change, reach agreement on the problems, define and frame the
solutions that can be implemented to solve the problems, devise their own
action plan for installing the change, take active roles in the installation effort,
and play a major role in evaluating results.

                                                                                PAGE 7]]></page><page Index="8"><![CDATA[OD Effectiveness ModelTM

    The Penn State Organization Development (OD) Effectiveness Model's
    approach entails three stages: (a) building on experience, (b) using
    constructive feedback, and (c) learning from other disciplines, particularly
    innovation diffusion research. The OD Effectiveness model as shown below in
    Figure 2.1 considers other aspects of existing models for more effective
    organization development and change.

                               Figure 1.3. OD Effectiveness Model TM

Note: This model should bear a trademark. It is trademarked by the Master of Professional Studies in Organization Development an
        d Change Program at The Pennsylvania State University. All rights reserved. It could also be, or alternatively be, copyrighted.

                                                                                PAGE 8]]></page><page Index="9"><![CDATA[This model stresses an individual approach to change and the importance of
interpersonal and technological communication networks. Many models of
change focus on a normative/reeducative approach to behavioral changes on
the part of individuals when people are driven by self-interest (Duck, 2001).
These models imply authority-driven, top-down approaches when managing
change for persons wanting reliable communications in making independent
and voluntary change decisions (Smollan, 2013; Zhou, 2008). This new model
complements current change models by stressing the importance of the
change process for both the individual and the organization.

       1st Phase: Inquiring

Organizations and individuals are always changing as they pursue a better
future. Previous change models have relied primarily on one of two
approaches to understanding the present: (a) assessing data that represent
value-neutral reality and (b) being involved in communication that reveals
an individual's notion of reality. Being aware that objective/subjective goals,
capabilities, and cultures coexist in an organization, one needs to consider
the present by using the two approaches simultaneously and interpreted
from perspectives of both initiators and adopters of change. To emphasize
once more, there is no "one best way" to manage change.
Unless an organization is entirely dysfunctional, all issues and opportunities
identified from the appraisal must be considered. Before developing an
effective strategy, one must assess an organization's communication practice
and overall structure. A comprehensive understanding of how decisions are
made as well as the structure of formal/informal communication networks
and information technology systems is vital for developing effective
strategies for any future changes. Success depends on one's approach.

                                                                                PAGE 9]]></page><page Index="10"><![CDATA[2nd Phase: Strategizing

You must not be misled by thinking the future is something concrete. Instead,
the future is always changing. You must keep this point in mind and always be
ready to redefine and adjust your expectations.
You must consider the aspects of each option and how it may apply to target
groups and individuals, their overall readiness to change, and the
organizational communication network. You should also maintain the level of
commitment on the part of top leaders, as they are the primary instigators of
change and must be aware that change must happen at all levels.
It is best to consider different change options with potential benefits and
costs. These include those with potential crises, plausible possibilities, and the
expected communication patterns and responses among the target audience.
Doing this is particularly important for making sound decisions regarding any
changes that are to be made.

       3rd Phase: Planning

Besides planning the time frame and resources, a communication scheme
must be designed with two core components: (a) framing messages so that
people will be more aware of certain aspects of the scope of the changes and
(b) establishing communication networks to engage messengers and
technologies in communicating the initiative effectively.
For example, information and messages need to be understandable,
advantageous, and compatible; executives, middle managers, opinion leaders,
target individuals, and even potential resisters, along with communication
technologies, need a proper role. Communication should also be assessed
throughout the change process.

                                                                                PAGE 10]]></page><page Index="11"><![CDATA[For any undesirable consequences, such as organizational instability and
members being averse to change, discussion must follow to deal with these
problems. Although it is impossible, of course, to anticipate all the
possibilities, feedback systems must be in place. These will stimulate
communication and lead to any adjustments that need to be made along with
providing for general evaluation after changes are made.

       4th Phase: Doing

Knowledge should be shared to help targeted groups stay informed and
interested in the proposed change (Rogers, 2003). The capacity, effectiveness,
and efficiency of communication technologies should be used to inform
people, and communicators should do their best to influence them.
Opinion leaders must be actively involved because they can influence people.
Knowing is one thing. Doing is another.
Once the change is accepted by the early adopters, a wider audience will likely
be receptive (Centola, 2013) by interaction through communication networks,
opinion leaders, and others. The change initiative continues to develop similar
to but possibly different from what was originally planned. Change leaders
must maintain the momentum and anticipate outcomes, always being flexible
and creative rather than necessarily maintaining predetermined details. Any
negative feedback must be monitored and discussed fully because a poorly
managed process may cause not only the initiative but also the organization to
fail.

                                                                                PAGE 11]]></page><page Index="12"><![CDATA[5th Phase: Revitalizing

After accepting change, living systems keep adjusting as necessary to confirm
or revoke it and even revitalize the change to open the way for additional
changes.
Three major components are involved at this stage: (a) helping sustain the
change, (b) evaluating the effort, and (c) inspiring people to keep renewing
and transforming. While efforts are being made to support change, it still must
be evaluated according to an established plan. Top leaders must still foster
constructive feedback and evaluate processes, consequences, and lessons
learned—always keeping the future in mind.
If formative evaluations have been made to get ongoing feedback as events
develop (Ashely, 2009) and used to modify overall strategies, this phase would
be more positive and rewarding. A follow-through evaluation is also suggested
to see if continuous improvements are being made in the organization with its
people, strategy, process, and structure, and if further changes are possible.
Specific changes may come to a certain conclusion, but organizational change
is constant and must continue.

            Remember
 Organization Development (OD) is a change effort that is carried out in a

     participative way, involving those affected by the change, and that uses
     action research as a key roadmap for the change OD approach that has
     been widely and successfully used in many ways to get "change that
     lasts." That is the key benefit of OD.

                                                                                PAGE 12]]></page><page Index="13"><![CDATA[Remember
 OD Effectiveness ModelTM is a simplified representation of the general

    steps in initiating and carrying out a change process. Managers and OD
    practitioners, when demonstrating the competencies of an OD
    practitioner, are well-advised to rely on the OD Effectiveness model as a
    compass to show them the direction in which to lead the change effort
    and change process.

Enhance Your Learning

Watch the following brief videos, which are featured by Dr. William J.
Rothwell, presenting basics of Organization Development. Each video is
protected by password. If you want to watch videos, put password '572'
on the first screen of each video.

Defining OD                Available at:
History of OD              http://player.vimeo.com/video/295
What is Change Management  39055

                           Available at:
                           http://player.vimeo.com/video/296
                           19167

                           Available at:
                           http://player.vimeo.com/video/301
                           05280

                           PAGE 13]]></page><page Index="14"><![CDATA[Enhance Your Learning

The change models rely primarily on a normative, re-educative, and
innovative approach to behavioral change. A model for change serves as a
compass to guide leaders as they lead or facilitate change efforts. These
models are best understood as simplified representations of the general
steps in initiating and carrying out a change process.
If you are interested in other change models, please visit the following
websites.

Lewin's 3-Phase Change Model  Available at:
                              http://www.change-management-c
Kotter's 8-Step Change Model  onsultant.com/kurt-lewin.html

Various Change Management     Available at:
Models                        http://www.mindtools.com/pages/a
                              rticle/newPPM_82.htm

                              Available at:
                              https://www.scrumalliance.org/com
                              munity/articles/2014/march/change
                              -management-models

                              PAGE 14]]></page><page Index="15"><![CDATA[References

Ashley, S. R. (2009). Innovation diffusion: Implications for evaluation. New
    Directions for Evaluation, 124, 35–45.

Centola, D. M. (2013). Homophily, networks, and critical mass: Solving the start-up
    problem in large group collective action. Rationality and Society, 25(1), 3–40.

Druckman, D., & Bjork, R. A. (1991). In the Mind's Eye: Enhancing human
    performance. Washington, DC: National Academies Press.

Duck, J. D. (2001). The change monster: The human forces that fuel or foil
    corporate transformation and change. New York, NY: Crown Business.

Rogers, E. M. (2003). Diffusion of Innovations (5th ed.). New York, NY: Free Press.
Rothwell, W. J. (2012). Five approaches to change in organizations. In W. J.

    Rothwell (Ed.). Encyclopedia of human resource management: Human resourc
    es and employment forms (pp. 273-282). San Francisco: Pfeiffer.
Rothwell, W. J. (Ed.). (2014). Organization development fundamentals: Managing
    strategic change. Alexandria, VA: Association for Talent Development.
Rothwell, W. J., Stavros, J. M., & Sullivan, R. L. (Eds.). (2015). Practicing
    organization development: A guide for leading change, 4th ed. San Diego:
    Pfeiffer & Co.
Smollan, R. K. (2013). Trust in change managers: The role of affect. Journal of
    Organizational Change Management, 26(4), 725–747.
Zhou, Y. (2008). Voluntary adopters versus forced adopters: Integrating the
    diffusion of innovation theory and the technology acceptance model to study
    intra-organizational adoption. New Media & Society, 10(3), 475–496.

                                                                                PAGE 15]]></page></pages></Search>


text:
namespace Schema.NET.Tool.Models;

using System;
using System.Collections.Generic;
using System.Linq;
using Schema.NET.Tool.Constants;

public class SchemaClass : SchemaObject
{
    private static readonly Uri EnumerationId = new("https://schema.org/Enumeration");

    public SchemaClass(string layer, Uri id, string label, string comment)
        : base(layer, id, label, comment)
    {
    }

    public bool IsEnum => EnumerableExtensions
        .Traverse(this, x => x.SubClassOf)
        .Any(x => x.Id == EnumerationId);

    public override bool IsArchived => EnumerableExtensions
        .Traverse(this, x => x.SubClassOf)
        .Any(x => string.Equals(x.Layer, LayerName.Archived, StringComparison.OrdinalIgnoreCase));

    public override bool IsMeta => EnumerableExtensions
        .Traverse(this, x => x.SubClassOf)
        .Any(x => string.Equals(x.Layer, LayerName.Meta, StringComparison.OrdinalIgnoreCase));

    public ICollection<SchemaClass> SubClassOf { get; } = new List<SchemaClass>();

    public ICollection<Uri> SubClassOfIds { get; } = new List<Uri>();
}

redpajama_set_name: RedPajamaGithub


text:
from loggit.context import actor_context_manager

class ActorMiddleware(object):
    """
    Wrap a request with a context that contains the current request.user
    as the actor for any actions.
    This is similar to how django-reversion does it.
    """
    def process_request(self, request):
        """
        Check to see that the session exists and that a user is on
        the request and then set them to the actor on actor_context_manager.
        """
        if hasattr(request, 'session') and hasattr(request, "user"):
            if request.user.is_authenticated():
                actor_context_manager.actor = request.user
            else:
                actor_context_manager.actor = None


text:
{% load humanize %}

{% spaceless %}

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <meta name="google-site-verification" content="IrS0Bj9BizvppKEK1gS3Omjmfv0k_gVRfmqVtmNbfmI"/>
        <title>{% block title %}College Football Reference{% endblock %}</title>

        <link rel="stylesheet" href="/static/css/style.css" type="text/css" media="screen"/>
        {% if not debug %}

        {% endif %}

College Football Reference

More than you wanted about college football.

            {% block content %}

            {% endblock %}

Basics

Blog

Start Looking

Teams

Conferences

Coaches

States

Extras

Team Rankings

Bowl Games

Fewest Rushing Yards Lost

Powered by Hemingway flavored Django.

{% endspaceless %}


text:
import numpy as np
import scipy.special
from bokeh.plotting import *

mu, sigma = 0, 0.5       # NOTE: you can tinker with these values if you like

# sample the distribution
measured = np.random.normal(mu, sigma, 1000)
hist, edges = np.histogram(measured, density=True, bins=50)

# compute ideal values
x = np.linspace(-2, 2, 1000)
pdf = 1/(sigma * np.sqrt(2*np.pi)) * np.exp(-(x-mu)**2 / (2*sigma**2))
cdf = (1+scipy.special.erf((x-mu)/np.sqrt(2*sigma**2)))/2

# EXERCISE: output to a static HTML file
output_file('histogram.html')

# EXERCISE: turn on plot hold
hold()

# Use the `quad` renderer to display the histogram bars.
quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],
     fill_color="#036564", line_color="#033649",

     # NOTE: these are only needed on the first renderer
     background_fill="#E8DDCB",
     title="Normal Distribution (μ=0, σ=0.5)",
     tools=""
)

# Use `line` renderers to display the PDF and CDF
line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")
line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")

# Move the legend to a better place.
# Acceptable values: 'top_left', 'top_right', 'bottom_left', and 'bottom_right'
legend().orientation = "top_left"

# EXERCISE: create a new figure
figure()

mu, sigma = 0, 0.5       # NOTE: you can tinker with these values if you like

# sample the distribution
measured = np.random.lognormal(mu, sigma, 1000)
hist, edges = np.histogram(measured, density=True, bins=50)

# compute ideal values
x = np.linspace(0, 8.0, 1000)
pdf = 1/(x* sigma * np.sqrt(2*np.pi)) * np.exp(-(np.log(x)-mu)**2 / (2*sigma**2))
cdf = (1+scipy.special.erf((np.log(x)-mu)/(np.sqrt(2)*sigma)))/2

# EXERCISE: recreate the first plot for this new data
quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],
     fill_color="#036564", line_color="#033649", background_fill="#E8DDCB",
     title="Log Normal Distribution (μ=0, σ=0.5)", tools="")
line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")
line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")
legend().orientation = "bottom_right"

# EXERCISE (optional): Add new plots for the following distributions:
# * Gamma
# * Beta
# * Weibull
# The numerical code is included, you will need to create new figures.
figure()

k, theta = 1.0, 2.0

# sample the distribution
measured = np.random.gamma(k, theta, 1000)
hist, edges = np.histogram(measured, density=True, bins=50)

# compute ideal values
x = np.linspace(0, 20.0, 1000)
pdf = x**(k-1) * np.exp(-x/theta) / (theta**k * scipy.special.gamma(k))
cdf = scipy.special.gammainc(k, x/theta) / scipy.special.gamma(k)

quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],
     fill_color="#036564", line_color="#033649", background_fill="#E8DDCB",
     title="Gamma Distribution (k=1, θ=2)", tools="")
line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")
line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")
legend().orientation = "top_left"

figure()

alpha, beta = 2.0, 2.0

# sample the distribution
measured = np.random.beta(alpha, beta, 1000)
hist, edges = np.histogram(measured, density=True, bins=50)

# compute ideal values
x = np.linspace(0, 1, 1000)
pdf = x**(alpha-1) * (1-x)**(beta-1) / scipy.special.beta(alpha, beta)
cdf = scipy.special.btdtr(alpha, beta, x)

quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],
     fill_color="#036564", line_color="#033649", background_fill="#E8DDCB",
     title="Beta Distribution (α=2, β=2)", tools="")
line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")
line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")

figure()

lam, k = 1, 1.25

# sample the distribution
measured = lam*(-np.log(np.random.uniform(0, 1, 1000)))**(1/k)
hist, edges = np.histogram(measured, density=True, bins=50)

# compute ideal values
x = np.linspace(0, 8, 1000)
pdf = (k/lam)*(x/lam)**(k-1) * np.exp(-(x/lam)**k)
cdf = 1 - np.exp(-(x/lam)**k)

quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],
     fill_color="#036564", line_color="#033649", background_fill="#E8DDCB",
     title="Weibull Distribution (λ=1, k=1.25)", tools="")
line(x, pdf, line_color="#D95B43", line_width=8, alpha=0.7, legend="PDF")
line(x, cdf, line_color="white", line_width=2, alpha=0.7, legend="CDF")
legend().orientation = "top_left"

show()


text:
package org.elasticsearch.xpack.transform.transforms;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.util.SetOnce;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.ResourceNotFoundException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.LatchedActionListener;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.IndexRoutingTable;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.persistent.AllocatedPersistentTask;
import org.elasticsearch.persistent.PersistentTaskState;
import org.elasticsearch.persistent.PersistentTasksCustomMetadata;
import org.elasticsearch.persistent.PersistentTasksExecutor;
import org.elasticsearch.tasks.TaskId;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xpack.core.indexing.IndexerState;
import org.elasticsearch.xpack.core.transform.TransformField;
import org.elasticsearch.xpack.core.transform.TransformMessages;
import org.elasticsearch.xpack.core.transform.action.StartTransformAction;
import org.elasticsearch.xpack.core.transform.transforms.TransformCheckpoint;
import org.elasticsearch.xpack.core.transform.transforms.TransformConfig;
import org.elasticsearch.xpack.core.transform.transforms.TransformState;
import org.elasticsearch.xpack.core.transform.transforms.TransformStoredDoc;
import org.elasticsearch.xpack.core.transform.transforms.TransformTaskParams;
import org.elasticsearch.xpack.core.transform.transforms.persistence.TransformInternalIndexConstants;
import org.elasticsearch.xpack.transform.Transform;
import org.elasticsearch.xpack.transform.TransformServices;
import org.elasticsearch.xpack.transform.notifications.TransformAuditor;
import org.elasticsearch.xpack.transform.persistence.SeqNoPrimaryTermAndIndex;
import org.elasticsearch.xpack.transform.persistence.TransformInternalIndex;
import org.elasticsearch.xpack.transform.transforms.pivot.SchemaUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class TransformPersistentTasksExecutor extends PersistentTasksExecutor<TransformTaskParams> {

    private static final Logger logger = LogManager.getLogger(TransformPersistentTasksExecutor.class);

    // The amount of time we wait for the cluster state to respond when being marked as failed
    private static final int MARK_AS_FAILED_TIMEOUT_SEC = 90;
    private final Client client;
    private final TransformServices transformServices;
    private final ThreadPool threadPool;
    private final ClusterService clusterService;
    private final IndexNameExpressionResolver resolver;
    private final TransformAuditor auditor;
    private volatile int numFailureRetries;

    public TransformPersistentTasksExecutor(
        Client client,
        TransformServices transformServices,
        ThreadPool threadPool,
        ClusterService clusterService,
        Settings settings,
        IndexNameExpressionResolver resolver
    ) {
        super(TransformField.TASK_NAME, Transform.TASK_THREAD_POOL_NAME);
        this.client = client;
        this.transformServices = transformServices;
        this.threadPool = threadPool;
        this.clusterService = clusterService;
        this.resolver = resolver;
        this.auditor = transformServices.getAuditor();
        this.numFailureRetries = Transform.NUM_FAILURE_RETRIES_SETTING.get(settings);
        clusterService.getClusterSettings().addSettingsUpdateConsumer(Transform.NUM_FAILURE_RETRIES_SETTING, this::setNumFailureRetries);
    }

    @Override
    public PersistentTasksCustomMetadata.Assignment getAssignment(TransformTaskParams params, ClusterState clusterState) {
        List<String> unavailableIndices = verifyIndicesPrimaryShardsAreActive(clusterState, resolver);
        if (unavailableIndices.size() != 0) {
            String reason = "Not starting transform ["
                + params.getId()
                + "], "
                + "because not all primary shards are active for the following indices ["
                + String.join(",", unavailableIndices)
                + "]";
            logger.debug(reason);
            return new PersistentTasksCustomMetadata.Assignment(null, reason);
        }
        DiscoveryNode discoveryNode = selectLeastLoadedNode(
            clusterState,
            (node) -> nodeCanRunThisTransform(node, params, null)
        );

        if (discoveryNode == null) {
            Map<String, String> explainWhyAssignmentFailed = new TreeMap<>();
            for (DiscoveryNode node : clusterState.getNodes()) {
                nodeCanRunThisTransform(node, params, explainWhyAssignmentFailed);
            }
            String reason = "Not starting transform ["
                + params.getId()
                + "], reasons ["
                + explainWhyAssignmentFailed.entrySet().stream().map(e -> e.getKey() + ":" + e.getValue()).collect(Collectors.joining("|"))
                + "]";

            logger.debug(reason);
            return new PersistentTasksCustomMetadata.Assignment(null, reason);
        }

        return new PersistentTasksCustomMetadata.Assignment(discoveryNode.getId(), "");
    }

    public static boolean nodeCanRunThisTransform(DiscoveryNode node, TransformTaskParams params, Map<String, String> explain) {
        // version of the transform run on a node that has at least the same version
        if (node.getVersion().onOrAfter(params.getVersion()) == false) {
            if (explain != null) {
                explain.put(
                    node.getId(),
                    "node has version: " + node.getVersion() + " but transform requires at least " + params.getVersion()
                );
            }
            return false;
        }

        final Map<String, String> nodeAttributes = node.getAttributes();

        // transform enabled?
        if (Boolean.parseBoolean(nodeAttributes.get(Transform.TRANSFORM_ENABLED_NODE_ATTR)) == false) {
            if (explain != null) {
                explain.put(node.getId(), "not a transform node");
            }
            return false;
        }

        // does the transform require a remote and remote is enabled?
        if (params.requiresRemote() && node.isRemoteClusterClient() == false) {
            if (explain != null) {
                explain.put(node.getId(), "transform requires a remote connection but remote is disabled");
            }
            return false;
        }

        // we found no reason that the transform can not run on this node
        return true;
    }

    static List<String> verifyIndicesPrimaryShardsAreActive(ClusterState clusterState, IndexNameExpressionResolver resolver) {
        String[] indices = resolver.concreteIndexNames(
            clusterState,
            IndicesOptions.lenientExpandOpen(),
            TransformInternalIndexConstants.INDEX_NAME_PATTERN,
            TransformInternalIndexConstants.INDEX_NAME_PATTERN_DEPRECATED
        );
        List<String> unavailableIndices = new ArrayList<>(indices.length);
        for (String index : indices) {
            IndexRoutingTable routingTable = clusterState.getRoutingTable().index(index);
            if (routingTable == null || routingTable.allPrimaryShardsActive() == false) {
                unavailableIndices.add(index);
            }
        }
        return unavailableIndices;
    }

    @Override
    protected void nodeOperation(AllocatedPersistentTask task, @Nullable TransformTaskParams params, PersistentTaskState state) {
        final String transformId = params.getId();
        final TransformTask buildTask = (TransformTask) task;
        // NOTE: TransformPersistentTasksExecutor#createTask pulls in the stored task state from the ClusterState when the object
        // is created. TransformTask#ctor takes into account setting the task as failed if that is passed in with the
        // persisted state.
        // TransformPersistentTasksExecutor#startTask will fail as TransformTask#start, when force == false, will return
        // a failure indicating that a failed task cannot be started.
        //
        // We want the rest of the state to be populated in the task when it is loaded on the node so that users can force start it again
        // later if they want.
        final ClientTransformIndexerBuilder indexerBuilder = new ClientTransformIndexerBuilder().setAuditor(auditor)
            .setClient(buildTask.getParentTaskClient())
            .setTransformsCheckpointService(transformServices.getCheckpointService())
            .setTransformsConfigManager(transformServices.getConfigManager());

        final SetOnce<TransformState> stateHolder = new SetOnce<>();

        ActionListener<StartTransformAction.Response> startTaskListener = ActionListener.wrap(
            response -> logger.info("[{}] successfully completed and scheduled task in node operation", transformId),
            failure -> {
                auditor.error(
                    transformId,
                    "Failed to start transform. " + "Please stop and attempt to start again. Failure: " + failure.getMessage()
                );
                logger.error("Failed to start task [" + transformId + "] in node operation", failure);
            }
        );

        // <7> load next checkpoint
        ActionListener<TransformCheckpoint> getTransformNextCheckpointListener = ActionListener.wrap(nextCheckpoint -> {

            if (nextCheckpoint.isEmpty()) {
                // extra safety: reset position and progress if next checkpoint is empty
                // prevents a failure if for some reason the next checkpoint has been deleted
                indexerBuilder.setInitialPosition(null);
                indexerBuilder.setProgress(null);
            } else {
                logger.trace("[{}] Loaded next checkpoint [{}] found, starting the task", transformId, nextCheckpoint.getCheckpoint());
                indexerBuilder.setNextCheckpoint(nextCheckpoint);
            }

            final long lastCheckpoint = stateHolder.get().getCheckpoint();

            startTask(buildTask, indexerBuilder, lastCheckpoint, startTaskListener);
        }, error -> {
            // TODO: do not use the same error message as for loading the last checkpoint
            String msg = TransformMessages.getMessage(TransformMessages.FAILED_TO_LOAD_TRANSFORM_CHECKPOINT, transformId);
            logger.error(msg, error);
            markAsFailed(buildTask, msg);
        });

        // <6> load last checkpoint
        ActionListener<TransformCheckpoint> getTransformLastCheckpointListener = ActionListener.wrap(lastCheckpoint -> {
            indexerBuilder.setLastCheckpoint(lastCheckpoint);

            logger.trace("[{}] Loaded last checkpoint [{}], looking for next checkpoint", transformId, lastCheckpoint.getCheckpoint());
            transformServices.getConfigManager()
                .getTransformCheckpoint(transformId, lastCheckpoint.getCheckpoint() + 1, getTransformNextCheckpointListener);
        }, error -> {
            String msg = TransformMessages.getMessage(TransformMessages.FAILED_TO_LOAD_TRANSFORM_CHECKPOINT, transformId);
            logger.error(msg, error);
            markAsFailed(buildTask, msg);
        });

        // <5> Set the previous stats (if they exist), initialize the indexer, start the task (If it is STOPPED)
        // Since we don't create the task until `_start` is called, if we see that the task state is stopped, attempt to start
        // Schedule execution regardless
        ActionListener<Tuple<TransformStoredDoc, SeqNoPrimaryTermAndIndex>> transformStatsActionListener = ActionListener.wrap(
            stateAndStatsAndSeqNoPrimaryTermAndIndex -> {
                TransformStoredDoc stateAndStats = stateAndStatsAndSeqNoPrimaryTermAndIndex.v1();
                SeqNoPrimaryTermAndIndex seqNoPrimaryTermAndIndex = stateAndStatsAndSeqNoPrimaryTermAndIndex.v2();
                // Since we have not set the value for this yet, it SHOULD be null
                logger.trace("[{}] initializing state and stats: [{}]", transformId, stateAndStats.toString());
                TransformState transformState = stateAndStats.getTransformState();
                indexerBuilder.setInitialStats(stateAndStats.getTransformStats())
                    .setInitialPosition(stateAndStats.getTransformState().getPosition())
                    .setProgress(stateAndStats.getTransformState().getProgress())
                    .setIndexerState(currentIndexerState(transformState))
                    .setSeqNoPrimaryTermAndIndex(seqNoPrimaryTermAndIndex)
                    .setShouldStopAtCheckpoint(transformState.shouldStopAtNextCheckpoint());
                logger.debug(
                    "[{}] Loading existing state: [{}], position [{}]",
                    transformId,
                    stateAndStats.getTransformState(),
                    stateAndStats.getTransformState().getPosition()
                );

                stateHolder.set(transformState);
                final long lastCheckpoint = stateHolder.get().getCheckpoint();

                if (lastCheckpoint == 0) {
                    logger.trace("[{}] No last checkpoint found, looking for next checkpoint", transformId);
                    transformServices.getConfigManager()
                        .getTransformCheckpoint(transformId, lastCheckpoint + 1, getTransformNextCheckpointListener);
                } else {
                    logger.trace("[{}] Restore last checkpoint: [{}]", transformId, lastCheckpoint);
                    transformServices.getConfigManager()
                        .getTransformCheckpoint(transformId, lastCheckpoint, getTransformLastCheckpointListener);
                }
            },
            error -> {
                if (error instanceof ResourceNotFoundException == false) {
                    String msg = TransformMessages.getMessage(TransformMessages.FAILED_TO_LOAD_TRANSFORM_STATE, transformId);
                    logger.error(msg, error);
                    markAsFailed(buildTask, msg);
                } else {
                    logger.trace("[{}] No stats found (new transform), starting the task", transformId);
                    startTask(buildTask, indexerBuilder, null, startTaskListener);
                }
            }
        );

        // <4> set fieldmappings for the indexer, get the previous stats (if they exist)
        ActionListener<Map<String, String>> getFieldMappingsListener = ActionListener.wrap(fieldMappings -> {
            indexerBuilder.setFieldMappings(fieldMappings);
            transformServices.getConfigManager().getTransformStoredDoc(transformId, transformStatsActionListener);
        }, error -> {
            String msg = TransformMessages.getMessage(
                TransformMessages.UNABLE_TO_GATHER_FIELD_MAPPINGS,
                indexerBuilder.getTransformConfig().getDestination().getIndex()
            );
            logger.error(msg, error);
            markAsFailed(buildTask, msg);
        });

        // <3> Validate the transform, assigning it to the indexer, and get the field mappings
        ActionListener<TransformConfig> getTransformConfigListener = ActionListener.wrap(config -> {
            if (config.isValid()) {
                indexerBuilder.setTransformConfig(config);
                SchemaUtil.getDestinationFieldMappings(buildTask.getParentTaskClient(), config.getDestination().getIndex(),
                        getFieldMappingsListener);
            } else {
                markAsFailed(buildTask, TransformMessages.getMessage(TransformMessages.TRANSFORM_CONFIGURATION_INVALID, transformId));
            }
        }, error -> {
            String msg = TransformMessages.getMessage(TransformMessages.FAILED_TO_LOAD_TRANSFORM_CONFIGURATION, transformId);
            logger.error(msg, error);
            markAsFailed(buildTask, msg);
        });

        // <2> Get the transform config
        ActionListener<Void> templateCheckListener = ActionListener.wrap(
            aVoid -> transformServices.getConfigManager().getTransformConfiguration(transformId, getTransformConfigListener),
            error -> {
                Throwable cause = ExceptionsHelper.unwrapCause(error);
                String msg = "Failed to create internal index mappings";
                logger.error(msg, cause);
                markAsFailed(buildTask, msg + "[" + cause + "]");
            }
        );

        // <1> Check the index templates are installed
        TransformInternalIndex.installLatestIndexTemplatesIfRequired(clusterService, buildTask.getParentTaskClient(),
                templateCheckListener);
    }

    private static IndexerState currentIndexerState(TransformState previousState) {
        if (previousState == null) {
            return IndexerState.STOPPED;
        }
        switch (previousState.getIndexerState()) {
            // If it is STARTED or INDEXING we want to make sure we revert to started
            // Otherwise, the internal indexer will never get scheduled and execute
            case STARTED:
            case INDEXING:
                return IndexerState.STARTED;
            // If we are STOPPED, STOPPING, or ABORTING and just started executing on this node,
            // then it is safe to say we should be STOPPED
            case STOPPED:
            case STOPPING:
            case ABORTING:
            default:
                return IndexerState.STOPPED;
        }
    }

    private void markAsFailed(TransformTask task, String reason) {
        CountDownLatch latch = new CountDownLatch(1);

        task.fail(
            reason,
            new LatchedActionListener<>(
                ActionListener.wrap(
                    nil -> {},
                    failure -> logger.error("Failed to set task [" + task.getTransformId() + "] to failed", failure)
                ),
                latch
            )
        );
        try {
            latch.await(MARK_AS_FAILED_TIMEOUT_SEC, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            logger.error("Timeout waiting for task [" + task.getTransformId() + "] to be marked as failed in cluster state", e);
        }
    }

    private void startTask(
        TransformTask buildTask,
        ClientTransformIndexerBuilder indexerBuilder,
        Long previousCheckpoint,
        ActionListener<StartTransformAction.Response> listener
    ) {
        buildTask.initializeIndexer(indexerBuilder);
        // TransformTask#start will fail if the task state is FAILED
        buildTask.setNumFailureRetries(numFailureRetries).start(previousCheckpoint, listener);
    }

    private void setNumFailureRetries(int numFailureRetries) {
        this.numFailureRetries = numFailureRetries;
    }

    @Override
    protected AllocatedPersistentTask createTask(
        long id,
        String type,
        String action,
        TaskId parentTaskId,
        PersistentTasksCustomMetadata.PersistentTask<TransformTaskParams> persistentTask,
        Map<String, String> headers
    ) {
        return new TransformTask(
            id,
            type,
            action,
            parentTaskId,
            client,
            persistentTask.getParams(),
            (TransformState) persistentTask.getState(),
            transformServices.getSchedulerEngine(),
            auditor,
            threadPool,
            headers
        );
    }
}


text:
package testenv

import (
	"flag"
	"io"
	"log"
	"os"
	"path"
	"testing"

	"github.com/pborman/uuid"
	"golang.org/x/net/context"

	mixerapi "istio.io/api/mixer/v1"
	"istio.io/istio/mixer/adapter/denier"
	"istio.io/istio/mixer/pkg/adapter"
	"istio.io/istio/mixer/template"
)

func closeHelper(c io.Closer) {
	err := c.Close()
	if err != nil {
		log.Fatal(err)
	}
}

func copyFile(dest, src string) error {
	in, err := os.Open(src)
	if err != nil {
		return err
	}

	defer closeHelper(in)
	out, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer closeHelper(out)
	_, err = io.Copy(out, in)
	return err

}

func buildConfigStore(relativePaths []string) (string, error) {
	currentPath, err := os.Getwd()
	if err != nil {
		return "", err
	}

	configPath := path.Join(currentPath, uuid.New())
	if err = os.Mkdir(configPath, os.ModePerm); err != nil {
		return "", err
	}

	for _, filePath := range relativePaths {
		err = copyFile(path.Join(configPath, path.Base(filePath)), path.Join(currentPath, filePath))
		if err != nil {
			return "", err
		}
	}

	return configPath, nil
}

func TestMain(m *testing.M) {
	flag.Parse()
	code := m.Run()
	os.Exit(code)
}

func TestDenierAdapter(t *testing.T) {
	configStore, err := buildConfigStore([]string{
		"../../testdata/config/attributes.yaml",
		"../../testdata/config/deny.yaml",
	})
	if err != nil {
		t.Fatalf("fail to build test config store: %v", err)
	}

	defer func() {
		if removeErr := os.RemoveAll(configStore); removeErr != nil {
			log.Fatal(removeErr)
		}
	}()

	var args = Args{
		// Start Mixer server on a free port on loop back interface
		MixerServerAddr:               `127.0.0.1:0`,
		ConfigStoreURL:                `fs://` + configStore,
		ConfigStore2URL:               `fs://` + configStore,
		ConfigDefaultNamespace:        "istio-system",
		ConfigIdentityAttribute:       "destination.service",
		ConfigIdentityAttributeDomain: "svc.cluster.local",
		UseAstEvaluator:               true,
	}

	env, err := NewEnv(&args, template.SupportedTmplInfo, []adapter.InfoFn{denier.GetInfo})
	if err != nil {
		t.Fatalf("fail to create testenv: %v", err)
	}

	defer closeHelper(env)

	client, conn, err := env.CreateMixerClient()
	if err != nil {
		t.Fatalf("fail to create client connection: %v", err)
	}
	defer closeHelper(conn)

	attrs := map[string]interface{}{"request.headers": map[string]string{"clnt": "abc"}}
	bag := GetAttrBag(attrs, args.ConfigIdentityAttribute, args.ConfigIdentityAttributeDomain)
	request := mixerapi.CheckRequest{Attributes: bag}
	resq, err := client.Check(context.Background(), &request)
	if err != nil {
		t.Errorf("fail to send check to Mixer %v", err)
	}
	if resq.Precondition.Status.Code != 7 {
		t.Error(`resq.Precondition.Status.Code != 7`)
	}
}


text:
layout: post
title: "What It Means to Stub the System Under Test"
date: 2017-02-09T14:34:02-05:00
categories:
- articles
tags:
- testing
- ruby on rails
---

Has anyone else felt confused by the phrase stubbing the system under test? I've felt like the phrases that we use in the dev community to label concepts are designed for the sole purpose to obfuscate the truth.

Obfuscate, see what I did there?

There's a popular quote that I always keep in the back of my mind when I use terminology or jargon.

"If you can't explain it simply, you don't understand it well enough."

It isn't just enough to tell developer not to stub the system under test, you have to define and explain it (preferably with an example). Because if you don't understand the underlying concept or terminology how on earth can you stop introducing it to your code.

Short answer, you can't

So let's properly define and explain (simply) what exactly it means to stub the system under test.

What is a stub?

Stubs vs Mocks
A stub defines specific behavior for an object's method. A mock acts as a stand-in object for another. The double keyword in RSpec creates a pseudo-mock object.

To stub a method means to define its behavior. When you stub in a test you are basically saying, "For an object that calls a specific method return this result". There is also another term called mocks which are sometimes used interchangeably but are fundamentally different.

For example, let's say that you have a simple User model that defines name and role attributes for each record.

{% highlight ruby linenos %}
# app/models/user.rb
class User
  validates :name, prescense: true
  validates :role, prescence: true

  # We will focus on testing this method
  def welcome_message
    if admin?
      "Welcome, #{name}. You can find admin actions under the settings menu"
    else
      "Welcome, guest"
    end
  end

  private

  def admin?
    role == "admin"
  end
end

# db/migrate/2017_create_users.rb
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string   :name
      t.string   :role
      t.timestamps
    end
  end
end
{% endhighlight %}

Now for your corresponding spec we'd like to test the #welcome_message method and through it the #admin? method as well.

Here's the updated spec:

{% highlight ruby %}
  let(:user) { create(:user, name: "Christian Bale") }

  describe "#welcome_message" do
    it "returns true for user's of role 'admin'" do
      allow(user).to receive(:admin?).and_return(true)

      expect(user.welcome_message).to eq "Welcome, #{user.name}. You can find admin actions under the settings menu"
    end

    it "returns guest message for user's not of type 'admin'" do
      expect(user.welcome_message).to eq "Welcome, guest"
    end
  end
{% endhighlight %}

Everything is green and passing.

But there is a slight problem with the code above. What happens when the client asks for a slight change for when the admin welcome message displays. Specifically, they only want users whom are admin and have been created in the last 3 months to recieve the message.

{% highlight ruby %}
  def admin?
    # User has to be of role admin
    # and created in the last 3 months
    role == "admin" && created_at > (DateTime.current - 3.months)
  end
{% endhighlight %}

Does our test suite still pass?

It actually does and with flying colors, but why? Well, because in the early step we allows user to accept the message admin? and return the value true, now in the context of that test the #admin? method now always returns true.

{% highlight ruby %}
    it "returns true for user's of role 'admin'" do
      allow(user).to receive(:admin?).and_return(true) # Stubbing the system under test

      expect(user.welcome_message).to eq "Welcome, #{user.name}. You can find admin actions under the settings menu"
    end
{% endhighlight %}

Private methods
Something to keep in mind is that the #admin? method is listed as private. I'm paraphrasing Sandi Metz here, messages that we send to self (current class) aren't things that we care about testing since they don't effect other parts of our system.

The test above, while a farily contrived example, shows how stubbing the #admin? method's response to true can hide our codes actual intent. This produces an unreliable testing suite that over time becomes hard to trust and maintain.

Here's how I would test the above scenario including the guest branch, the admin that was created recently branch, and the admin that was created in the past branch.

{% highlight ruby %}
  let(:user) { create(:user, name: "Christian Bale") }

  describe "#welcome_message" do
    context "when admin" do
      let(:current_time) { DateTime.current }
      let(:the_past) { current_time - 5.months }
      let(:admin) { create(:user, name: "Nic Cage", role: "admin")

      context "and created recently" do
        before do
          admin.created_at = current_time
          admin.save
        end

        it "returns the welcome message with instructions" do
          expect(admin.welcome_message).to eq "Welcome, #{user.name}. You can find admin actions under the settings menu"
        end
      end

      context "and created in the far past" do
        before do
          admin.created_at = the_past
          admin.save
        end

        it "returns the guest message" do
          expect(admin.welcome_message).to eq "Welcome, guest"
        end
      end
    end

    context "when basic user" do
      let(:user) { create(:user, name: "Christian Bale") }

      it "returns the guest message" do
        expect(user.welcome_message).to eq "Welcome, guest"
      end
    end
  end
{% endhighlight %}

Now future changes to the #admin? method are able to effect the #welcome_message method and we're covered against tests that pass when in reality they are broken.  This is the basic premise behind not stubbing the system under test.

What does system refer to?

{% include rich-snippets/article-image src="2017/morpheus-specs.jpg" caption="Morpheus quote modified from the Matrix" width="500" height="303" %}

This one stumped me for some time.

"the system" refers to the current class or logic that you are attempting to harness and test. No it isn't what they talk about in The Matrix, though I always have this thought when I hear the phrase. Think of it more like your application logic or flow. You want to ensure that they are functioning as you intend and more importantly how the code is written. When you stub over functionality in your tests you get the all satisfying green but in reality your test isn't worth much.

For the example above the system under test is specifically the User model. Our goal is to directly test its functionality in the corresponding spec.

So when do you stub? Well, this is something that is constantly evolving for me but here are a few general guidelines I think about when I start the reach for stubbing.

What to stub?

Third-party services and apis

Essentially, anything that you don't have direct control over fits this category. You can use stubs to ensure your system appropriately handles both error cases and happy path cases. This also improves test suite performance by avoiding waiting on the third-party service to respond(~100ms every request will start to add up).

Outgoing messages that you expect to send

Controllers that call service objects are a good example of this. In a hypothetical controller test you wouldn't want to unit test the service class as well. Ideally, it would be properly tested in isolation within its own spec.

With that being said we still want to ensure that it is being sent a message (essentially being called) in the controller spec context.

{% highlight ruby %}
  # Example controller #index action
  def index
    CreateUserService.perform(params: params)
  rescue StandardError => e
    head :bad_request
  end

  # Example test ensuring a message is sent
  it "ensures message is sent to CreateUserService" do
    expect(CreateUserService).to receive(:perform).with(params: params)

    get :index
  end
{% endhighlight %}

This spec says, "Given the #index action for the controller, ensure that the CreateUserService receives the message of perform with the arguments of params: params"

We aren't directly testing the CreateUserService here because it already has its own associated unit test (not shown here) which ensures that it is functioning as expected. Not stubbing the service class above is just duplicating testing effort.

Minimizing database interactions

If you have a model with a scope that returns its active users (we'll call is :active) which already has unit tests ensuring that it functions as expected, then anytime you have to use the same scope elsewhere you could stub out the response.

This avoids having to hit the database in the test which greatly speeds up the test suite. Be warned though if you are writing tests specific to database interactions it is probably wise to over-test rather than under-test. Minimizing database interactions is a delicate balancing act between performance and confidence.

What to avoid stubbing?

Private methods (messages to self)

Like I mentioned above, these tend to directly deal with the current class that you are testing (system under test). You want to make sure that they are working as you expect and stubbing over the implementation is going to lead to unreliable results.

Integration Tests

This is end-to-end testing and as such you want to ensure that all steps along the path are in working order. I would also argue that it is ok for these specs to be a little slower at the great benefit of higher confidence.

Conclusion

As with all programming, knowing when to stub and when not to can be fairly opionated. There is always room for breaking the rules in certain situations and as such its important to remain flexible with your approach to testing. Using your best judgement to decide what to directly test and what to stub is something that takes a lot of practice (I'm still learning this as well).

I took loads of inspiration from Sandi Metz's talk about Magic Tricks of Testing, which is an excellent in-depth discussion of what to test and what not to. I highly recommend watching it and following along with the slides on SpeakerDeck.

Did I miss something that should be stubbed? How about something else not to stub? I'd love to add to the above list based on your comments below.

Thanks for reading


text:
namespace tink_testing_api {

namespace {

using ::google::crypto::tink::KeyTemplate;
using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::NotNull;

std::string ValidAeadKeyset() {
  const KeyTemplate& key_template = crypto::tink::AeadKeyTemplates::Aes128Eax();
  auto handle_result = crypto::tink::KeysetHandle::GenerateNew(key_template);
  EXPECT_TRUE(handle_result.ok());
  std::stringbuf keyset;
  auto writer_result = crypto::tink::BinaryKeysetWriter::New(
      absl::make_unique<std::ostream>(&keyset));
  EXPECT_TRUE(writer_result.ok());

  auto status = crypto::tink::CleartextKeysetHandle::Write(
      writer_result.value().get(), *handle_result.value());
  EXPECT_TRUE(status.ok());
  return keyset.str();
}

class CreateTest : public ::testing::Test {
 protected:
  static void SetUpTestSuite() {
    ASSERT_TRUE(crypto::tink::AeadConfig::Register().ok());
  }
};

TEST_F(CreateTest, RpcHelperSuccess) {
  std::string keyset = ValidAeadKeyset();
  CreationRequest request;
  request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
  CreationResponse response;

  EXPECT_TRUE(
      CreatePrimitiveForRpc<crypto::tink::Aead>(&request, &response)
          .ok());
  EXPECT_THAT(response.err(), IsEmpty());
}

TEST_F(CreateTest, RpcHelperWrongPrimitiveFails) {
  std::string keyset = ValidAeadKeyset();
  CreationRequest request;
  request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
  CreationResponse response;
  EXPECT_TRUE(
      CreatePrimitiveForRpc<crypto::tink::Mac>(&request, &response).ok());
  EXPECT_THAT(response.err(), Not(IsEmpty()));
}

TEST_F(CreateTest, PrimitiveCreationWorks) {
  AnnotatedKeyset annotated_keyset;
  annotated_keyset.set_serialized_keyset(ValidAeadKeyset());
  crypto::tink::util::StatusOr<std::unique_ptr<crypto::tink::Aead>> aead =
      PrimitiveFromSerializedBinaryProtoKeyset<crypto::tink::Aead>(
          annotated_keyset);
  ASSERT_TRUE(aead.status().ok()) << aead.status();
  EXPECT_THAT(*aead, NotNull());
}

TEST_F(CreateTest, PrimitiveCreationWrongPrimitiveFails) {
  AnnotatedKeyset annotated_keyset;
  annotated_keyset.set_serialized_keyset(ValidAeadKeyset());
  crypto::tink::util::StatusOr<std::unique_ptr<crypto::tink::Mac>> aead =
      PrimitiveFromSerializedBinaryProtoKeyset<crypto::tink::Mac>(
          annotated_keyset);
  ASSERT_FALSE(aead.status().ok());
}

TEST_F(CreateTest, PrimitiveWithAnnotationsWorks) {
  AnnotatedKeyset annotated_keyset;
  annotated_keyset.set_serialized_keyset(ValidAeadKeyset());
  annotated_keyset.mutable_annotations()->insert({"key1", "value1"});
  crypto::tink::util::StatusOr<std::unique_ptr<crypto::tink::Aead>> aead =
      PrimitiveFromSerializedBinaryProtoKeyset<crypto::tink::Aead>(
          annotated_keyset);
  ASSERT_TRUE(aead.status().ok());
  EXPECT_THAT(*aead, NotNull());
}

}  // namespace

}  // namespace tink_testing_api


text:
title: "Long hair purple and red highlights"
excerpt: "PaperFaces portrait of @neikura drawn with Paper by 53 on an iPad."
image:
  feature: paperfaces-neikura-twitter-lg.jpg
  thumb: paperfaces-neikura-twitter-150.jpg
tags: [portrait, illustration, Paper by 53]
---

PaperFaces portrait of [@neikura](http://twitter.com/neikura).

{% include boilerplate/paperfaces.html %}


text:
(function() {
  var infos, manfred, merge;

  infos = require('./infos');

  merge = require('./utils').merge;

  module.exports = manfred = function() {
    return console.log("" + manfred.fullname + " <" + manfred.mail + ">");
  };

  manfred.__defineGetter__('fullname', function() {
    return "" + manfred.firstname + " " + manfred.lastname;
  });

  merge(manfred, infos);

}).call(this);


text:
package org.mozilla.javascript.drivers;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Properties;
import java.util.List;
import java.util.ArrayList;

import junit.framework.Assert;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.mozilla.javascript.tools.shell.ShellContextFactory;

/**
 * Executes the tests in the js/tests directory, much like jsDriver.pl does.
 * Excludes tests found in the js/tests/rhino-n.tests file.
 * @author Attila Szegedi
 * @version $Id: StandardTests.java,v 1.8.2.3 2008/12/12 10:27:42 hannes%helma.at Exp $
 */
public class StandardTests extends TestSuite
{
	public static TestSuite suite() throws Exception
    {
        TestSuite suite = new TestSuite("Standard JavaScript tests");

        File testDir = null;
        if (System.getProperty("mozilla.js.tests") != null) {
            testDir = new File(System.getProperty("mozilla.js.tests"));
        } else {
            URL url = StandardTests.class.getResource(".");
            String path = url.getFile();
            int jsIndex = path.lastIndexOf("/js");
            if(jsIndex == -1)
            {
                throw new IllegalStateException("You aren't running the tests from within the standard mozilla/js directory structure");
            }
            path = path.substring(0, jsIndex + 3).replace('/', File.separatorChar);
            testDir = new File(path, "tests");
        }
        if(!testDir.isDirectory())
        {
            throw new FileNotFoundException(testDir + " is not a directory");
        }
        String[] excludes = TestUtils.loadTestsFromResource("/base.skip", null);
        String[] opt1Excludes = TestUtils.loadTestsFromResource("/opt1.skip", excludes);
        for(int i = -1; i < 2; ++i)
        {
            TestSuite optimizationLevelSuite = new TestSuite("Optimization level " + i);
            addSuites(optimizationLevelSuite, testDir, i == -1 ? excludes : opt1Excludes, i);
            suite.addTest(optimizationLevelSuite);
        }
        return suite;
    }

    private static void addSuites(TestSuite topLevel, File testDir, String[] excludes, int optimizationLevel)
    {
        File[] subdirs = testDir.listFiles(ShellTest.DIRECTORY_FILTER);
        Arrays.sort(subdirs);
        for (int i = 0; i < subdirs.length; i++)
        {
            File subdir = subdirs[i];
            String name = subdir.getName();
            if (TestUtils.matches(excludes, name)) {
                continue;
            }
            TestSuite testSuite = new TestSuite(name);
            addCategories(testSuite, subdir, name + "/", excludes, optimizationLevel);
            topLevel.addTest(testSuite);
        }
    }

    private static void addCategories(TestSuite suite, File suiteDir, String prefix, String[] excludes, int optimizationLevel)
    {
        File[] subdirs = suiteDir.listFiles(ShellTest.DIRECTORY_FILTER);
        Arrays.sort(subdirs);
        for (int i = 0; i < subdirs.length; i++)
        {
            File subdir = subdirs[i];
            String name = subdir.getName();
            TestSuite testCategory = new TestSuite(name);
            addTests(testCategory, subdir, prefix + name + "/", excludes, optimizationLevel);
            suite.addTest(testCategory);
        }
    }

    private static void addTests(TestSuite suite, File suiteDir, String prefix, String[] excludes, int optimizationLevel)
    {
        File[] jsFiles = suiteDir.listFiles(ShellTest.TEST_FILTER);
        Arrays.sort(jsFiles);
        for (int i = 0; i < jsFiles.length; i++)
        {
            File jsFile = jsFiles[i];
            String name = jsFile.getName();
            if (!TestUtils.matches(excludes, prefix + name)) {
                suite.addTest(new JsTestCase(jsFile, optimizationLevel));
            }
        }
    }

    private static class JunitStatus extends ShellTest.Status {
        @Override
        final void running(File jsFile) {
            //    do nothing
        }

        @Override
        final void failed(String s) {
            Assert.fail(s);
        }

        @Override
        final void exitCodesWere(int expected, int actual) {
            Assert.assertEquals("Unexpected exit code", expected, actual);
        }

        @Override
        final void outputWas(String s) {
            // Do nothing; we don't want to see the output when running JUnit
            // tests.
        }

        @Override
        final void threw(Throwable t) {
            Assert.fail(ShellTest.getStackTrace(t));
        }

        @Override
        final void timedOut() {
            failed("Timed out.");
        }
    }

    private static final class JsTestCase extends TestCase
    {
        private final File jsFile;
        private final int optimizationLevel;

        JsTestCase(File jsFile, int optimizationLevel)
        {
            super(jsFile.getName() + (optimizationLevel == 1 ? "-compiled" : "-interpreted"));
            this.jsFile = jsFile;
            this.optimizationLevel = optimizationLevel;
        }

        @Override
        public int countTestCases()
        {
            return 1;
        }

        private static class ShellTestParameters extends ShellTest.Parameters {
            @Override
            int getTimeoutMilliseconds() {
                if (System.getProperty("mozilla.js.tests.timeout") != null) {
                    return Integer.parseInt(System.getProperty("mozilla.js.tests.timeout"));
                }
                return 60000;
            }
        }

        @Override
        public void runBare() throws Exception
        {
            final ShellContextFactory shellContextFactory = new ShellContextFactory();
            shellContextFactory.setOptimizationLevel(optimizationLevel);
            ShellTestParameters params = new ShellTestParameters();
            ShellTest.run(shellContextFactory, jsFile, params, new JunitStatus());
        }
    }
}


text:
require 'spec_helper'

describe Drivers::Worker::Shoryuken do
  it 'receives and exposes app and node' do
    driver = described_class.new(dummy_context(node), aws_opsworks_app)

    expect(driver.app).to eq aws_opsworks_app
    expect(driver.send(:node)).to eq node
    expect(driver.options).to eq({})
  end

  it 'returns proper out data' do
    expect(described_class.new(dummy_context(node), aws_opsworks_app).out).to eq(
      process_count: 2,
      syslog: true,
      require: 'lorem_ipsum.rb',
      require_rails: true,
      config: {
        'concurency' => 5,
        'verbose' => false,
        'queues' => ['default']
      }
    )
  end
end


text:
package com.flowtomation.akkared.format

import com.flowtomation.akkared.model._
import com.flowtomation.akkared.util.JsonReader
import org.scalatest.WordSpec
import play.api.libs.json.{JsArray, JsBoolean, JsSuccess}
import play.api.libs.json.Json._

import collection.immutable.Seq

class FlowsFormatSpec extends WordSpec {

  "The flows format" when {

    "reading" should {

      "correctly handle an empty json" in {
        val json = arr()
        val result = FlowsFormat.FlowsFormat.reads(json)
        assert(result == JsSuccess(Flows.empty))
      }

      "correctly handle a real json" in {
        val json = JsonReader.fromClasspath("flow.json")
        val JsSuccess(result, _) = FlowsFormat.FlowsFormat.reads(json)
        assert(result.items.length == 14)
      }
    }

    "writing" should {

      "correctly write an empty flows file" in {
        val flows = Flows.empty
        val result = FlowsFormat.FlowsFormat.writes(flows)
        assert(result == arr())
      }

      "correctly write multiple flows" in {
        val flows = Flows(
          FlowTab(ItemId("t1"), "tab1", disabled = true, "This is a test"),
          FlowTab(ItemId("t2"), "tab2", disabled = false, "This is a test"),
          FlowNode(ItemId("n1"), ItemId("t2"), "foo", "footype", 10, 20, Seq.empty, Map("test" -> JsBoolean(true)))
        )
        val result = FlowsFormat.FlowsFormat.writes(flows)
        assert(result.as[JsArray].value.length == 3)
      }

    }

  }
}


text:
package aggregation

import (
	"github.com/pingcap/errors"
	"github.com/pingcap/parser/ast"
	"github.com/pingcap/tidb/expression"
	"github.com/pingcap/tidb/kv"
	"github.com/pingcap/tidb/sessionctx/stmtctx"
	"github.com/pingcap/tidb/types"
	"github.com/pingcap/tipb/go-tipb"
)

// AggFuncToPBExpr converts aggregate function to pb.
func AggFuncToPBExpr(sc *stmtctx.StatementContext, client kv.Client, aggFunc *AggFuncDesc) *tipb.Expr {
	if aggFunc.HasDistinct {
		return nil
	}
	pc := expression.NewPBConverter(client, sc)
	var tp tipb.ExprType
	switch aggFunc.Name {
	case ast.AggFuncCount:
		tp = tipb.ExprType_Count
	case ast.AggFuncFirstRow:
		tp = tipb.ExprType_First
	case ast.AggFuncGroupConcat:
		tp = tipb.ExprType_GroupConcat
	case ast.AggFuncMax:
		tp = tipb.ExprType_Max
	case ast.AggFuncMin:
		tp = tipb.ExprType_Min
	case ast.AggFuncSum:
		tp = tipb.ExprType_Sum
	case ast.AggFuncAvg:
		tp = tipb.ExprType_Avg
	case ast.AggFuncBitOr:
		tp = tipb.ExprType_Agg_BitOr
	case ast.AggFuncBitXor:
		tp = tipb.ExprType_Agg_BitXor
	case ast.AggFuncBitAnd:
		tp = tipb.ExprType_Agg_BitAnd
	case ast.AggFuncVarPop:
		tp = tipb.ExprType_VarPop
	}
	if !client.IsRequestTypeSupported(kv.ReqTypeSelect, int64(tp)) {
		return nil
	}

	children := make([]*tipb.Expr, 0, len(aggFunc.Args))
	for _, arg := range aggFunc.Args {
		pbArg := pc.ExprToPB(arg)
		if pbArg == nil {
			return nil
		}
		children = append(children, pbArg)
	}
	return &tipb.Expr{Tp: tp, Children: children, FieldType: expression.ToPBFieldType(aggFunc.RetTp)}
}

// PBExprToAggFuncDesc converts pb to aggregate function.
func PBExprToAggFuncDesc(sc *stmtctx.StatementContext, aggFunc *tipb.Expr, fieldTps []*types.FieldType) (*AggFuncDesc, error) {
	var name string
	switch aggFunc.Tp {
	case tipb.ExprType_Count:
		name = ast.AggFuncCount
	case tipb.ExprType_First:
		name = ast.AggFuncFirstRow
	case tipb.ExprType_GroupConcat:
		name = ast.AggFuncGroupConcat
	case tipb.ExprType_Max:
		name = ast.AggFuncMax
	case tipb.ExprType_Min:
		name = ast.AggFuncMin
	case tipb.ExprType_Sum:
		name = ast.AggFuncSum
	case tipb.ExprType_Avg:
		name = ast.AggFuncAvg
	case tipb.ExprType_Agg_BitOr:
		name = ast.AggFuncBitOr
	case tipb.ExprType_Agg_BitXor:
		name = ast.AggFuncBitXor
	case tipb.ExprType_Agg_BitAnd:
		name = ast.AggFuncBitAnd
	default:
		return nil, errors.Errorf("unknown aggregation function type: %v", aggFunc.Tp)
	}

	args, err := expression.PBToExprs(aggFunc.Children, fieldTps, sc)
	if err != nil {
		return nil, err
	}
	base := baseFuncDesc{
		Name:  name,
		Args:  args,
		RetTp: expression.FieldTypeFromPB(aggFunc.FieldType),
	}
	return &AggFuncDesc{
		baseFuncDesc: base,
		Mode:         Partial1Mode,
		HasDistinct:  false,
	}, nil
}


text:
package wekit

import (
	"regexp"
	"strings"
)

// RightPad2Len pad string to right
func RightPad2Len(s string, padStr string, overallLen int) string {
	var padCountInt = 1 + ((overallLen - len(padStr)) / len(padStr))
	var retStr = s + strings.Repeat(padStr, padCountInt)
	return retStr[:overallLen]
}

// LeftPad2Len pad string to left
func LeftPad2Len(s string, padStr string, overallLen int) string {
	var padCountInt = 1 + ((overallLen - len(padStr)) / len(padStr))
	var retStr = strings.Repeat(padStr, padCountInt) + s
	return retStr[(len(retStr) - overallLen):]
}

// Nl2Br replace \n to

func Nl2Br(s string) string {
	return strings.Replace(s, "\n", "
", -1)
}

var numberSequence = regexp.MustCompile(`([a-zA-Z])(\d+)([a-zA-Z]?)`)
var numberReplacement = []byte(`$1 $2 $3`)

func addWordBoundariesToNumbers(s string) string {
	b := []byte(s)
	b = numberSequence.ReplaceAll(b, numberReplacement)
	return string(b)
}

// Converts a string to CamelCase
func toCamelInitCase(s string, initCase bool) string {
	s = addWordBoundariesToNumbers(s)
	s = strings.Trim(s, " ")
	n := ""
	capNext := initCase
	for _, v := range s {
		if v >= 'A' && v <= 'Z' {
			n += string(v)
		}
		if v >= '0' && v <= '9' {
			n += string(v)
		}
		if v >= 'a' && v <= 'z' {
			if capNext {
				n += strings.ToUpper(string(v))
			} else {
				n += string(v)
			}
		}
		if v == '_' || v == ' ' || v == '-' {
			capNext = true
		} else {
			capNext = false
		}
	}
	return n
}

// ToCamel Converts a string to CamelCase
func ToCamel(s string) string {
	return toCamelInitCase(s, true)
}

// ToLowerCamel Converts a string to lowerCamelCase
func ToLowerCamel(s string) string {
	if s == "" {
		return s
	}
	if r := rune(s[0]); r >= 'A' && r <= 'Z' {
		s = strings.ToLower(string(r)) + s[1:]
	}
	return toCamelInitCase(s, false)
}

// ToUnderscore Converts a string to snake_case
func ToUnderscore(s string) string {
	return ToDelimited(s, '_')
}

// ToUpperUnderscore Converts a string to SCREAMING_SNAKE_CASE
func ToUpperUnderscore(s string) string {
	return ToUpperDelimited(s, '_', true)
}

// ToHyphen Converts a string to kebab-case
func ToHyphen(s string) string {
	return ToDelimited(s, '-')
}

// ToUpperToHyphen Converts a string to SCREAMING-KEBAB-CASE
func ToUpperToHyphen(s string) string {
	return ToUpperDelimited(s, '-', true)
}

// ToDelimited Converts a string to delimited.snake.case (in this case `del = '.'`)
func ToDelimited(s string, del uint8) string {
	return ToUpperDelimited(s, del, false)
}

// ToUpperDelimited Converts a string to SCREAMING.DELIMITED.SNAKE.CASE (in this case `del = '.'; screaming = true`) or delimited.snake.case (in this case `del = '.'; screaming = false`)
func ToUpperDelimited(s string, del uint8, screaming bool) string {
	s = addWordBoundariesToNumbers(s)
	s = strings.Trim(s, " ")
	n := ""
	for i, v := range s {
		// treat acronyms as words, eg for JSONData -> JSON is a whole word
		nextCaseIsChanged := false
		if i+1 < len(s) {
			next := s[i+1]
			if (v >= 'A' && v <= 'Z' && next >= 'a' && next <= 'z') || (v >= 'a' && v <= 'z' && next >= 'A' && next <= 'Z') {
				nextCaseIsChanged = true
			}
		}

		if i > 0 && n[len(n)-1] != del && nextCaseIsChanged {
			// add underscore if next letter case type is changed
			if v >= 'A' && v <= 'Z' {
				n += string(del) + string(v)
			} else if v >= 'a' && v <= 'z' {
				n += string(v) + string(del)
			}
		} else if v == ' ' || v == '_' || v == '-' {
			// replace spaces/underscores with delimiters
			n += string(del)
		} else {
			n = n + string(v)
		}
	}

	if screaming {
		n = strings.ToUpper(n)
	} else {
		n = strings.ToLower(n)
	}
	return n
}


text:
namespace Microsoft.Data.Spatial
{
    /// <summary>
    /// Gml Constants
    /// </summary>
    internal class GmlConstants
    {
        /// <summary>
        /// Gml Namespace
        /// </summary>
        internal const string GmlNamespace = "http://www.opengis.net/gml";

        /// <summary>
        /// FullGlobe namespace
        /// </summary>
        internal const string FullGlobeNamespace = "http://schemas.microsoft.com/sqlserver/2011/geography";

        /// <summary>
        /// Gml Prefix
        /// </summary>
        internal const string GmlPrefix = "gml";

        /// <summary>
        /// System reference attribute name
        /// </summary>
        internal const string SrsName = "srsName";

        /// <summary>
        /// gml:id attribute name
        /// </summary>
        internal const string IdName = "id";

        /// <summary>
        /// System Reference Prefix
        /// </summary>
        internal const string SrsPrefix = "http://www.opengis.net/def/crs/EPSG/0/";

        /// <summary>
        /// Gml representation of a point
        /// </summary>
        internal const string Position = "pos";

        /// <summary>
        /// The Gml:name element name
        /// </summary>
        internal const string Name = "name";

        /// <summary>
        /// the Gml:Description element name
        /// </summary>
        internal const string Description = "description";

        /// <summary>
        /// the metadata property element name
        /// </summary>
        internal const string MetadataProperty = "metaDataProperty";

        /// <summary>
        /// Description Reference element name
        /// </summary>
        internal const string DescriptionReference = "descriptionReference";

        /// <summary>
        /// identifier element name
        /// </summary>
        internal const string IdentifierElement = "identifier";

        /// <summary>
        /// Gml representation of a point
        /// </summary>
        internal const string PointProperty = "pointProperty";

        /// <summary>
        /// Gml representation of a point array
        /// </summary>
        internal const string PositionList = "posList";

        /// <summary>
        /// Gml Point
        /// </summary>
        internal const string Point = "Point";

        /// <summary>
        /// Gml representation of a linestring
        /// </summary>
        internal const string LineString = "LineString";

        /// <summary>
        /// Gml Polygon
        /// </summary>
        internal const string Polygon = "Polygon";

        /// <summary>
        /// Gml MultiPoint
        /// </summary>
        internal const string MultiPoint = "MultiPoint";

        /// <summary>
        /// Gml MultiLineString
        /// </summary>
        internal const string MultiLineString = "MultiCurve";

        /// <summary>
        /// Gml MultiPolygon
        /// </summary>
        internal const string MultiPolygon = "MultiSurface";

        /// <summary>
        /// Gml Collection
        /// </summary>
        internal const string Collection = "MultiGeometry";

        /// <summary>
        /// Gml FullGlobe
        /// </summary>
        internal const string FullGlobe = "FullGlobe";

        /// <summary>
        /// Gml Polygon exterior ring
        /// </summary>
        internal const string ExteriorRing = "exterior";

        /// <summary>
        /// Gml Polygon interior ring
        /// </summary>
        internal const string InteriorRing = "interior";

        /// <summary>
        /// Gml Ring
        /// </summary>
        internal const string LinearRing = "LinearRing";

        /// <summary>
        /// Member Tag for MultiPoint
        /// </summary>
        internal const string PointMember = "pointMember";

        /// <summary>
        /// Members Tag for MultiPoint
        /// </summary>
        internal const string PointMembers = "pointMembers";

        /// <summary>
        /// Member Tag for MultiLineString
        /// </summary>
        internal const string LineStringMember = "curveMember";

        /// <summary>
        /// Members Tag for MultiLineString
        /// </summary>
        internal const string LineStringMembers = "curveMembers";

        /// <summary>
        /// Member Tag for MultiPolygon
        /// </summary>
        internal const string PolygonMember = "surfaceMember";

        /// <summary>
        /// Members Tag for MultiPolygon
        /// </summary>
        internal const string PolygonMembers = "surfaceMembers";

        /// <summary>
        /// Member Tag for Collection
        /// </summary>
        internal const string CollectionMember = "geometryMember";

        /// <summary>
        /// Members Tag for Collection
        /// </summary>
        internal const string CollectionMembers = "geometryMembers";

        /// <summary>
        /// Attribute name for Axis Labels
        /// </summary>
        internal const string AxisLabels = "axisLabels";

        /// <summary>
        /// Attribute name for unit of measure labels
        /// </summary>
        internal const string UomLabels = "uomLabels";

        /// <summary>
        /// Attribute name for count
        /// </summary>
        internal const string Count = "count";
    }
}


text:
#pragma once

#include "mocca/net/framing/FramingStrategy.h"

#include <unordered_map>

namespace mocca {
namespace net {
class WebSocketProtocol : public FramingStrategy {
public:
    struct ConnectionInfo {
        std::string method;
        std::string path;
        std::string httpVersion;
        std::unordered_map<std::string, std::string> header;
    };

    std::unique_ptr<FramingStrategy> clone() const override;
    std::string name() const override;
    Message readMessageFromStream(IStreamConnection& connection) override;
    void writeMessageToStream(IStreamConnection& connection, Message frame) override;
    void performHandshake(IStreamConnection& connection) override;

private:
    void receiveHandshake(IStreamConnection& connection);
    void sendHandshakeResponse(IStreamConnection& connection);

private:
    ConnectionInfo connectionInfo_;
};
}
}


text:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.prevElementSibling = exports.nextElementSibling = exports.getName = exports.hasAttrib = exports.getAttributeValue = exports.getSiblings = exports.getParent = exports.getChildren = void 0;
var domhandler_1 = require("domhandler");
var emptyArray = [];
/**
 * Get a node's children.
 *
 * @param elem Node to get the children of.
 * @returns `elem`'s children, or an empty array.
 */
function getChildren(elem) {
    var _a;
    return (_a = elem.children) !== null && _a !== void 0 ? _a : emptyArray;
}
exports.getChildren = getChildren;
/**
 * Get a node's parent.
 *
 * @param elem Node to get the parent of.
 * @returns `elem`'s parent node.
 */
function getParent(elem) {
    return elem.parent || null;
}
exports.getParent = getParent;
/**
 * Gets an elements siblings, including the element itself.
 *
 * Attempts to get the children through the element's parent first.
 * If we don't have a parent (the element is a root node),
 * we walk the element's `prev` & `next` to get all remaining nodes.
 *
 * @param elem Element to get the siblings of.
 * @returns `elem`'s siblings.
 */
function getSiblings(elem) {
    var _a, _b;
    var parent = getParent(elem);
    if (parent != null)
        return getChildren(parent);
    var siblings = [elem];
    var prev = elem.prev, next = elem.next;
    while (prev != null) {
        siblings.unshift(prev);
        (_a = prev, prev = _a.prev);
    }
    while (next != null) {
        siblings.push(next);
        (_b = next, next = _b.next);
    }
    return siblings;
}
exports.getSiblings = getSiblings;
/**
 * Gets an attribute from an element.
 *
 * @param elem Element to check.
 * @param name Attribute name to retrieve.
 * @returns The element's attribute value, or `undefined`.
 */
function getAttributeValue(elem, name) {
    var _a;
    return (_a = elem.attribs) === null || _a === void 0 ? void 0 : _a[name];
}
exports.getAttributeValue = getAttributeValue;
/**
 * Checks whether an element has an attribute.
 *
 * @param elem Element to check.
 * @param name Attribute name to look for.
 * @returns Returns whether `elem` has the attribute `name`.
 */
function hasAttrib(elem, name) {
    return (elem.attribs != null &&
        Object.prototype.hasOwnProperty.call(elem.attribs, name) &&
        elem.attribs[name] != null);
}
exports.hasAttrib = hasAttrib;
/**
 * Get the tag name of an element.
 *
 * @param elem The element to get the name for.
 * @returns The tag name of `elem`.
 */
function getName(elem) {
    return elem.name;
}
exports.getName = getName;
/**
 * Returns the next element sibling of a node.
 *
 * @param elem The element to get the next sibling of.
 * @returns `elem`'s next sibling that is a tag.
 */
function nextElementSibling(elem) {
    var _a;
    var next = elem.next;
    while (next !== null && !(0, domhandler_1.isTag)(next))
        (_a = next, next = _a.next);
    return next;
}
exports.nextElementSibling = nextElementSibling;
/**
 * Returns the previous element sibling of a node.
 *
 * @param elem The element to get the previous sibling of.
 * @returns `elem`'s previous sibling that is a tag.
 */
function prevElementSibling(elem) {
    var _a;
    var prev = elem.prev;
    while (prev !== null && !(0, domhandler_1.isTag)(prev))
        (_a = prev, prev = _a.prev);
    return prev;
}
exports.prevElementSibling = prevElementSibling;


text:
<?php

namespace App\UserdirectoryBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 * @ORM\Table(name="user_apptitlelist")
 */
class AppTitleList extends ListAbstract
{

    /**
     * @ORM\OneToMany(targetEntity="AppTitleList", mappedBy="original")
     **/
    protected $synonyms;

    /**
     * @ORM\ManyToOne(targetEntity="AppTitleList", inversedBy="synonyms")
     * @ORM\JoinColumn(name="original_id", referencedColumnName="id")
     **/
    protected $original;

}