<commit_before>var assert = require('assert')

var _ = require('lodash')

var __ = require('@carbon-io/fibers').__(module)
var _o   = require('@carbon-io/bond')._o(module)
var o   = require('@carbon-io/atom').o(module)
var testtube = require('@carbon-io/test-tube')

/******************************************************************************
 *
 */
__(function() {
  module.exports = o.main({

    /****************************************************************************
     * _type
     */
    _type: _o("./TestBase"),

    /****************************************************************************
     * name
     */
    name: 'AsyncCollectionTest',

    /****************************************************************************
     *
     */
    tests: [
      o({
        _type: testtube.Test,
        name: 'FindToArrayTest',
        description: 'testing users collection async find toArray',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').find().toArray(function(e, data) {
            var err = undefined
            try {
              assert(data != null)
              assert(e == null)
              assert(data.length > 0)
              assert(data[0].username === 'abdul')
              assert(data[1].username === 'bob')
            } catch (e) {
              err = e
            }
            return done(e)
          })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'LimitTest',
        description: 'testing users collection async find (limit:1)',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').find(
            {}, {limit: 1}).toArray(function(e, data) {
              var err = undefined
              try {
                assert(data != null)
                assert(e == null)
                assert(data.length > 0)
                assert(data[0].username === 'abdul')
              } catch (e) {
                err = e
              }
              return done(err)
            })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'SkipResultTest',
        description: 'testing users collection async find (limit:1, skip:1)',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').find(
            {}, {limit: 1, skip: 1}).toArray(function(e, data) {
              var err = undefined
              try {
                assert(data != null)
                assert(e == null)
                assert(data.length > 0)
                assert(data[0].username === 'bob')
              } catch (e) {
                err = e
              }
              return done(err)
            })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'CursorNextTest',
        description: 'testing cursor.next',
        setup: function(ctx) {
          ctx.global.cursor = ctx.global.testClient.getCollection('users').find()
        },
        doTest: function(ctx, done) {
          ctx.global.cursor.next(function(e, obj) {
            var err = undefined
            try {
              assert(obj != null)
              assert(e == null)
              assert(obj.username === 'abdul')
            } catch (e) {
              err = e
            }
            return done(err)
          })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'CursorToArrayAfterNextTest',
        description: 'testing cursor.toArray() after next()',
        teardown: function(ctx) {
          delete ctx.global.cursor
        },
        doTest: function(ctx, done) {
          ctx.global.cursor.toArray(function(e, data) {
            var err = undefined
            try {
              assert(data != null)
              assert(e == null)
              assert(data.length == 1)
              assert(data[0].username === 'bob')
            } catch (e) {
              err = e
            }
            return done(err)
          })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'FindEachTest',
        description: 'testing find.forEach()',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').find().forEach(function(item) {
            assert(item.username === 'abdul' || item.username === 'bob')

          }, function(e) {
            assert(_.isNull(e))
            return done()
          })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'InsertTest',
        description: 'testing users collection async insert',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').insertObject({
              username: 'joe'
            }, function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(!_.isNull(result))
                assert(!_.isNull(result['_id']))
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),

      o({
        _type: testtube.Test,
        name: 'UpdateTest',
        description: 'testing users collection async update',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').update({
            username: 'joe'
          }, {
            '$set': {
              email: 'joe@foo.com'
            }
          }, function(e, result) {
            var err = undefined
            try {
              assert(_.isNull(e))
              assert(!_.isNull(result))
              assert(result.n == 1)
            } catch (e) {
              err = e
            }
            return done(err)
          })
        }
      }),

      o({
        _type: testtube.Test,
        name: 'RemoveTest',
        description: 'testing users collection async remove',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').remove({
              username: 'joe'
            }, function(e, result) {
              var err = undefined
              try {
                assert(e == null)
                assert(result != null)
                assert(result.n == 1)
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),
      o({
        _type: testtube.Test,
        name: 'RemoveObjectTest',
        description: 'testing users collection async removeObject',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').removeObject('123',
            function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(_.isNull(result))
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),
      o({
        _type: testtube.Test,
        name: 'SaveObjectTest',
        description: 'testing users collection async saveObject',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').saveObject('123', {
            _id: "123",
            username: 'joe'
          },
            function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(!_.isNull(result))
                assert.equal(result._id, '123')
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),

      o({
        _type: testtube.Test,
        name: 'UpdateObjectTest',
        description: 'testing users collection async update object',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').updateObject('123', {
              '$set': {
                email: 'joe@foo.com'
              }
            },
            function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(_.isNull(result))
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),
      o({
        _type: testtube.Test,
        name: 'InsertLiteTest',
        description: 'testing users collection async insert with no body',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('userlite').insertObject({
              username: 'bill'
            }, function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(!_.isNull(result))
                assert(!_.isNull(result['_id']))
                assert.equal(result['username'], 'bill')
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      })
    ]
  })
})
<commit_msg>testing insert/save + tweaks<commit_after>var assert = require('assert')

var _ = require('lodash')

var __ = require('@carbon-io/fibers').__(module)
var _o   = require('@carbon-io/bond')._o(module)
var o   = require('@carbon-io/atom').o(module)
var testtube = require('@carbon-io/test-tube')

/******************************************************************************
 *
 */
__(function() {
  module.exports = o.main({

    /****************************************************************************
     * _type
     */
    _type: _o("./TestBase"),

    /****************************************************************************
     * name
     */
    name: 'AsyncCollectionTest',

    /****************************************************************************
     *
     */
    tests: [
      o({
        _type: testtube.Test,
        name: 'FindToArrayTest',
        description: 'testing users collection async find toArray',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').find().toArray(function(e, data) {
            var err = undefined
            try {
              assert(data != null)
              assert(e == null)
              assert(data.length > 0)
              assert(data[0].username === 'abdul')
              assert(data[1].username === 'bob')
            } catch (e) {
              err = e
            }
            return done(e)
          })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'LimitTest',
        description: 'testing users collection async find (limit:1)',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').find(
            {}, {limit: 1}).toArray(function(e, data) {
              var err = undefined
              try {
                assert(data != null)
                assert(e == null)
                assert(data.length > 0)
                assert(data[0].username === 'abdul')
              } catch (e) {
                err = e
              }
              return done(err)
            })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'SkipResultTest',
        description: 'testing users collection async find (limit:1, skip:1)',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').find(
            {}, {limit: 1, skip: 1}).toArray(function(e, data) {
              var err = undefined
              try {
                assert(data != null)
                assert(e == null)
                assert(data.length > 0)
                assert(data[0].username === 'bob')
              } catch (e) {
                err = e
              }
              return done(err)
            })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'CursorNextTest',
        description: 'testing cursor.next',
        setup: function(ctx) {
          ctx.global.cursor = ctx.global.testClient.getCollection('users').find()
        },
        doTest: function(ctx, done) {
          ctx.global.cursor.next(function(e, obj) {
            var err = undefined
            try {
              assert(obj != null)
              assert(e == null)
              assert(obj.username === 'abdul')
            } catch (e) {
              err = e
            }
            return done(err)
          })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'CursorToArrayAfterNextTest',
        description: 'testing cursor.toArray() after next()',
        teardown: function(ctx) {
          delete ctx.global.cursor
        },
        doTest: function(ctx, done) {
          ctx.global.cursor.toArray(function(e, data) {
            var err = undefined
            try {
              assert(data != null)
              assert(e == null)
              assert(data.length == 1)
              assert(data[0].username === 'bob')
            } catch (e) {
              err = e
            }
            return done(err)
          })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'FindEachTest',
        description: 'testing find.forEach()',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').find().forEach(function(item) {
            assert(item.username === 'abdul' || item.username === 'bob')

          }, function(e) {
            assert(_.isNull(e))
            return done()
          })
        }
      }),
      o({
        _type: testtube.Test,
        name: 'InsertTest',
        description: 'testing users collection async insert',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').insert([{
              username: 'tim'
            }], function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(!_.isNull(result))
                assert(_.isArray(result))
                assert(!_.isNull(result[0]['_id']))
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),

      o({
        _type: testtube.Test,
        name: 'InsertObjectTest',
        description: 'testing users collection async insertObject',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').insertObject({
              username: 'chris'
            }, function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(!_.isNull(result))
                assert(!_.isNull(result['_id']))
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),

      o({
        _type: testtube.Test,
        name: 'UpdateTest',
        description: 'testing users collection async update',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').update({
            username: 'abdul'
          }, {
            '$set': {
              lastLogin: new Date()
            }
          }, function(e, result) {
            var err = undefined
            try {
              assert(_.isNull(e))
              assert(!_.isNull(result))
              assert(result.n == 1)
            } catch (e) {
              err = e
            }
            return done(err)
          })
        }
      }),

      o({
        _type: testtube.Test,
        name: 'RemoveTest',
        description: 'testing users collection async remove',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').remove({
              username: 'bob'
            }, function(e, result) {
              var err = undefined
              try {
                assert(e == null)
                assert(result != null)
                assert(result.n == 1)
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),
      o({
        _type: testtube.Test,
        name: 'RemoveObjectTest',
        description: 'testing users collection async removeObject',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').removeObject('123',
            function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(_.isNull(result))
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),

      o({
        _type: testtube.Test,
        name: 'SaveOTest',
        description: 'testing users collection async save',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').save([{
              _id: "123",
              username: 'joe'
            }],
            function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(!_.isNull(result))
                assert(_.isArray(result))
                assert.equal(result[0]._id, '123')
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),

      o({
        _type: testtube.Test,
        name: 'SaveObjectTest',
        description: 'testing users collection async saveObject',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').saveObject('123', {
            _id: "123",
            username: 'joe'
          },
            function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(!_.isNull(result))
                assert.equal(result._id, '123')
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),

      o({
        _type: testtube.Test,
        name: 'UpdateObjectTest',
        description: 'testing users collection async update object',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('users').updateObject('123', {
              '$set': {
                email: 'joe@foo.com'
              }
            },
            function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(_.isNull(result))
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      }),
      o({
        _type: testtube.Test,
        name: 'InsertLiteTest',
        description: 'testing users collection async insert with no body',
        doTest: function(ctx, done) {
          ctx.global.testClient.getCollection('userlite').insertObject({
              username: 'bill'
            }, function(e, result) {
              var err = undefined
              try {
                assert(_.isNull(e))
                assert(!_.isNull(result))
                assert(!_.isNull(result['_id']))
                assert.equal(result['username'], 'bill')
              } catch (e) {
                err = e
              }
              return done(err)
            }
          )
        }
      })
    ]
  })
})
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2015 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

define("joynr/util/Typing", [
    "joynr",
    "joynr/TypesEnum",
    "joynr/types/TypeRegistrySingleton"
], function(joynr, TypesEnum, TypeRegistrySingleton) {

    var translateJoynrTypeToJavascriptTypeTable = {};
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.BOOL] = "Boolean";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.BYTE] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.SHORT] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.INT] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.LONG] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.FLOAT] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.DOUBLE] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.STRING] = "String";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.LIST] = "Array";

    /**
     * @name Typing
     * @class
     */
    var Typing = {};

    /**
     * @function Typing#getObjectType
     * @param {Boolean|Number|String|Object}
     *            obj the object to determine the type of
     * @returns {String} the object type
     */
    Typing.getObjectType = function(obj) {
        if (obj === null || obj === undefined) {
            throw new Error("cannot determine the type of an undefined object");
        }
        var funcNameRegex = /function ([$\w]+)\(/;
        var results = funcNameRegex.exec(obj.constructor.toString());
        return (results && results.length > 1) ? results[1] : "";
    };

    /**
     * Translates the Joynr Types to Javascript Types
     *
     * @function Typing#translateJoynrTypeToJavascriptType
     * @param {String} joynrType the joynr type string
     * @returns {String} the javascript type or the joynrType if not found
     * @throws {Error} an error when input parameters are nullable (undefined or null)
     */
    Typing.translateJoynrTypeToJavascriptType = function(joynrType) {
        if (joynrType === undefined || joynrType === null) {
            throw new Error("cannot determine javascript type of \"" + joynrType + "\"");
        }

        return translateJoynrTypeToJavascriptTypeTable[joynrType] || joynrType;
    };

    /**
     * Recursively deep copies a given object and augments type information on the way if a
     * constructor is registered in the typeRegistry for the value of the object's
     * member "_typeName"
     *
     * @function Typing#augmentTypes
     * @param {Boolean|Number|String|Array|Object}
     *            untyped the untyped object
     * @param {TypeRegistry}
     *            typeRegistry the typeRegistry to retrieve type information from
     * @param {String}
     *            typeHint optional parameter which provides the type informed of the untyped object.
     *            This is used i.e. for enums, where the type information is not included in the untyped object itself
     * @returns a deep copy of the untyped object with the types being augmented
     * @throws {Error}
     *             if in any of the objects contains a member of type "Function" or the type of the
     *             untyped object is not (Boolean|Number|String|Array|Object)
     */
    Typing.augmentTypes =
            function(untyped, typeRegistry, typeHint) {
                var i, typedObj, typeName;

                // return nullable values immediately
                if (untyped === null || untyped === undefined) {
                    return untyped;
                }

                // retrieve the javascript runtime type info
                var type = Typing.getObjectType(untyped);

                // what should we do with a function?
                if (type === "Function") {
                    // functions should not at all appear here!!!
                    throw new Error("cannot augment object type \"" + type + "\"");
                }

                // try to type each single element of an array
                if (type === "Array") {
                    typedObj = [];
                    for (i = 0; i < untyped.length; ++i) {
                        typedObj.push(Typing.augmentTypes(untyped[i], typeRegistry, typeHint));
                    }
                }
                //check if provisioned type name is given. In this case, check for special considerations
                else if (typeHint !== undefined && typeRegistry.isEnumType(typeHint)) {
                    typedObj = typeRegistry.getConstructor(typeHint)[untyped];
                }
                // leave integral data types untyped
                else if (type === "Boolean" || type === "Number" || type === "String") {
                    typedObj = untyped;
                }
                // try to type each single member of an object, and use registered constructor if
                // available
                else if (type === "Object") {
                    /*jslint nomen: true */
                    var Constructor = typeRegistry.getConstructor(untyped._typeName);
                    /*jslint nomen: false */

                    // if object has joynr type name and corresponding constructor is found in the
                    // type registry, construct it, otherwise throw an error
                    if (Constructor) {
                        typedObj = new Constructor();
                    } else {
                        throw new Error(
                                "type must contain a _typeName that is registered in the type registry: "
                                    + JSON.stringify(untyped));
                    }

                    // copy over and type each single member
                    for (i in untyped) {
                        if (untyped.hasOwnProperty(i)) {
                            if (Constructor.getMemberType !== undefined) {
                                typedObj[i] =
                                        Typing.augmentTypes(untyped[i], typeRegistry, Constructor
                                                .getMemberType(i));
                            } else {
                                typedObj[i] = Typing.augmentTypes(untyped[i], typeRegistry);
                            }
                        }
                    }
                } else {
                    // encountered an unknown object type, that should not appear here
                    throw new Error("encountered unknown object \""
                        + JSON.stringify(untyped)
                        + "\" of type \""
                        + type
                        + "\" while augmenting types");
                }

                return typedObj;
            };

    /**
     * Augments the javascript runtime type into the member "_typeName"
     *
     * @function Typing#augmentTypeName
     * @param {?} obj the object to augment the typeName for
     * @param {String} [packageName] an optional packageName that is used as starting string for
     *             _typeName
     * @param {String} [memberName] an optional member name that is used instead of _typeName
     *
     * @returns {?} the same object with the typeName set
     */
    Typing.augmentTypeName = function(obj, packageName, memberName) {
        packageName = packageName === undefined ? "" : packageName + ".";
        obj[memberName || "_typeName"] = packageName + Typing.getObjectType(obj);
        return obj;
    };

    /**
     * Returns true if the object is a joynr complex type modelled in Franca
     * @function Typing#isComplexJoynrObject
     */
    Typing.isComplexJoynrObject = function isComplexJoynrObject(value) {
        try {
            var valuePrototype = Object.getPrototypeOf(value);
            return (valuePrototype && valuePrototype instanceof joynr.JoynrObject);
        } catch (error) {
            // This can be the case when the value is a primitive type
        }
        return false;
    };

    /**
     * Returns true if the object is a joynr enum type modelled in Franca
     * @function Typing#isEnumType
     * @param {Object} value the object to be check for typing
     * @param {Boolean} checkForJoynrObject an optional member. If set to true,
     *                  the parameter value is forced to be an instance of the root
     *                  joynr object type
     * @returns {Boolean} true if the provided value is an enum type
     */
    Typing.isEnumType =
            function isEnumType(value, checkForJoynrObject) {
                var isJoynrObject =
                        checkForJoynrObject === undefined
                            || (!checkForJoynrObject || Typing.isComplexJoynrObject(value));
                /*jslint nomen: true */
                var result =
                        typeof value === "object"
                            && isJoynrObject
                            && TypeRegistrySingleton.getInstance().isEnumType(value._typeName);
                /*jslint nomen: false */
                return result;
            };

    return Typing;

});<commit_msg>[JS] Typining.augmentTypes can also be invoked for typed objects<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2015 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

define("joynr/util/Typing", [
    "joynr",
    "joynr/TypesEnum",
    "joynr/types/TypeRegistrySingleton"
], function(joynr, TypesEnum, TypeRegistrySingleton) {

    var translateJoynrTypeToJavascriptTypeTable = {};
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.BOOL] = "Boolean";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.BYTE] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.SHORT] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.INT] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.LONG] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.FLOAT] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.DOUBLE] = "Number";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.STRING] = "String";
    translateJoynrTypeToJavascriptTypeTable[TypesEnum.LIST] = "Array";

    /**
     * @name Typing
     * @class
     */
    var Typing = {};

    /**
     * @function Typing#getObjectType
     * @param {Boolean|Number|String|Object}
     *            obj the object to determine the type of
     * @returns {String} the object type
     */
    Typing.getObjectType = function(obj) {
        if (obj === null || obj === undefined) {
            throw new Error("cannot determine the type of an undefined object");
        }
        var funcNameRegex = /function ([$\w]+)\(/;
        var results = funcNameRegex.exec(obj.constructor.toString());
        return (results && results.length > 1) ? results[1] : "";
    };

    /**
     * Translates the Joynr Types to Javascript Types
     *
     * @function Typing#translateJoynrTypeToJavascriptType
     * @param {String} joynrType the joynr type string
     * @returns {String} the javascript type or the joynrType if not found
     * @throws {Error} an error when input parameters are nullable (undefined or null)
     */
    Typing.translateJoynrTypeToJavascriptType = function(joynrType) {
        if (joynrType === undefined || joynrType === null) {
            throw new Error("cannot determine javascript type of \"" + joynrType + "\"");
        }

        return translateJoynrTypeToJavascriptTypeTable[joynrType] || joynrType;
    };

    /**
     * Recursively deep copies a given object and augments type information on the way if a
     * constructor is registered in the typeRegistry for the value of the object's
     * member "_typeName"
     *
     * @function Typing#augmentTypes
     * @param {Boolean|Number|String|Array|Object}
     *            untyped the untyped object
     * @param {TypeRegistry}
     *            typeRegistry the typeRegistry to retrieve type information from
     * @param {String}
     *            typeHint optional parameter which provides the type informed of the untyped object.
     *            This is used i.e. for enums, where the type information is not included in the untyped object itself
     * @returns a deep copy of the untyped object with the types being augmented
     * @throws {Error}
     *             if in any of the objects contains a member of type "Function" or the type of the
     *             untyped object is not (Boolean|Number|String|Array|Object)
     */
    Typing.augmentTypes =
            function(untyped, typeRegistry, typeHint) {
                var i, typedObj, typeName;

                // return nullable values immediately
                if (untyped === null || untyped === undefined) {
                    return untyped;
                }

                // return already typed objects immediately
                if (Typing.isComplexJoynrObject(untyped)) {
                    return untyped;
                }

                // retrieve the javascript runtime type info
                var type = Typing.getObjectType(untyped);

                // what should we do with a function?
                if (type === "Function") {
                    // functions should not at all appear here!!!
                    throw new Error("cannot augment object type \"" + type + "\"");
                }

                // try to type each single element of an array
                if (type === "Array") {
                    typedObj = [];
                    for (i = 0; i < untyped.length; ++i) {
                        typedObj.push(Typing.augmentTypes(untyped[i], typeRegistry, typeHint));
                    }
                }
                //check if provisioned type name is given. In this case, check for special considerations
                else if (typeHint !== undefined && typeRegistry.isEnumType(typeHint)) {
                    typedObj = typeRegistry.getConstructor(typeHint)[untyped];
                }
                // leave integral data types untyped
                else if (type === "Boolean" || type === "Number" || type === "String") {
                    typedObj = untyped;
                }
                // try to type each single member of an object, and use registered constructor if
                // available
                else if (type === "Object") {
                    /*jslint nomen: true */
                    var Constructor = typeRegistry.getConstructor(untyped._typeName);
                    /*jslint nomen: false */

                    // if object has joynr type name and corresponding constructor is found in the
                    // type registry, construct it, otherwise throw an error
                    if (Constructor) {
                        typedObj = new Constructor();
                    } else {
                        throw new Error(
                                "type must contain a _typeName that is registered in the type registry: "
                                    + JSON.stringify(untyped));
                    }

                    // copy over and type each single member
                    for (i in untyped) {
                        if (untyped.hasOwnProperty(i)) {
                            if (Constructor.getMemberType !== undefined) {
                                typedObj[i] =
                                        Typing.augmentTypes(untyped[i], typeRegistry, Constructor
                                                .getMemberType(i));
                            } else {
                                typedObj[i] = Typing.augmentTypes(untyped[i], typeRegistry);
                            }
                        }
                    }
                } else {
                    // encountered an unknown object type, that should not appear here
                    throw new Error("encountered unknown object \""
                        + JSON.stringify(untyped)
                        + "\" of type \""
                        + type
                        + "\" while augmenting types");
                }

                return typedObj;
            };

    /**
     * Augments the javascript runtime type into the member "_typeName"
     *
     * @function Typing#augmentTypeName
     * @param {?} obj the object to augment the typeName for
     * @param {String} [packageName] an optional packageName that is used as starting string for
     *             _typeName
     * @param {String} [memberName] an optional member name that is used instead of _typeName
     *
     * @returns {?} the same object with the typeName set
     */
    Typing.augmentTypeName = function(obj, packageName, memberName) {
        packageName = packageName === undefined ? "" : packageName + ".";
        obj[memberName || "_typeName"] = packageName + Typing.getObjectType(obj);
        return obj;
    };

    /**
     * Returns true if the object is a joynr complex type modelled in Franca
     * @function Typing#isComplexJoynrObject
     */
    Typing.isComplexJoynrObject = function isComplexJoynrObject(value) {
        try {
            var valuePrototype = Object.getPrototypeOf(value);
            return (valuePrototype && valuePrototype instanceof joynr.JoynrObject);
        } catch (error) {
            // This can be the case when the value is a primitive type
        }
        return false;
    };

    /**
     * Returns true if the object is a joynr enum type modelled in Franca
     * @function Typing#isEnumType
     * @param {Object} value the object to be check for typing
     * @param {Boolean} checkForJoynrObject an optional member. If set to true,
     *                  the parameter value is forced to be an instance of the root
     *                  joynr object type
     * @returns {Boolean} true if the provided value is an enum type
     */
    Typing.isEnumType =
            function isEnumType(value, checkForJoynrObject) {
                var isJoynrObject =
                        checkForJoynrObject === undefined
                            || (!checkForJoynrObject || Typing.isComplexJoynrObject(value));
                /*jslint nomen: true */
                var result =
                        typeof value === "object"
                            && isJoynrObject
                            && TypeRegistrySingleton.getInstance().isEnumType(value._typeName);
                /*jslint nomen: false */
                return result;
            };

    return Typing;

});<|endoftext|>


<commit_before>'use strict'

const { getMhub } = require('./.get/get-mhub')
const { getCaddy } = require('./.get/get-caddy')
const { getMongo } = require('./.get/get-mongo')
const { getNpmModule } = require('./.get/get-npm-module')
const { getByHttp } = require('./.get/get-by-http')

// eslint-disable-next-line node/exports-style
module.exports = {
  modules: {
    caddy: {
      internal: true,
      get: getCaddy
    },
    mongo: {
      internal: true,
      get: getMongo
    },
    mhub: {
      internal: true,
      get: getMhub,
      options: {
        package: 'mhub',
        version: '0.9.1'
      }
    },
    'identity-provider': {
      get: getNpmModule,
      options: {
        version: 'FirstLegoLeague/identity-provider#83c597a4fb35a680fb447837d402546066d5909a'
      }
    },
    display: {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/display',
        version: '2.4.3'
      }
    },
    tournament: {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/tournament',
        version: '2.0.2'
      }
    },
    'tournament-status': {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/tournament-status',
        version: '1.0.0'
      }
    },
    scoring: {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/scoring',
        version: '2.3.4'
      }
    },
    rankings: {
      get: getNpmModule,
      options: {
        version: 'FirstLegoLeague/rankings#680fd8f4ac5b4d0ce9f58248050e2ccc9d67f0c0'
      }
    },
    clock: {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/clock',
        version: '2.4.2'
      }
    }
  },
  custom: {
    npm: getNpmModule,
    http: getByHttp
  }
}
<commit_msg>Including scoring PR#85 bugfixes<commit_after>'use strict'

const { getMhub } = require('./.get/get-mhub')
const { getCaddy } = require('./.get/get-caddy')
const { getMongo } = require('./.get/get-mongo')
const { getNpmModule } = require('./.get/get-npm-module')
const { getByHttp } = require('./.get/get-by-http')

// eslint-disable-next-line node/exports-style
module.exports = {
  modules: {
    caddy: {
      internal: true,
      get: getCaddy
    },
    mongo: {
      internal: true,
      get: getMongo
    },
    mhub: {
      internal: true,
      get: getMhub,
      options: {
        package: 'mhub',
        version: '0.9.1'
      }
    },
    'identity-provider': {
      get: getNpmModule,
      options: {
        version: 'FirstLegoLeague/identity-provider#83c597a4fb35a680fb447837d402546066d5909a'
      }
    },
    display: {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/display',
        version: '2.4.3'
      }
    },
    tournament: {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/tournament',
        version: '2.0.2'
      }
    },
    'tournament-status': {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/tournament-status',
        version: '1.0.0'
      }
    },
    scoring: {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/scoring',
        version: '2.3.5'
      }
    },
    rankings: {
      get: getNpmModule,
      options: {
        version: 'FirstLegoLeague/rankings#680fd8f4ac5b4d0ce9f58248050e2ccc9d67f0c0'
      }
    },
    clock: {
      get: getNpmModule,
      options: {
        package: '@first-lego-league/clock',
        version: '2.4.2'
      }
    }
  },
  custom: {
    npm: getNpmModule,
    http: getByHttp
  }
}
<|endoftext|>


<commit_before>// Copyright 2014-2017, University of Colorado Boulder

/**
 * General dialog type
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var AccessibilityUtil = require( 'SCENERY/accessibility/AccessibilityUtil' );
  var AriaHerald = require( 'SCENERY_PHET/accessibility/AriaHerald' );
  var Display = require( 'SCENERY/display/Display' );
  var FullScreen = require( 'JOIST/FullScreen' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Input = require( 'SCENERY/input/Input' );
  var joist = require( 'JOIST/joist' );
  var JoistA11yStrings = require( 'JOIST/JoistA11yStrings' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Panel = require( 'SUN/Panel' );
  var Path = require( 'SCENERY/nodes/Path' );
  var RectangularPushButton = require( 'SUN/buttons/RectangularPushButton' );
  var Shape = require( 'KITE/Shape' );
  var Tandem = require( 'TANDEM/Tandem' );
  var TDialog = require( 'JOIST/TDialog' );

  // strings
  var closeString = JoistA11yStrings.closeString;

  /**
   * @param {Node} content - The content to display inside the dialog (not including the title)
   * @param {Object} [options]
   * @constructor
   */
  function Dialog( content, options ) {

    var self = this;
    options = _.extend( {

      // Dialog-specific options
      modal: false, // {boolean} modal dialogs prevent interaction with the rest of the sim while open
      title: null, // {Node} title to be displayed at top
      titleAlign: 'center', // horizontal alignment of the title: {string} left, right or center
      titleSpacing: 20, // {number} how far the title is placed above the content
      hasCloseButton: true, // whether to put a close 'X' button is upper-right corner

      // {function} which sets the dialog's position in global coordinates. called as
      // layoutStrategy( dialog, simBounds, screenBounds, scale )
      layoutStrategy: Dialog.DEFAULT_LAYOUT_STRATEGY,

      // pass through to Panel options
      cornerRadius: 10, // {number} radius of the dialog's corners
      resize: true, // {boolean} whether to resize if content's size changes
      fill: 'white', // {string|Color}
      stroke: 'black', // {string|Color}
      backgroundPickable: true,
      xMargin: 20,
      yMargin: 20,
      closeButtonBaseColor: '#d00',
      closeButtonMargin: 5, // {number} how far away should the close button be from the panel border
      tandem: Tandem.tandemRequired(),
      phetioType: TDialog,

      // a11y options
      tagName: 'div',
      ariaRole: 'dialog',
      focusOnCloseNode: null // {Node} receives focus on close, if null focus returns to element that had focus on open
    }, options );

    // @private (read-only)
    this.isModal = options.modal;

    // see https://github.com/phetsims/joist/issues/293
    assert && assert( this.isModal, 'Non-modal dialogs not currently supported' );

    // @private - whether the dialog is showing
    this.isShowing = false;

    var dialogContent = new Node( {
      children: [ content ]
    } );

    if ( options.title ) {

      var titleNode = options.title;
      dialogContent.addChild( titleNode );

      var updateTitlePosition = function() {
        switch( options.titleAlign ) {
          case 'center':
            titleNode.centerX = content.centerX;
            break;
          case 'left':
            titleNode.left = content.left;
            break;
          case 'right':
            titleNode.right = content.right;
            break;
          default:
            throw new Error( 'unknown titleAlign for Dialog: ' + options.titleAlign );
        }
        titleNode.bottom = content.top - options.titleSpacing;
      };

      if ( options.resize ) {
        content.on( 'bounds', updateTitlePosition );
        titleNode.on( 'localBounds', updateTitlePosition );
      }
      updateTitlePosition();
    }

    Panel.call( this, dialogContent, options );

    if ( options.hasCloseButton ) {

      var crossSize = 10;
      var crossNode = new Path( new Shape().moveTo( 0, 0 ).lineTo( crossSize, crossSize ).moveTo( 0, crossSize ).lineTo( crossSize, 0 ), {
        stroke: '#fff',
        lineWidth: 3
      } );

      var closeButton = new RectangularPushButton( {
        content: crossNode,
        baseColor: options.closeButtonBaseColor,
        xMargin: 5,
        yMargin: 5,
        listener: function() {
          self.hide();
        },
        accessibleFire: function() {
          self.focusActiveElement();
        },
        tandem: options.tandem.createTandem( 'closeButton' ),

        // a11y options
        tagName: 'button',
        accessibleLabel: closeString
      } );
      this.addChild( closeButton );

      var updateClosePosition = function() {
        closeButton.right = dialogContent.right + options.xMargin - options.closeButtonMargin;
        closeButton.top = dialogContent.top - options.yMargin + options.closeButtonMargin;

        // place the focus highlight, and make it a bit bigger than the
        closeButton.focusHighlight = Shape.bounds( crossNode.bounds.dilated( 10 ) );
      };

      if ( options.resize ) {
        dialogContent.on( 'bounds', updateClosePosition );
        if ( options.title ) {
          options.title.on( 'bounds', updateClosePosition );
        }
      }
      updateClosePosition();
    }

    var sim = window.phet.joist.sim;

    // @private
    this.updateLayout = function() {
      options.layoutStrategy( self, sim.boundsProperty.value, sim.screenBoundsProperty.value, sim.scaleProperty.value );
    };

    this.updateLayout();

    // @private
    this.sim = sim;

    // a11y - set the order of content for accessibility, title before content
    this.accessibleOrder = [ titleNode, dialogContent ];

    // a11y - set the aria labelledby and describedby relations so that whenever focus enters the dialog, the title
    // and description content are read in full
    content.tagName && this.setAriaDescribedByNode( content );
    if ( options.title ) {
      options.title.tagName && this.setAriaLabelledByNode( options.title );
    }

    // must be removed on dispose
    this.sim.resizedEmitter.addListener( this.updateLayout );

    // @private (a11y) - the active element when the dialog is shown, tracked so that focus can be restored on close
    this.activeElement = options.focusOnCloseNode || null;

    // a11y - close the dialog when pressing "escape"
    var escapeListener = this.addAccessibleInputListener( {
      keydown: function( event ) {
        if ( event.keyCode === Input.KEY_ESCAPE ) {
          event.preventDefault();
          self.hide();
          self.focusActiveElement();
        }
        else if ( event.keyCode === Input.KEY_TAB && FullScreen.isFullScreen() ) {

          // prevent a particular bug in Windows 7/8.1 Firefox where focus gets trapped in the document
          // when the navigation bar is hidden and there is only one focusable element in the DOM
          // see https://bugzilla.mozilla.org/show_bug.cgi?id=910136
          var activeElement = Display.focusedNode;
          var noNextFocusable = AccessibilityUtil.getNextFocusable() === activeElement;
          var noPreviousFocusable = AccessibilityUtil.getPreviousFocusable() === activeElement;

          if ( noNextFocusable && noPreviousFocusable ) {
            event.preventDefault();
          }
        }
      }
    } );

    // @private - to be called on dispose()
    this.disposeDialog = function() {
      options.tandem.removeInstance( this );
      self.sim.resizedEmitter.removeListener( self.updateLayout );
      self.removeAccessibleInputListener( escapeListener );

      if ( options.hasCloseButton ) {
        closeButton.dispose();
      }

      if ( options.resize ) {
        dialogContent.off( 'bounds', updateClosePosition );
        if ( options.title ) {
          options.title.off( 'bounds', updateClosePosition );
          titleNode.off( 'localBounds', updateTitlePosition );
          content.off( 'bounds', updateTitlePosition );
        }
      }

      // remove dialog content from scene graph, but don't dispose because Panel
      // needs to remove listeners on the content in its dispose()
      dialogContent.removeAllChildren();
      dialogContent.detach();
    };
  }

  joist.register( 'Dialog', Dialog );

  // @private
  Dialog.DEFAULT_LAYOUT_STRATEGY = function( dialog, simBounds, screenBounds, scale ) {

    // The size is set in the Sim.topLayer, but we need to update the location here
    dialog.center = simBounds.center.times( 1.0 / scale );
  };

  return inherit( Panel, Dialog, {

    // @public
    show: function() {
      if ( !this.isShowing ) {
        window.phet.joist.sim.showPopup( this, this.isModal );
        this.isShowing = true;

        // a11y - store the currently active element before hiding all other accessible content
        // so that the active element isn't blurred
        this.activeElement = this.activeElement || Display.focusedNode;
        this.setAccessibleViewsVisible( false );

        // In case the window size has changed since the dialog was hidden, we should try layout out again.
        // See https://github.com/phetsims/joist/issues/362
        this.updateLayout();
      }
    },

    /**
     * Hide the dialog.  If you create a new dialog next time you show(), be sure to dispose this
     * dialog instead.
     * @public
     */
    hide: function() {
      if ( this.isShowing ) {
        window.phet.joist.sim.hidePopup( this, this.isModal );
        this.isShowing = false;

        // a11y - when the dialog is hidden, make all ScreenView content visible to assistive technology
        this.setAccessibleViewsVisible( true );
      }
    },

    /**
     * Make eligible for garbage collection.
     * @public
     */
    dispose: function() {
      this.hide();
      this.disposeDialog();
      Panel.prototype.dispose.call( this );
    },

    /**
     * Hide or show all accessible content related to the sim ScreenViews, navigation bar, and alert content. Instead
     * of using setVisible, we have to remove the subtree of accessible content from each view element in order to
     * prevent an IE11 bug where content remains invisible in the accessibility tree, see
     * https://github.com/phetsims/john-travoltage/issues/247
     *
     * @param {boolean} visible
     */
    setAccessibleViewsVisible: function( visible ) {
      for ( var i = 0; i < this.sim.screens.length; i++ ) {
        this.sim.screens[ i ].view.accessibleContentDisplayed = visible;
      }
      this.sim.navigationBar.accessibleContentDisplayed = visible;

      // workaround for a strange Edge bug where this child of the navigation bar remains visible,
      // see https://github.com/phetsims/a11y-research/issues/30
      this.sim.navigationBar.keyboardHelpButton.accessibleVisible = visible;

      // clear the aria-live alert content from the DOM
      AriaHerald.clearAll();
    },

    /**
     * If there is an active element, focus it.  Should almost always be closed after the Dialog has been closed.
     *
     * @public
     * @a11y
     */
    focusActiveElement: function() {
      this.activeElement && this.activeElement.focus();
    }
  } );
} );<commit_msg>dilate focus highlight less since we dilate in FocusOverlay now by default, https://github.com/phetsims/scenery/issues/676<commit_after>// Copyright 2014-2017, University of Colorado Boulder

/**
 * General dialog type
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var AccessibilityUtil = require( 'SCENERY/accessibility/AccessibilityUtil' );
  var AriaHerald = require( 'SCENERY_PHET/accessibility/AriaHerald' );
  var Display = require( 'SCENERY/display/Display' );
  var FullScreen = require( 'JOIST/FullScreen' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Input = require( 'SCENERY/input/Input' );
  var joist = require( 'JOIST/joist' );
  var JoistA11yStrings = require( 'JOIST/JoistA11yStrings' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Panel = require( 'SUN/Panel' );
  var Path = require( 'SCENERY/nodes/Path' );
  var RectangularPushButton = require( 'SUN/buttons/RectangularPushButton' );
  var Shape = require( 'KITE/Shape' );
  var Tandem = require( 'TANDEM/Tandem' );
  var TDialog = require( 'JOIST/TDialog' );

  // strings
  var closeString = JoistA11yStrings.closeString;

  /**
   * @param {Node} content - The content to display inside the dialog (not including the title)
   * @param {Object} [options]
   * @constructor
   */
  function Dialog( content, options ) {

    var self = this;
    options = _.extend( {

      // Dialog-specific options
      modal: false, // {boolean} modal dialogs prevent interaction with the rest of the sim while open
      title: null, // {Node} title to be displayed at top
      titleAlign: 'center', // horizontal alignment of the title: {string} left, right or center
      titleSpacing: 20, // {number} how far the title is placed above the content
      hasCloseButton: true, // whether to put a close 'X' button is upper-right corner

      // {function} which sets the dialog's position in global coordinates. called as
      // layoutStrategy( dialog, simBounds, screenBounds, scale )
      layoutStrategy: Dialog.DEFAULT_LAYOUT_STRATEGY,

      // pass through to Panel options
      cornerRadius: 10, // {number} radius of the dialog's corners
      resize: true, // {boolean} whether to resize if content's size changes
      fill: 'white', // {string|Color}
      stroke: 'black', // {string|Color}
      backgroundPickable: true,
      xMargin: 20,
      yMargin: 20,
      closeButtonBaseColor: '#d00',
      closeButtonMargin: 5, // {number} how far away should the close button be from the panel border
      tandem: Tandem.tandemRequired(),
      phetioType: TDialog,

      // a11y options
      tagName: 'div',
      ariaRole: 'dialog',
      focusOnCloseNode: null // {Node} receives focus on close, if null focus returns to element that had focus on open
    }, options );

    // @private (read-only)
    this.isModal = options.modal;

    // see https://github.com/phetsims/joist/issues/293
    assert && assert( this.isModal, 'Non-modal dialogs not currently supported' );

    // @private - whether the dialog is showing
    this.isShowing = false;

    var dialogContent = new Node( {
      children: [ content ]
    } );

    if ( options.title ) {

      var titleNode = options.title;
      dialogContent.addChild( titleNode );

      var updateTitlePosition = function() {
        switch( options.titleAlign ) {
          case 'center':
            titleNode.centerX = content.centerX;
            break;
          case 'left':
            titleNode.left = content.left;
            break;
          case 'right':
            titleNode.right = content.right;
            break;
          default:
            throw new Error( 'unknown titleAlign for Dialog: ' + options.titleAlign );
        }
        titleNode.bottom = content.top - options.titleSpacing;
      };

      if ( options.resize ) {
        content.on( 'bounds', updateTitlePosition );
        titleNode.on( 'localBounds', updateTitlePosition );
      }
      updateTitlePosition();
    }

    Panel.call( this, dialogContent, options );

    if ( options.hasCloseButton ) {

      var crossSize = 10;
      var crossNode = new Path( new Shape().moveTo( 0, 0 ).lineTo( crossSize, crossSize ).moveTo( 0, crossSize ).lineTo( crossSize, 0 ), {
        stroke: '#fff',
        lineWidth: 3
      } );

      var closeButton = new RectangularPushButton( {
        content: crossNode,
        baseColor: options.closeButtonBaseColor,
        xMargin: 5,
        yMargin: 5,
        listener: function() {
          self.hide();
        },
        accessibleFire: function() {
          self.focusActiveElement();
        },
        tandem: options.tandem.createTandem( 'closeButton' ),

        // a11y options
        tagName: 'button',
        accessibleLabel: closeString
      } );
      this.addChild( closeButton );

      var updateClosePosition = function() {
        closeButton.right = dialogContent.right + options.xMargin - options.closeButtonMargin;
        closeButton.top = dialogContent.top - options.yMargin + options.closeButtonMargin;

        // place the focus highlight, and make it a bit bigger than the
        closeButton.focusHighlight = Shape.bounds( crossNode.bounds.dilated( 8 ) );
      };

      if ( options.resize ) {
        dialogContent.on( 'bounds', updateClosePosition );
        if ( options.title ) {
          options.title.on( 'bounds', updateClosePosition );
        }
      }
      updateClosePosition();
    }

    var sim = window.phet.joist.sim;

    // @private
    this.updateLayout = function() {
      options.layoutStrategy( self, sim.boundsProperty.value, sim.screenBoundsProperty.value, sim.scaleProperty.value );
    };

    this.updateLayout();

    // @private
    this.sim = sim;

    // a11y - set the order of content for accessibility, title before content
    this.accessibleOrder = [ titleNode, dialogContent ];

    // a11y - set the aria labelledby and describedby relations so that whenever focus enters the dialog, the title
    // and description content are read in full
    content.tagName && this.setAriaDescribedByNode( content );
    if ( options.title ) {
      options.title.tagName && this.setAriaLabelledByNode( options.title );
    }

    // must be removed on dispose
    this.sim.resizedEmitter.addListener( this.updateLayout );

    // @private (a11y) - the active element when the dialog is shown, tracked so that focus can be restored on close
    this.activeElement = options.focusOnCloseNode || null;

    // a11y - close the dialog when pressing "escape"
    var escapeListener = this.addAccessibleInputListener( {
      keydown: function( event ) {
        if ( event.keyCode === Input.KEY_ESCAPE ) {
          event.preventDefault();
          self.hide();
          self.focusActiveElement();
        }
        else if ( event.keyCode === Input.KEY_TAB && FullScreen.isFullScreen() ) {

          // prevent a particular bug in Windows 7/8.1 Firefox where focus gets trapped in the document
          // when the navigation bar is hidden and there is only one focusable element in the DOM
          // see https://bugzilla.mozilla.org/show_bug.cgi?id=910136
          var activeElement = Display.focusedNode;
          var noNextFocusable = AccessibilityUtil.getNextFocusable() === activeElement;
          var noPreviousFocusable = AccessibilityUtil.getPreviousFocusable() === activeElement;

          if ( noNextFocusable && noPreviousFocusable ) {
            event.preventDefault();
          }
        }
      }
    } );

    // @private - to be called on dispose()
    this.disposeDialog = function() {
      options.tandem.removeInstance( this );
      self.sim.resizedEmitter.removeListener( self.updateLayout );
      self.removeAccessibleInputListener( escapeListener );

      if ( options.hasCloseButton ) {
        closeButton.dispose();
      }

      if ( options.resize ) {
        dialogContent.off( 'bounds', updateClosePosition );
        if ( options.title ) {
          options.title.off( 'bounds', updateClosePosition );
          titleNode.off( 'localBounds', updateTitlePosition );
          content.off( 'bounds', updateTitlePosition );
        }
      }

      // remove dialog content from scene graph, but don't dispose because Panel
      // needs to remove listeners on the content in its dispose()
      dialogContent.removeAllChildren();
      dialogContent.detach();
    };
  }

  joist.register( 'Dialog', Dialog );

  // @private
  Dialog.DEFAULT_LAYOUT_STRATEGY = function( dialog, simBounds, screenBounds, scale ) {

    // The size is set in the Sim.topLayer, but we need to update the location here
    dialog.center = simBounds.center.times( 1.0 / scale );
  };

  return inherit( Panel, Dialog, {

    // @public
    show: function() {
      if ( !this.isShowing ) {
        window.phet.joist.sim.showPopup( this, this.isModal );
        this.isShowing = true;

        // a11y - store the currently active element before hiding all other accessible content
        // so that the active element isn't blurred
        this.activeElement = this.activeElement || Display.focusedNode;
        this.setAccessibleViewsVisible( false );

        // In case the window size has changed since the dialog was hidden, we should try layout out again.
        // See https://github.com/phetsims/joist/issues/362
        this.updateLayout();
      }
    },

    /**
     * Hide the dialog.  If you create a new dialog next time you show(), be sure to dispose this
     * dialog instead.
     * @public
     */
    hide: function() {
      if ( this.isShowing ) {
        window.phet.joist.sim.hidePopup( this, this.isModal );
        this.isShowing = false;

        // a11y - when the dialog is hidden, make all ScreenView content visible to assistive technology
        this.setAccessibleViewsVisible( true );
      }
    },

    /**
     * Make eligible for garbage collection.
     * @public
     */
    dispose: function() {
      this.hide();
      this.disposeDialog();
      Panel.prototype.dispose.call( this );
    },

    /**
     * Hide or show all accessible content related to the sim ScreenViews, navigation bar, and alert content. Instead
     * of using setVisible, we have to remove the subtree of accessible content from each view element in order to
     * prevent an IE11 bug where content remains invisible in the accessibility tree, see
     * https://github.com/phetsims/john-travoltage/issues/247
     *
     * @param {boolean} visible
     */
    setAccessibleViewsVisible: function( visible ) {
      for ( var i = 0; i < this.sim.screens.length; i++ ) {
        this.sim.screens[ i ].view.accessibleContentDisplayed = visible;
      }
      this.sim.navigationBar.accessibleContentDisplayed = visible;

      // workaround for a strange Edge bug where this child of the navigation bar remains visible,
      // see https://github.com/phetsims/a11y-research/issues/30
      this.sim.navigationBar.keyboardHelpButton.accessibleVisible = visible;

      // clear the aria-live alert content from the DOM
      AriaHerald.clearAll();
    },

    /**
     * If there is an active element, focus it.  Should almost always be closed after the Dialog has been closed.
     *
     * @public
     * @a11y
     */
    focusActiveElement: function() {
      this.activeElement && this.activeElement.focus();
    }
  } );
} );<|endoftext|>


<commit_before>// site1.js

/**
*    Copyright (C) 2008 10gen Inc.
*
*    This program is free software: you can redistribute it and/or  modify
*    it under the terms of the GNU Affero General Public License, version 3,
*    as published by the Free Software Foundation.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU Affero General Public License for more details.
*
*    You should have received a copy of the GNU Affero General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

Cloud.Environment = function(){
    this.branch = null;
    this.name = this.branch;
    this.db = null;
    this.pool = null;
    this.giturl = null;
    this.iid = ObjectId();
    this.aliases = [];
};

Cloud.SiteDB = function(){
    this.name = null;
    this.server = null;
    this.did = ObjectId();
};

Cloud.Site = function( name ){
    this.name = name;
    this.created = new Date();

    this.environments = [];
    this.environments._dbCons = Cloud.Environment;

    this.dbs = [];
    this.dbs._dbCons = Cloud.SiteDB;
};

Cloud.Site.prototype.environmentNames = function(){
    return this.environments.map( function(z){ return z.name } );
}

Cloud.Site.prototype.dbNames = function(){
    return this.dbs.map( function(z){ return z.name } );
}

Cloud.Site.prototype.findEnvironmentByName = function( name ){
    if ( ! name )
        return null;

    var ret = null;
    var ali = null;
    this.environments.forEach( function(z){

        if ( z.name == name )
            ret = z;

        if ( z.aliases && z.aliases.contains( name ) )
            ali = z;
    } );

    return ret || ali;
};

Cloud.Site.prototype.findEnvironmentById = function( iid ){
    if ( ! iid )
        return null;

    if ( isString( iid ) )
        iid = ObjectId( iid );

    var ret = null;
    this.environments.forEach( function(z){
        if ( z.iid == iid )
            ret = z;
    } );
    return ret;
};

/**
this returns the 10gen server name (prod1)
*/
Cloud.Site.prototype.getDatabaseServerForEnvironmentName = function( name ){
    name = name || "www";

    var env = this.findEnvironmentByName( name );

    if ( ! env )
        throw "can't find environment [" + name + "] choices [" + this.environmentNames() + "] site:" + this.name;

    var db = this.findDBByName( env.db );
    if ( ! db )
        throw "something is wrong, can't find db [" + env.db + "] choices [" + this.dbNames() + "]";

    if ( ! db.server )
	throw "we found db [" + env.db + "] but its misconfigured";

    return db.server;
}

Cloud.Site.prototype.findDBByName = function( name ){
    if ( ! name )
        return null;

    var ret = null;
    this.dbs.forEach( function(z){
        if ( z.name == name )
            ret = z;
    } );
    return ret;
};

Cloud.Site.prototype.findDBById = function( did ){
    if ( ! did )
        return null;

    if ( isString( did ) )
        did = ObjectId( did );

    var ret = null;
    this.dbs.forEach( function(z){
        if ( z.did == did )
            ret = z;
    } );
    return ret;
};

Cloud.Site.prototype.getGitBranchNames = function( force ){

    if ( ! this.giturl || this.giturl.startsWith( "ssh://git.10gen.com/data/gitroot/" ) ){
        var g = db.git.findOne( { name : "sites/" + this.name } );
        if ( ! g ){
            g = new Cloud.Git.Repository();
            g.ensureHash( "master" , "0" );
            db.git.save( g );
        }
        return g.branches.keySet();
    }

    var base = javaCreate( "java.io.File" , "/data/tmp/externalgit/" );
    base.mkdirs();
    var root = javaCreate( "java.io.File" , base , this.name );

    if ( ! root.exists() ){
        var msg = "clone [" + this.giturl + "] to [" + root + "]";

        log.git.info( msg );
        if ( ! javaStatic( "ed.util.GitUtils" , "clone" , this.giturl , base , this.name ) ){
            log.git.error( "failed " + msg );
            throw "couldn't " + msg;
        }
        force = true;
    }

    var now = new Date();

    var ts = javaCreate( "java.io.File" , root , ".git/10gents" );
    if ( ! ts.exists() ){
        force = true;
        ts.createNewFile();
    }
    else {
        if ( ( ts.lastModified() + ( 1000 * 60 * 5 ) ) < now.getTime() )
            force = true;
    }

    if ( force ){
        log.git.info( " doing full update for [" + this.name + "]" );
        javaStatic( "ed.util.GitUtils" , "fullUpdate" , root );
        ts.setLastModified( now.getTime() );
    }

    return javaStatic( "ed.util.GitUtils" , "getAllBranchAndTagNames" , root );
};

Cloud.Site.prototype.toString = function(){
    return "Site: " + this.name;
};

Cloud.Site.forName = function( name , create ){
    var s = db.sites.findOne( { name : name } );

    if ( s || ! create )
	return s;

    s = new Cloud.Site( name );
    db.sites.apply( s );
    return s;
};

db.sites.setConstructor( Cloud.Site );
if ( me.real ){
    db.sites.ensureIndex( { name : 1 } );
}
<commit_msg>detect gitroot change and re-clone<commit_after>// site1.js

/**
*    Copyright (C) 2008 10gen Inc.
*
*    This program is free software: you can redistribute it and/or  modify
*    it under the terms of the GNU Affero General Public License, version 3,
*    as published by the Free Software Foundation.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU Affero General Public License for more details.
*
*    You should have received a copy of the GNU Affero General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

Cloud.Environment = function(){
    this.branch = null;
    this.name = this.branch;
    this.db = null;
    this.pool = null;
    this.giturl = null;
    this.iid = ObjectId();
    this.aliases = [];
};

Cloud.SiteDB = function(){
    this.name = null;
    this.server = null;
    this.did = ObjectId();
};

Cloud.Site = function( name ){
    this.name = name;
    this.created = new Date();

    this.environments = [];
    this.environments._dbCons = Cloud.Environment;

    this.dbs = [];
    this.dbs._dbCons = Cloud.SiteDB;
};

Cloud.Site.prototype.environmentNames = function(){
    return this.environments.map( function(z){ return z.name } );
}

Cloud.Site.prototype.dbNames = function(){
    return this.dbs.map( function(z){ return z.name } );
}

Cloud.Site.prototype.findEnvironmentByName = function( name ){
    if ( ! name )
        return null;

    var ret = null;
    var ali = null;
    this.environments.forEach( function(z){

        if ( z.name == name )
            ret = z;

        if ( z.aliases && z.aliases.contains( name ) )
            ali = z;
    } );

    return ret || ali;
};

Cloud.Site.prototype.findEnvironmentById = function( iid ){
    if ( ! iid )
        return null;

    if ( isString( iid ) )
        iid = ObjectId( iid );

    var ret = null;
    this.environments.forEach( function(z){
        if ( z.iid == iid )
            ret = z;
    } );
    return ret;
};

/**
this returns the 10gen server name (prod1)
*/
Cloud.Site.prototype.getDatabaseServerForEnvironmentName = function( name ){
    name = name || "www";

    var env = this.findEnvironmentByName( name );

    if ( ! env )
        throw "can't find environment [" + name + "] choices [" + this.environmentNames() + "] site:" + this.name;

    var db = this.findDBByName( env.db );
    if ( ! db )
        throw "something is wrong, can't find db [" + env.db + "] choices [" + this.dbNames() + "]";

    if ( ! db.server )
	throw "we found db [" + env.db + "] but its misconfigured";

    return db.server;
}

Cloud.Site.prototype.findDBByName = function( name ){
    if ( ! name )
        return null;

    var ret = null;
    this.dbs.forEach( function(z){
        if ( z.name == name )
            ret = z;
    } );
    return ret;
};

Cloud.Site.prototype.findDBById = function( did ){
    if ( ! did )
        return null;

    if ( isString( did ) )
        did = ObjectId( did );

    var ret = null;
    this.dbs.forEach( function(z){
        if ( z.did == did )
            ret = z;
    } );
    return ret;
};

Cloud.Site.prototype.getGitBranchNames = function( force ){

    if ( ! this.giturl || this.giturl.startsWith( "ssh://git.10gen.com/data/gitroot/" ) ){
        var g = db.git.findOne( { name : "sites/" + this.name } );
        if ( ! g ){
            g = new Cloud.Git.Repository();
            g.ensureHash( "master" , "0" );
            db.git.save( g );
        }
        return g.branches.keySet();
    }

    var base = javaCreate( "java.io.File" , "/data/tmp/externalgit/" );
    base.mkdirs();
    var root = javaCreate( "java.io.File" , base , this.name );

    if ( root.exists() ){
        var conf = javaStatic( "ed.util.GitUtils" , "readConfig" , root );
        if ( conf.remote.origin.url != this.giturl ){
            log.git.info( "giturl changed for site [" + this.name + "]  was [" + conf.remote.origin.url + "] now is [" + this.giturl + "]" );
            javaStatic( "ed.io.FileUtil" , "deleteDirectory" , root );
        }
    }

    if ( ! root.exists() ){
        var msg = "clone [" + this.giturl + "] to [" + root + "]";

        log.git.info( msg );
        if ( ! javaStatic( "ed.util.GitUtils" , "clone" , this.giturl , base , this.name ) ){
            log.git.error( "failed " + msg );
            throw "couldn't " + msg;
        }
        force = true;
    }

    var now = new Date();

    var ts = javaCreate( "java.io.File" , root , ".git/10gents" );
    if ( ! ts.exists() ){
        force = true;
        ts.createNewFile();
    }
    else {
        if ( ( ts.lastModified() + ( 1000 * 60 * 5 ) ) < now.getTime() )
            force = true;
    }

    if ( force ){
        log.git.info( " doing full update for [" + this.name + "]" );
        javaStatic( "ed.util.GitUtils" , "fullUpdate" , root );
        ts.setLastModified( now.getTime() );
    }

    return javaStatic( "ed.util.GitUtils" , "getAllBranchAndTagNames" , root );
};

Cloud.Site.prototype.toString = function(){
    return "Site: " + this.name;
};

Cloud.Site.forName = function( name , create ){
    var s = db.sites.findOne( { name : name } );

    if ( s || ! create )
	return s;

    s = new Cloud.Site( name );
    db.sites.apply( s );
    return s;
};

db.sites.setConstructor( Cloud.Site );
if ( me.real ){
    db.sites.ensureIndex( { name : 1 } );
}
<|endoftext|>


<commit_before>'use strict';

var patchSource = require('./source_replacer').patchSource;

function isLiteral(element) {
    return Object(element) !== element;
}

function performOnParallellTraverse(action) {
    var parallelTraverse = function parallellTraverse(actual, expected, actualLastFunctionScope, expectedLastFunctionScope) {
        var attr;

        if (isLiteral(actual)) {
            if (actual !== expected) {
                action(actualLastFunctionScope, expectedLastFunctionScope);
            }
            return;
        }

        if (actual.type === "BlockStatement") {
            actualLastFunctionScope = actual;
            expectedLastFunctionScope = expected;
        }

        if (Array.isArray(actual)) {
            if (actual.length !== expected.length) {
                action(actualLastFunctionScope, expectedLastFunctionScope);
            } else {
                actual.forEach(function (_, i) {
                    parallellTraverse(actual[i], expected[i], actualLastFunctionScope, expectedLastFunctionScope);
                });
                return;
            }
        }

        for (attr in actual) {
            if (attr !== 'type' && attr !== 'loc' && attr !== 'raw' && actual.hasOwnProperty(attr) && expected.hasOwnProperty(attr)) {
                if (expected && attr in expected) {
                    parallellTraverse(actual[attr], expected[attr], actualLastFunctionScope, expectedLastFunctionScope);
                } else {
                    action(actualLastFunctionScope, expectedLastFunctionScope);
                }
            }
        }
    };

    return parallelTraverse;
}

function equalizeTrees(patchedTree, sourceCode, createAst) {
    var treesAreDifferent = true,
        originalTree = createAst(sourceCode);

    function replaceOriginalSourceWithPatch(a, b) {
        var sourceToBePatched = b.loc.source,
            sourceCode = patchSource(a.loc, b.loc, sourceToBePatched),
            patchedAST = createAst(sourceCode);

        throw patchedAST;
    }

    while (treesAreDifferent) {
        try {
            performOnParallellTraverse(replaceOriginalSourceWithPatch)(patchedTree, originalTree, patchedTree, originalTree);
            treesAreDifferent = false;
        } catch (replacedTree) {
            originalTree = replacedTree;
        }
    }

    return originalTree.loc.source;
}

module.exports = {
    equalizeTrees: equalizeTrees
};
<commit_msg>Remove unreachable case when both trees do not have the same property<commit_after>'use strict';

var patchSource = require('./source_replacer').patchSource;

function isLiteral(element) {
    return Object(element) !== element;
}

function performOnParallellTraverse(action) {
    var parallelTraverse = function parallellTraverse(actual, expected, actualLastFunctionScope, expectedLastFunctionScope) {
        var attr;

        function shouldBeChecked(attr) {
            return attr !== 'type' && attr !== 'loc' && attr !== 'raw' && actual.hasOwnProperty(attr) && expected.hasOwnProperty(attr);
        }

        if (isLiteral(actual)) {
            if (actual !== expected) {
                action(actualLastFunctionScope, expectedLastFunctionScope);
            }
            return;
        }

        if (actual.type === "BlockStatement") {
            actualLastFunctionScope = actual;
            expectedLastFunctionScope = expected;
        }

        if (Array.isArray(actual)) {
            if (actual.length !== expected.length) {
                action(actualLastFunctionScope, expectedLastFunctionScope);
            } else {
                actual.forEach(function (_, i) {
                    parallellTraverse(actual[i], expected[i], actualLastFunctionScope, expectedLastFunctionScope);
                });
                return;
            }
        }

        for (attr in actual) {
            if (shouldBeChecked(attr)) {
                if (expected && attr in expected) {
                    parallellTraverse(actual[attr], expected[attr], actualLastFunctionScope, expectedLastFunctionScope);
                }
            }
        }
    };

    return parallelTraverse;
}

function equalizeTrees(patchedTree, sourceCode, createAst) {
    var treesAreDifferent = true,
        originalTree = createAst(sourceCode);

    function replaceOriginalSourceWithPatch(a, b) {
        var sourceToBePatched = b.loc.source,
            sourceCode = patchSource(a.loc, b.loc, sourceToBePatched),
            patchedAST = createAst(sourceCode);

        throw patchedAST;
    }

    while (treesAreDifferent) {
        try {
            performOnParallellTraverse(replaceOriginalSourceWithPatch)(patchedTree, originalTree, patchedTree, originalTree);
            treesAreDifferent = false;
        } catch (replacedTree) {
            originalTree = replacedTree;
        }
    }

    return originalTree.loc.source;
}

module.exports = {
    equalizeTrees: equalizeTrees
};
<|endoftext|>


<commit_before>import element from '../../lib/element';
import fixture from '../../lib/fixture';
import support from '../../../src/native/support';
import { ready, symbols, vdom } from '../../../src/index';

describe('vdom/elements', function () {
  it('slot', function () {
    const elem1 = element().skate({
      render () {
        vdom('slot', { name: 'test' });
      }
    })();
    const elem2 = element().skate({
      render () {
        vdom.slot({ name: 'test' });
      }
    })();

    function assertSlotElement () {
      expect(ch1.tagName).to.equal('SLOT', 'vdom');
      expect(ch1.getAttribute('name')).to.equal('test', 'vdom');
      expect(ch2.tagName).to.equal('SLOT', 'vdom(slot)');
      expect(ch2.getAttribute('name')).to.equal('test', 'vdom(slot)');
    }

    const ch1 = elem1[symbols.shadowRoot].firstElementChild;
    const ch2 = elem2[symbols.shadowRoot].firstElementChild;

    if (support.shadowDomV1) {
      assertSlotElement();
    } else if (support.shadowDomV0) {
      expect(ch1.tagName).to.equal('CONTENT', 'vdom');
      expect(ch1.getAttribute('select')).to.equal('[slot="test"]', 'vdom');
      expect(ch2.tagName).to.equal('CONTENT', 'vdom(slot)');
      expect(ch2.getAttribute('select')).to.equal('[slot="test"]', 'vdom(slot)');
    } else {
      assertSlotElement();
    }
  });

  it('passing a component constructor to the vdom() function', function (done) {
    const elem1 = element().skate({
      render () {
        vdom.text('rendered');
      }
    });
    const elem2 = element().skate({
      render () {
        vdom.div(function () {
          vdom(elem1);
        });
      }
    });

    const el2 = elem2();
    const el1 = el2[symbols.shadowRoot].firstChild.firstChild;

    fixture(el2);
    ready(el1, function () {
      expect(el1.textContent).to.equal('rendered');
      done();
    });
  });
});
<commit_msg>Ensure vdom test is working in all browsers. Use init() to ensure in non-custom-element browsers that it is initialised sync.<commit_after>import element from '../../lib/element';
import fixture from '../../lib/fixture';
import support from '../../../src/native/support';
import { init, symbols, vdom } from '../../../src/index';

describe('vdom/elements', function () {
  it('slot', function () {
    const elem1 = element().skate({
      render () {
        vdom('slot', { name: 'test' });
      }
    })();
    const elem2 = element().skate({
      render () {
        vdom.slot({ name: 'test' });
      }
    })();

    function assertSlotElement () {
      expect(ch1.tagName).to.equal('SLOT', 'vdom');
      expect(ch1.getAttribute('name')).to.equal('test', 'vdom');
      expect(ch2.tagName).to.equal('SLOT', 'vdom(slot)');
      expect(ch2.getAttribute('name')).to.equal('test', 'vdom(slot)');
    }

    const ch1 = elem1[symbols.shadowRoot].firstElementChild;
    const ch2 = elem2[symbols.shadowRoot].firstElementChild;

    if (support.shadowDomV1) {
      assertSlotElement();
    } else if (support.shadowDomV0) {
      expect(ch1.tagName).to.equal('CONTENT', 'vdom');
      expect(ch1.getAttribute('select')).to.equal('[slot="test"]', 'vdom');
      expect(ch2.tagName).to.equal('CONTENT', 'vdom(slot)');
      expect(ch2.getAttribute('select')).to.equal('[slot="test"]', 'vdom(slot)');
    } else {
      assertSlotElement();
    }
  });

  it('passing a component constructor to the vdom() function', function () {
    const elem1 = element().skate({
      render () {
        vdom.text('rendered');
      }
    });
    const elem2 = element().skate({
      render () {
        vdom.div(function () {
          vdom(elem1);
        });
      }
    });

    const el2 = elem2();
    const el1 = el2[symbols.shadowRoot].firstChild.firstChild;
    fixture(el2);
    init(el1);
    expect(el1[symbols.shadowRoot].textContent).to.equal('rendered');
  });
});
<|endoftext|>