<commit_before>'use strict';

delete require.cache[require.resolve('..')];
var DiagramRenderer = require('..');
var createRendererTester = require('../../../test_helper/create-renderer-tester');
var test = createRendererTester(DiagramRenderer);
var assert = require('../../../test_helper/empowered-assert');

describe('DiagramRenderer', function () {

    describe('Identifier', function () {
        test('boolean', function (transpiledCode) {
            var truthy = false;
            eval(transpiledCode);
        }, [
            'assert(truthy)',
            '       |      ',
            '       false  ',
        ]);

        test('empty string', function (transpiledCode) {
            var truthy = '';
            eval(transpiledCode);
        }, [
            'assert(truthy)',
            '       |      ',
            '       ""     ',
        ]);

        test('zero', function (transpiledCode) {
            var truthy = 0;
            eval(transpiledCode);
        }, [
            'assert(truthy)',
            '       |      ',
            '       0      ',
        ]);

        test('undefined', function (transpiledCode) {
            var truthy = undefined;
            eval(transpiledCode);
        }, [
            'assert(truthy)',
            '       |      ',
            '       undefined',
        ]);
    });

    describe('UnaryExpression', function () {
        test('with NumberLiteral', function (transpiledCode) {
            var num = 1;
            eval(transpiledCode);
        }, [
            'assert(-0)',
            '       |  ',
            '       0  '
        ]);

        test('with NumberLiteral and BinaryExpression', function (transpiledCode) {
            var num = 1;
            eval(transpiledCode);
        }, [
            'assert(4 === -4)',
            '         |   |  ',
            '         |   -4 ',
            '         false  '
        ]);

        test('with Identifier and BinaryExpression', function (transpiledCode) {
            var num = 1;
            eval(transpiledCode);
        }, [
            'assert(+num === -num)',
            '       ||   |   ||   ',
            '       ||   |   |1   ',
            '       ||   |   -1   ',
            '       |1   false    ',
            '       1             '
        ]);

        test('negation', function (transpiledCode) {
            var truth = true;
            eval(transpiledCode);
        }, [
            'assert(!truth)',
            '       ||     ',
            '       |true  ',
            '       false  '
        ]);

        test('double negation', function (transpiledCode) {
            var some = '';
            eval(transpiledCode);
        }, [
            'assert(!!some)',
            '       |||    ',
            '       ||""   ',
            '       |true  ',
            '       false  '
        ]);

        test('typeof operator', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert(typeof foo !== "undefined")',
            '       |          |               ',
            '       |          false           ',
            '       "undefined"                '
        ]);

        test('delete operator', function (transpiledCode) {
            var foo = {
                bar: {
                    baz: false
                }
            };
            eval(transpiledCode);
        }, [
            'assert(delete foo.bar === false)',
            '       |      |   |   |         ',
            '       |      |   |   false     ',
            '       |      |   Object{baz:false}',
            '       true   Object{bar:Object{baz:false}}',
        ]);
    });

    describe('MemberExpression', function () {
        test('computed: false', function (transpiledCode) {
            var en = { foo: false };
            eval(transpiledCode);
        }, [
            'assert(en.foo)',
            '       |  |   ',
            '       |  false',
            '       Object{foo:false}'
        ]);

        test('computed: false', function (transpiledCode) {
            var propName = 'foo';
            var en = { foo: false };
            eval(transpiledCode);
        }, [
            'assert(en[propName])',
            '       | ||         ',
            '       | |"foo"     ',
            '       | false      ',
            '       Object{foo:false}'
        ]);

        test('chained member', function (transpiledCode) {
            var en = { foo: { bar: false } };
            eval(transpiledCode);
        }, [
            'assert(en.foo.bar)',
            '       |  |   |   ',
            '       |  |   false',
            '       |  Object{bar:false}',
            '       Object{foo:Object{bar:false}}'
        ]);

        test('undefined property', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert({}.hoge === "xxx")',
            '       |  |    |         ',
            '       |  |    false     ',
            '       |  undefined      ',
            '       Object{}          '
        ]);
    });

    describe('CallExpression', function () {
        test('arguments', function (transpiledCode) {
            var name = 'bar';
            var age = 23;
            var foo = function (n, a) { return false; };
            eval(transpiledCode);
        }, [
            'assert(foo(name, age))',
            '       |   |     |    ',
            '       |   "bar" 23   ',
            '       false          '
        ]);

        test('deep CallExpression', function (transpiledCode) {
            var bar = function () { return 'baz'; };
            var en = { foo: function (n) { return false; } };
            eval(transpiledCode);
        }, [
            'assert(en.foo(bar()))',
            '       |  |   |      ',
            '       |  |   "baz"  ',
            '       |  false      ',
            '       Object{foo:#function#}'
        ]);
    });

    describe('BinaryExpression', function () {
        test('of BinaryExpression', function (transpiledCode) {
            var foo = 'foo';
            var bar = 'bar';
            eval(transpiledCode);
        }, [
            'assert(foo === bar === (foo === bar) === (foo === bar))',
            '       |   |   |   |    |   |   |    |    |   |   |    ',
            '       |   |   |   |    |   |   |    |    |   |   "bar"',
            '       |   |   |   |    |   |   |    |    |   false    ',
            '       |   |   |   |    |   |   |    |    "foo"        ',
            '       |   |   |   |    |   |   |    false             ',
            '       |   |   |   |    |   |   "bar"                  ',
            '       |   |   |   |    |   false                      ',
            '       |   |   |   true "foo"                          ',
            '       |   |   "bar"                                   ',
            '       |   false                                       ',
            '       "foo"                                           '
        ]);

        test('of Identifier', function (transpiledCode) {
            var foo = 'foo';
            var bar = 'bar';
            eval(transpiledCode);
        }, [
            'assert(foo === bar)',
            '       |   |   |   ',
            '       |   |   "bar"',
            '       |   false   ',
            '       "foo"       ',
        ]);

        test('of Identifier and StringLiteral', function (transpiledCode) {
            var foo = 'foo';
            eval(transpiledCode);
        }, [
            'assert(foo === "bar")',
            '       |   |         ',
            '       |   false     ',
            '       "foo"         ',
        ]);

        test('of StringLiteral', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert("foo" === "bar")',
            '             |         ',
            '             false     '
        ]);

        test('of NumberLiteral', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert(4 !== 4)',
            '         |     ',
            '         false '
        ]);

        test('of MemberExpression', function (transpiledCode) {
            var en = { foo: 'bar', toto: 'tata' };
            var fr = { toto: 'tata'};
            eval(transpiledCode);
        }, [
            'assert(en.foo === fr.toto)',
            '       |  |   |   |  |    ',
            '       |  |   |   |  "tata"',
            '       |  |   |   Object{toto:"tata"}',
            '       |  |   false       ',
            '       |  "bar"           ',
            '       Object{foo:"bar",toto:"tata"}'
        ]);

        test('of CallExpression', function (transpiledCode) {
            var en = { foo: function() { return 'bar';} };
            var fr = { toto: function() { return 'tata'; } };
            eval(transpiledCode);
        }, [
            'assert(en.foo() === fr.toto())',
            '       |  |     |   |  |      ',
            '       |  |     |   |  "tata" ',
            '       |  |     |   Object{toto:#function#}',
            '       |  "bar" false         ',
            '       Object{foo:#function#} '
        ]);

        test('non-Punctuator BinaryExpression operator', function (transpiledCode) {
            function Person (name) { this.name = name; };
            var foo = 'bob';
            eval(transpiledCode);
        }, [
            'assert(foo instanceof Person)',
            '       |   |          |      ',
            '       |   false      #function#',
            '       "bob"                 '
        ]);

        test('Loose equality', function (transpiledCode) {
            var truthy = '1';
            var falsy = false;
            eval(transpiledCode);
        }, [
            'assert(truthy == falsy)',
            '       |      |  |     ',
            '       |      |  false ',
            '       "1"    false    '
        ]);

        test('of NaN', function (transpiledCode) {
            var nan1 = NaN;
            var nan2 = NaN;
            eval(transpiledCode);
        }, [
            'assert(nan1 === nan2)',
            '       |    |   |    ',
            '       |    |   NaN  ',
            '       NaN  false    '
        ]);

        test('of Infinity', function (transpiledCode) {
            var positiveInfinity = Infinity;
            var negativeInfinity = -Infinity;
            eval(transpiledCode);
        }, [
            'assert(positiveInfinity === negativeInfinity)',
            '       |                |   |                ',
            '       |                |   -Infinity        ',
            '       Infinity         false                '
        ]);
    });

    describe('LogicalExpression', function () {
        test('of Identifiers', function (transpiledCode) {
            var x = false;
            var y = 0;
            var z = null;
            eval(transpiledCode);
        }, [
            'assert(x || y || z)',
            '       | |  | |  | ',
            '       | |  | |  null',
            '       | 0  0 null ',
            '       false       '
        ]);

        test('of Identifier evaluation order', function (transpiledCode) {
            var x = 'yeah';
            var y = 0;
            var z = true;
            eval(transpiledCode);
        }, [
            'assert(x && y && z)',
            '       | |  | |    ',
            '       | 0  0 0    ',
            '       "yeah"      '
        ]);

        test('of CallExpression and MemberExpression', function (transpiledCode) {
            var x = { foo: function(n) { return false; } };
            var y = function(n) { return null; };
            var z = { val: 0 };
            eval(transpiledCode);
        }, [
            'assert(x.foo() || y() || z.val)',
            '       | |     |  |   |  | |   ',
            '       | |     |  |   |  | 0   ',
            '       | |     |  |   0  Object{val:0}',
            '       | |     |  null         ',
            '       | false null            ',
            '       Object{foo:#function#}  '
        ]);
    });

    describe('ConditionalExpression', function () {
        test('of Identifiers, consequent', function (transpiledCode) {
            var foo = false;
            var bar = null;
            var baz = 0;
            eval(transpiledCode);
        }, [
            'assert(foo ? bar : baz)',
            '       |           |   ',
            '       false       0   '
        ]);
        test('of Identifiers, alternate', function (transpiledCode) {
            var foo = true;
            var bar = null;
            var baz = 0;
            eval(transpiledCode);
        }, [
            'assert(foo ? bar : baz)',
            '       |     |         ',
            '       true  null      '
        ]);
        test('of another ConditionalExpression', function (transpiledCode) {
            var falsy = null;
            var truthy = 'truth';
            var anotherFalsy = 0;
            eval(transpiledCode);
        }, [
            'assert(falsy ? truthy : truthy ? anotherFalsy : truthy)',
            '       |                |        |                     ',
            '       null             "truth"  0                     '
        ]);
    });

    describe('ObjectExpression', function () {
        test('of Literals', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert.deepEqual({ foo: 0 }, { foo: 1 })',
            '                 |           |          ',
            '                 |           Object{foo:1}',
            '                 Object{foo:0}          '
        ]);
        test('of Identifiers', function (transpiledCode) {
            var bar = 'BAR';
            var fuga = 'FUGA';
            eval(transpiledCode);
        }, [
            'assert.deepEqual({ foo: bar }, { hoge: fuga })',
            '                 |      |      |       |      ',
            '                 |      |      |       "FUGA" ',
            '                 |      "BAR"  Object{hoge:"FUGA"}',
            '                 Object{foo:"BAR"}            '
        ]);
        test('enhanced object literals', function (transpiledCode) {
            var name = 'bobby';
            eval(transpiledCode);
        }, [
            'assert.deepEqual({ name, [`greet from ${ name }`]: `Hello, I am ${ name }` }, null)',
            '                 |        |              |         |               |               ',
            '                 |        |              |         |               "bobby"         ',
            '                 |        |              "bobby"   "Hello, I am bobby"             ',
            '                 |        "greet from bobby"                                       ',
            '                 Object{name:"bobby","greet from bobby":"Hello, I am bobby"}       '
        ]);
    });

    test('ArrayExpression as an argument of CallExpression', function (transpiledCode) {
        var pop = function (ary) { return ary.pop(); };
        var zero = 0;
        var one = 1;
        var two = 2;
        eval(transpiledCode);
    }, [
        'assert(pop([zero, one, two]) === one)',
        '       |   ||     |    |     |   |   ',
        '       |   ||     |    |     |   1   ',
        '       |   |0     1    2     false   ',
        '       2   [0,1]                     '
    ]);

    describe('ObjectRestSpread', function () {
        test('Spread Properties', function (transpiledCode) {
            var a = 'a';
            var b = 'b';
            var obj = { foo: 'FOO', bar: 'BAR' };
            eval(transpiledCode);
        }, [
            'assert.deepEqual({ b, ...obj }, { a, ...obj })',
            '                 |              |             ',
            '                 |              Object{a:"a",foo:"FOO",bar:"BAR"}',
            '                 Object{b:"b",foo:"FOO",bar:"BAR"}'
        ]);
    });

    describe('Function Bind Syntax', function () {
        test('avajs/ava#881', function (transpiledCode) {
            function validate(name) {
                return {
                    name: name,
                    valid: true,
                    value: this
                };
            }
            eval(transpiledCode);
        }, [
            'assert.deepEqual(true::validate("foo"), { valid: true, value: true, name: "bar" })',
            '                 |                      |                                         ',
            '                 |                      Object{valid:true,value:true,name:"bar"}  ',
            '                 Object{name:"foo",valid:true,value:true}                         '
        ]);
    });

    describe('SequenceExpression i.e., comma operator', function () {
        test('power-assert-js/power-assert#59', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert((-0, -1) + 1 === -0 + -1)',
            '        |   |   |   |   |  | |  ',
            '        |   |   |   |   |  | -1 ',
            '        |   |   |   |   0  -1   ',
            '        0   -1  0   false       '
        ]);
    });
});
<commit_msg>test(power-assert-renderer-diagram): fix failing test due to the changes in babel output<commit_after>'use strict';

delete require.cache[require.resolve('..')];
var DiagramRenderer = require('..');
var createRendererTester = require('../../../test_helper/create-renderer-tester');
var test = createRendererTester(DiagramRenderer);
var assert = require('../../../test_helper/empowered-assert');

describe('DiagramRenderer', function () {

    describe('Identifier', function () {
        test('boolean', function (transpiledCode) {
            var truthy = false;
            eval(transpiledCode);
        }, [
            'assert(truthy)',
            '       |      ',
            '       false  ',
        ]);

        test('empty string', function (transpiledCode) {
            var truthy = '';
            eval(transpiledCode);
        }, [
            'assert(truthy)',
            '       |      ',
            '       ""     ',
        ]);

        test('zero', function (transpiledCode) {
            var truthy = 0;
            eval(transpiledCode);
        }, [
            'assert(truthy)',
            '       |      ',
            '       0      ',
        ]);

        test('undefined', function (transpiledCode) {
            var truthy = undefined;
            eval(transpiledCode);
        }, [
            'assert(truthy)',
            '       |      ',
            '       undefined',
        ]);
    });

    describe('UnaryExpression', function () {
        test('with NumberLiteral', function (transpiledCode) {
            var num = 1;
            eval(transpiledCode);
        }, [
            'assert(-0)',
            '       |  ',
            '       0  '
        ]);

        test('with NumberLiteral and BinaryExpression', function (transpiledCode) {
            var num = 1;
            eval(transpiledCode);
        }, [
            'assert(4 === -4)',
            '         |   |  ',
            '         |   -4 ',
            '         false  '
        ]);

        test('with Identifier and BinaryExpression', function (transpiledCode) {
            var num = 1;
            eval(transpiledCode);
        }, [
            'assert(+num === -num)',
            '       ||   |   ||   ',
            '       ||   |   |1   ',
            '       ||   |   -1   ',
            '       |1   false    ',
            '       1             '
        ]);

        test('negation', function (transpiledCode) {
            var truth = true;
            eval(transpiledCode);
        }, [
            'assert(!truth)',
            '       ||     ',
            '       |true  ',
            '       false  '
        ]);

        test('double negation', function (transpiledCode) {
            var some = '';
            eval(transpiledCode);
        }, [
            'assert(!!some)',
            '       |||    ',
            '       ||""   ',
            '       |true  ',
            '       false  '
        ]);

        test('typeof operator', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert(typeof foo !== "undefined")',
            '       |          |               ',
            '       |          false           ',
            '       "undefined"                '
        ]);

        test('delete operator', function (transpiledCode) {
            var foo = {
                bar: {
                    baz: false
                }
            };
            eval(transpiledCode);
        }, [
            'assert(delete foo.bar === false)',
            '       |      |   |   |         ',
            '       |      |   |   false     ',
            '       |      |   Object{baz:false}',
            '       true   Object{bar:Object{baz:false}}',
        ]);
    });

    describe('MemberExpression', function () {
        test('computed: false', function (transpiledCode) {
            var en = { foo: false };
            eval(transpiledCode);
        }, [
            'assert(en.foo)',
            '       |  |   ',
            '       |  false',
            '       Object{foo:false}'
        ]);

        test('computed: false', function (transpiledCode) {
            var propName = 'foo';
            var en = { foo: false };
            eval(transpiledCode);
        }, [
            'assert(en[propName])',
            '       | ||         ',
            '       | |"foo"     ',
            '       | false      ',
            '       Object{foo:false}'
        ]);

        test('chained member', function (transpiledCode) {
            var en = { foo: { bar: false } };
            eval(transpiledCode);
        }, [
            'assert(en.foo.bar)',
            '       |  |   |   ',
            '       |  |   false',
            '       |  Object{bar:false}',
            '       Object{foo:Object{bar:false}}'
        ]);

        test('undefined property', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert({}.hoge === "xxx")',
            '       |  |    |         ',
            '       |  |    false     ',
            '       |  undefined      ',
            '       Object{}          '
        ]);
    });

    describe('CallExpression', function () {
        test('arguments', function (transpiledCode) {
            var name = 'bar';
            var age = 23;
            var foo = function (n, a) { return false; };
            eval(transpiledCode);
        }, [
            'assert(foo(name, age))',
            '       |   |     |    ',
            '       |   "bar" 23   ',
            '       false          '
        ]);

        test('deep CallExpression', function (transpiledCode) {
            var bar = function () { return 'baz'; };
            var en = { foo: function (n) { return false; } };
            eval(transpiledCode);
        }, [
            'assert(en.foo(bar()))',
            '       |  |   |      ',
            '       |  |   "baz"  ',
            '       |  false      ',
            '       Object{foo:#function#}'
        ]);
    });

    describe('BinaryExpression', function () {
        test('of BinaryExpression', function (transpiledCode) {
            var foo = 'foo';
            var bar = 'bar';
            eval(transpiledCode);
        }, [
            'assert(foo === bar === (foo === bar) === (foo === bar))',
            '       |   |   |   |    |   |   |    |    |   |   |    ',
            '       |   |   |   |    |   |   |    |    |   |   "bar"',
            '       |   |   |   |    |   |   |    |    |   false    ',
            '       |   |   |   |    |   |   |    |    "foo"        ',
            '       |   |   |   |    |   |   |    false             ',
            '       |   |   |   |    |   |   "bar"                  ',
            '       |   |   |   |    |   false                      ',
            '       |   |   |   true "foo"                          ',
            '       |   |   "bar"                                   ',
            '       |   false                                       ',
            '       "foo"                                           '
        ]);

        test('of Identifier', function (transpiledCode) {
            var foo = 'foo';
            var bar = 'bar';
            eval(transpiledCode);
        }, [
            'assert(foo === bar)',
            '       |   |   |   ',
            '       |   |   "bar"',
            '       |   false   ',
            '       "foo"       ',
        ]);

        test('of Identifier and StringLiteral', function (transpiledCode) {
            var foo = 'foo';
            eval(transpiledCode);
        }, [
            'assert(foo === "bar")',
            '       |   |         ',
            '       |   false     ',
            '       "foo"         ',
        ]);

        test('of StringLiteral', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert("foo" === "bar")',
            '             |         ',
            '             false     '
        ]);

        test('of NumberLiteral', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert(4 !== 4)',
            '         |     ',
            '         false '
        ]);

        test('of MemberExpression', function (transpiledCode) {
            var en = { foo: 'bar', toto: 'tata' };
            var fr = { toto: 'tata'};
            eval(transpiledCode);
        }, [
            'assert(en.foo === fr.toto)',
            '       |  |   |   |  |    ',
            '       |  |   |   |  "tata"',
            '       |  |   |   Object{toto:"tata"}',
            '       |  |   false       ',
            '       |  "bar"           ',
            '       Object{foo:"bar",toto:"tata"}'
        ]);

        test('of CallExpression', function (transpiledCode) {
            var en = { foo: function() { return 'bar';} };
            var fr = { toto: function() { return 'tata'; } };
            eval(transpiledCode);
        }, [
            'assert(en.foo() === fr.toto())',
            '       |  |     |   |  |      ',
            '       |  |     |   |  "tata" ',
            '       |  |     |   Object{toto:#function#}',
            '       |  "bar" false         ',
            '       Object{foo:#function#} '
        ]);

        test('non-Punctuator BinaryExpression operator', function (transpiledCode) {
            function Person (name) { this.name = name; };
            var foo = 'bob';
            eval(transpiledCode);
        }, [
            'assert(foo instanceof Person)',
            '       |   |          |      ',
            '       |   false      #function#',
            '       "bob"                 '
        ]);

        test('Loose equality', function (transpiledCode) {
            var truthy = '1';
            var falsy = false;
            eval(transpiledCode);
        }, [
            'assert(truthy == falsy)',
            '       |      |  |     ',
            '       |      |  false ',
            '       "1"    false    '
        ]);

        test('of NaN', function (transpiledCode) {
            var nan1 = NaN;
            var nan2 = NaN;
            eval(transpiledCode);
        }, [
            'assert(nan1 === nan2)',
            '       |    |   |    ',
            '       |    |   NaN  ',
            '       NaN  false    '
        ]);

        test('of Infinity', function (transpiledCode) {
            var positiveInfinity = Infinity;
            var negativeInfinity = -Infinity;
            eval(transpiledCode);
        }, [
            'assert(positiveInfinity === negativeInfinity)',
            '       |                |   |                ',
            '       |                |   -Infinity        ',
            '       Infinity         false                '
        ]);
    });

    describe('LogicalExpression', function () {
        test('of Identifiers', function (transpiledCode) {
            var x = false;
            var y = 0;
            var z = null;
            eval(transpiledCode);
        }, [
            'assert(x || y || z)',
            '       | |  | |  | ',
            '       | |  | |  null',
            '       | 0  0 null ',
            '       false       '
        ]);

        test('of Identifier evaluation order', function (transpiledCode) {
            var x = 'yeah';
            var y = 0;
            var z = true;
            eval(transpiledCode);
        }, [
            'assert(x && y && z)',
            '       | |  | |    ',
            '       | 0  0 0    ',
            '       "yeah"      '
        ]);

        test('of CallExpression and MemberExpression', function (transpiledCode) {
            var x = { foo: function(n) { return false; } };
            var y = function(n) { return null; };
            var z = { val: 0 };
            eval(transpiledCode);
        }, [
            'assert(x.foo() || y() || z.val)',
            '       | |     |  |   |  | |   ',
            '       | |     |  |   |  | 0   ',
            '       | |     |  |   0  Object{val:0}',
            '       | |     |  null         ',
            '       | false null            ',
            '       Object{foo:#function#}  '
        ]);
    });

    describe('ConditionalExpression', function () {
        test('of Identifiers, consequent', function (transpiledCode) {
            var foo = false;
            var bar = null;
            var baz = 0;
            eval(transpiledCode);
        }, [
            'assert(foo ? bar : baz)',
            '       |           |   ',
            '       false       0   '
        ]);
        test('of Identifiers, alternate', function (transpiledCode) {
            var foo = true;
            var bar = null;
            var baz = 0;
            eval(transpiledCode);
        }, [
            'assert(foo ? bar : baz)',
            '       |     |         ',
            '       true  null      '
        ]);
        test('of another ConditionalExpression', function (transpiledCode) {
            var falsy = null;
            var truthy = 'truth';
            var anotherFalsy = 0;
            eval(transpiledCode);
        }, [
            'assert(falsy ? truthy : truthy ? anotherFalsy : truthy)',
            '       |                |        |                     ',
            '       null             "truth"  0                     '
        ]);
    });

    describe('ObjectExpression', function () {
        test('of Literals', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert.deepEqual({ foo: 0 }, { foo: 1 })',
            '                 |           |          ',
            '                 |           Object{foo:1}',
            '                 Object{foo:0}          '
        ]);
        test('of Identifiers', function (transpiledCode) {
            var bar = 'BAR';
            var fuga = 'FUGA';
            eval(transpiledCode);
        }, [
            'assert.deepEqual({ foo: bar }, { hoge: fuga })',
            '                 |      |      |       |      ',
            '                 |      |      |       "FUGA" ',
            '                 |      "BAR"  Object{hoge:"FUGA"}',
            '                 Object{foo:"BAR"}            '
        ]);
        test('enhanced object literals', function (transpiledCode) {
            var name = 'bobby';
            eval(transpiledCode);
        }, [
            'assert.deepEqual({ name, [`greet from ${name}`]: `Hello, I am ${name}` }, null)',
            '                 |        |             |        |              |              ',
            '                 |        |             |        |              "bobby"        ',
            '                 |        |             "bobby"  "Hello, I am bobby"           ',
            '                 |        "greet from bobby"                                   ',
            '                 Object{name:"bobby","greet from bobby":"Hello, I am bobby"}   '
        ]);
    });

    test('ArrayExpression as an argument of CallExpression', function (transpiledCode) {
        var pop = function (ary) { return ary.pop(); };
        var zero = 0;
        var one = 1;
        var two = 2;
        eval(transpiledCode);
    }, [
        'assert(pop([zero, one, two]) === one)',
        '       |   ||     |    |     |   |   ',
        '       |   ||     |    |     |   1   ',
        '       |   |0     1    2     false   ',
        '       2   [0,1]                     '
    ]);

    describe('ObjectRestSpread', function () {
        test('Spread Properties', function (transpiledCode) {
            var a = 'a';
            var b = 'b';
            var obj = { foo: 'FOO', bar: 'BAR' };
            eval(transpiledCode);
        }, [
            'assert.deepEqual({ b, ...obj }, { a, ...obj })',
            '                 |              |             ',
            '                 |              Object{a:"a",foo:"FOO",bar:"BAR"}',
            '                 Object{b:"b",foo:"FOO",bar:"BAR"}'
        ]);
    });

    describe('Function Bind Syntax', function () {
        test('avajs/ava#881', function (transpiledCode) {
            function validate(name) {
                return {
                    name: name,
                    valid: true,
                    value: this
                };
            }
            eval(transpiledCode);
        }, [
            'assert.deepEqual(true::validate("foo"), { valid: true, value: true, name: "bar" })',
            '                 |                      |                                         ',
            '                 |                      Object{valid:true,value:true,name:"bar"}  ',
            '                 Object{name:"foo",valid:true,value:true}                         '
        ]);
    });

    describe('SequenceExpression i.e., comma operator', function () {
        test('power-assert-js/power-assert#59', function (transpiledCode) {
            eval(transpiledCode);
        }, [
            'assert((-0, -1) + 1 === -0 + -1)',
            '        |   |   |   |   |  | |  ',
            '        |   |   |   |   |  | -1 ',
            '        |   |   |   |   0  -1   ',
            '        0   -1  0   false       '
        ]);
    });
});
<|endoftext|>


<commit_before>var webpackConfig = require('./webpack.config.js');

module.exports = function (config) {
  config.set({
    browsers: ['Firefox'],
    singleRun: true,
    frameworks: ['mocha'],
    files: [
      'node_modules/jquery/dist/jquery.min.js',
      'node_modules/foundation-sites/dist/js/foundation.min.js',
      'app/tests/**/*.test.jsx'
    ],
    preprocessors: {
      'app/tests/**/*.test.jsx': ['webpack', 'sourcemap'],
      'app/**/*.jsx': ['webpack', 'sourcemap']
    },
    reporters: ['mocha'],
    client: {
      mocha: {
        timeout: '5000'
      }
    },
    webpack: webpackConfig,
    webpackServer: {
      noInfo: true
    }
  });
};
<commit_msg>Raised mocha timeout for travis ci<commit_after>var webpackConfig = require('./webpack.config.js');

module.exports = function (config) {
  config.set({
    browsers: ['Firefox'],
    singleRun: true,
    frameworks: ['mocha'],
    files: [
      'node_modules/jquery/dist/jquery.min.js',
      'node_modules/foundation-sites/dist/js/foundation.min.js',
      'app/tests/**/*.test.jsx'
    ],
    preprocessors: {
      'app/tests/**/*.test.jsx': ['webpack', 'sourcemap'],
      'app/**/*.jsx': ['webpack', 'sourcemap']
    },
    reporters: ['mocha'],
    client: {
      mocha: {
        timeout: '10000'
      }
    },
    webpack: webpackConfig,
    webpackServer: {
      noInfo: true
    }
  });
};
<|endoftext|>


<commit_before>//
// Message
//

'use strict';

var mongoose = require('mongoose'),
    ObjectId = mongoose.Schema.Types.ObjectId;

var MessageSchema = new mongoose.Schema({
    room: {
        type: ObjectId,
        ref: 'Room',
        required: true
    },
    owner: {
        type: ObjectId,
        ref: 'User',
        required: true
    },
    text: {
        type: String,
        required: true,
        trim: true
    },
    posted: {
        type: Date,
        default: Date.now,
        index: true
    }
});

// EXPOSE ONLY CERTAIN FIELDS
// This helps ensure that the client gets
// data that can be digested properly
MessageSchema.method('toJSON', function() {
    return {
        id: this._id,
        room: this.room,
        owner: this.owner,
        text: this.text,
        posted: this.posted
    };
});

module.exports = mongoose.model('Message', MessageSchema);
<commit_msg>Added compound index to messages collection<commit_after>//
// Message
//

'use strict';

var mongoose = require('mongoose'),
    ObjectId = mongoose.Schema.Types.ObjectId;

var MessageSchema = new mongoose.Schema({
    room: {
        type: ObjectId,
        ref: 'Room',
        required: true
    },
    owner: {
        type: ObjectId,
        ref: 'User',
        required: true
    },
    text: {
        type: String,
        required: true,
        trim: true
    },
    posted: {
        type: Date,
        default: Date.now,
        index: true
    }
});

MessageSchema.index({ room: 1, posted: -1, _id: 1 });

// EXPOSE ONLY CERTAIN FIELDS
// This helps ensure that the client gets
// data that can be digested properly
MessageSchema.method('toJSON', function() {
    return {
        id: this._id,
        room: this.room,
        owner: this.owner,
        text: this.text,
        posted: this.posted
    };
});

module.exports = mongoose.model('Message', MessageSchema);
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react';
import 'rc-progress/assets/index.css';
import { Line as LineProgress } from 'rc-progress';

class Score extends Component {

  state = {
    meterWidth: 0,
  };

  optimum = 400;

  render() {
    const styleInducedMeterFillOffset = 3;
    const scorePercent = scoreToPercent(this.props.score - styleInducedMeterFillOffset, this.optimum);
    console.log("Score#render state.score", this.props.score, 'in percent', scorePercent);
    return (

        <LineProgress percent={scorePercent}
                      strokeWidth="1" strokeColor="#00FF00"
                      trailWidth="1" />
        Nachhaltigkeitslevel {scorePercent}%

    );
  }

  updateMeterWidth() {
    this.setState({meterWidth: window.innerWidth});
    console.log("updateMeterWidth", window.innerWidth, window.innerWidth);
  }

  componentWillMount() {
    this.updateMeterWidth();
    window.addEventListener('resize', this.updateMeterWidth.bind(this));
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.updateMeterWidth);
  }

}

function scoreToPercent(score, optimum) {
  return score / optimum * 100;
}

export default Score;
<commit_msg>Round display of sustainability level/score<commit_after>import React, {Component, PropTypes} from 'react';
import 'rc-progress/assets/index.css';
import { Line as LineProgress } from 'rc-progress';

class Score extends Component {

  state = {
    meterWidth: 0,
  };

  optimum = 400;

  render() {
    const styleInducedMeterFillOffset = 3;
    const scorePercent = scoreToPercent(this.props.score - styleInducedMeterFillOffset, this.optimum);
    console.log("Score#render state.score", this.props.score, 'in percent', scorePercent);
    return (

        <LineProgress percent={scorePercent}
                      strokeWidth="1" strokeColor="#00FF00"
                      trailWidth="1" />
        Nachhaltigkeitslevel {Math.round(scorePercent)}%

    );
  }

  updateMeterWidth() {
    this.setState({meterWidth: window.innerWidth});
    console.log("updateMeterWidth", window.innerWidth, window.innerWidth);
  }

  componentWillMount() {
    this.updateMeterWidth();
    window.addEventListener('resize', this.updateMeterWidth.bind(this));
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.updateMeterWidth);
  }

}

function scoreToPercent(score, optimum) {
  return score / optimum * 100;
}

export default Score;
<|endoftext|>


<commit_before>module.exports = {
  rules: {
    // enforce spacing inside array brackets
    'array-bracket-spacing': [2, 'never'],

    // enforce spacing inside single-line blocks
    // http://eslint.org/docs/rules/block-spacing
    'block-spacing': [2, 'always'],

    // enforce one true brace style
    'brace-style': [2, '1tbs', { allowSingleLine: true }],

    // require camel case names
    camelcase: [2, { properties: 'never' }],

    // enforce spacing before and after comma
    'comma-spacing': [2, { before: false, after: true }],

    // enforce one true comma style
    'comma-style': [2, 'last'],

    // disallow padding inside computed properties
    'computed-property-spacing': [2, 'never'],

    // enforces consistent naming when capturing the current execution context
    'consistent-this': 0,

    // enforce newline at the end of file, with no multiple empty lines
    'eol-last': 2,

    // require function expressions to have a name
    'func-names': 1,

    // enforces use of function declarations or expressions
    'func-style': 0,

    // Blacklist certain identifiers to prevent them being used
    // http://eslint.org/docs/rules/id-blacklist
    'id-blacklist': 0,

    // this option enforces minimum and maximum identifier lengths
    // (variable names, property names etc.)
    'id-length': 0,

    // require identifiers to match the provided regular expression
    'id-match': 0,

    // this option sets a specific tab width for your code
    // http://eslint.org/docs/rules/indent
    indent: [2, 2, { SwitchCase: 1, VariableDeclarator: 1 }],

    // specify whether double or single quotes should be used in JSX attributes
    // http://eslint.org/docs/rules/jsx-quotes
    'jsx-quotes': 0,

    // enforces spacing between keys and values in object literal properties
    'key-spacing': [2, { beforeColon: false, afterColon: true }],

    // require a space before & after certain keywords
    'keyword-spacing': [2, {
      before: true,
      after: true,
      overrides: {
        return: { after: true },
        throw: { after: true },
        case: { after: true }
      }
    }],

    // disallow mixed 'LF' and 'CRLF' as linebreaks
    'linebreak-style': 0,

    // enforces empty lines around comments
    'lines-around-comment': 0,

    // specify the maximum depth that blocks can be nested
    'max-depth': [0, 4],

    // specify the maximum length of a line in your program
    // http://eslint.org/docs/rules/max-len
    'max-len': [2, 100, 2, {
      ignoreUrls: true,
      ignoreComments: false
    }],

    // specify the max number of lines in a file
    // http://eslint.org/docs/rules/max-lines
    'max-lines': [0, {
      max: 300,
      skipBlankLines: true,
      skipComments: true
    }],

    // specify the maximum depth callbacks can be nested
    'max-nested-callbacks': 0,

    // limits the number of parameters that can be used in the function declaration.
    'max-params': [0, 3],

    // specify the maximum number of statement allowed in a function
    'max-statements': [0, 10],

    // restrict the number of statements per line
    // http://eslint.org/docs/rules/max-statements-per-line
    'max-statements-per-line': [0, { max: 1 }],

    // require a capital letter for constructors
    'new-cap': [2, { newIsCap: true }],

    // disallow the omission of parentheses when invoking a constructor with no arguments
    'new-parens': 0,

    // allow/disallow an empty newline after var statement
    'newline-after-var': 0,

    // http://eslint.org/docs/rules/newline-before-return
    'newline-before-return': 0,

    // enforces new line after each method call in the chain to make it
    // more readable and easy to maintain
    // http://eslint.org/docs/rules/newline-per-chained-call
    'newline-per-chained-call': [2, { ignoreChainWithDepth: 3 }],

    // disallow use of the Array constructor
    'no-array-constructor': 2,

    // disallow use of bitwise operators
    'no-bitwise': 0,

    // disallow use of the continue statement
    'no-continue': 0,

    // disallow comments inline after code
    'no-inline-comments': 0,

    // disallow if as the only statement in an else block
    'no-lonely-if': 0,

    // disallow un-paren'd mixes of different operators
    // http://eslint.org/docs/rules/no-mixed-operators
    'no-mixed-operators': [2, {
      groups: [
        ['+', '-', '*', '/', '%', '**'],
        ['&', '|', '^', '~', '<<', '>>', '>>>'],
        ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
        ['&&', '||'],
        ['in', 'instanceof']
      ],
      allowSamePrecedence: false
    }],

    // disallow mixed spaces and tabs for indentation
    'no-mixed-spaces-and-tabs': 2,

    // disallow multiple empty lines and only one newline at the end
    'no-multiple-empty-lines': [2, { max: 2, maxEOF: 1 }],

    // disallow negated conditions
    // http://eslint.org/docs/rules/no-negated-condition
    'no-negated-condition': 0,

    // disallow nested ternary expressions
    'no-nested-ternary': 2,

    // disallow use of the Object constructor
    'no-new-object': 2,

    // disallow use of unary operators, ++ and --
    'no-plusplus': 0,

    // disallow certain syntax forms
    // http://eslint.org/docs/rules/no-restricted-syntax
    'no-restricted-syntax': [
      2,
      'DebuggerStatement',
      'ForInStatement',
      'LabeledStatement',
      'WithStatement',
    ],

    // disallow space between function identifier and application
    'no-spaced-func': 2,

    // disallow the use of ternary operators
    'no-ternary': 0,

    // disallow trailing whitespace at the end of lines
    'no-trailing-spaces': 2,

    // disallow dangling underscores in identifiers
    'no-underscore-dangle': [2, { allowAfterThis: false }],

    // disallow the use of Boolean literals in conditional expressions
    // also, prefer `a || b` over `a ? a : b`
    // http://eslint.org/docs/rules/no-unneeded-ternary
    'no-unneeded-ternary': [2, { defaultAssignment: false }],

    // disallow whitespace before properties
    // http://eslint.org/docs/rules/no-whitespace-before-property
    'no-whitespace-before-property': 2,

    // require padding inside curly braces
    'object-curly-spacing': [2, 'always'],

    // enforce line breaks between braces
    // http://eslint.org/docs/rules/object-curly-newline
    'object-curly-newline': [0, {
      ObjectExpression: { minProperties: 0, multiline: true },
      ObjectPattern: { minProperties: 0, multiline: true }
    }],

    // enforce "same line" or "multiple line" on object properties.
    // http://eslint.org/docs/rules/object-property-newline
    'object-property-newline': [2, {
      allowMultiplePropertiesPerLine: true,
    }],

    // allow just one var statement per function
    'one-var': [2, 'never'],

    // require a newline around variable declaration
    // http://eslint.org/docs/rules/one-var-declaration-per-line
    'one-var-declaration-per-line': [2, 'always'],

    // require assignment operator shorthand where possible or prohibit it entirely
    'operator-assignment': 0,

    // enforce operators to be placed before or after line breaks
    'operator-linebreak': 0,

    // enforce padding within blocks
    'padded-blocks': [2, 'never'],

    // require quotes around object literal property names
    // http://eslint.org/docs/rules/quote-props.html
    'quote-props': [2, 'as-needed', { keywords: false, unnecessary: true, numbers: false }],

    // specify whether double or single quotes should be used
    quotes: [2, 'single', { avoidEscape: true }],

    // do not require jsdoc
    // http://eslint.org/docs/rules/require-jsdoc
    'require-jsdoc': 0,

    // require or disallow use of semicolons instead of ASI
    semi: [2, 'always'],

    // enforce spacing before and after semicolons
    'semi-spacing': [2, { before: false, after: true }],

    // sort variables within the same declaration block
    'sort-vars': 0,

    // require or disallow space before blocks
    'space-before-blocks': 2,

    // require or disallow space before function opening parenthesis
    // http://eslint.org/docs/rules/space-before-function-paren
    'space-before-function-paren': [2, { anonymous: 'always', named: 'never' }],

    // require or disallow spaces inside parentheses
    'space-in-parens': [2, 'never'],

    // require spaces around operators
    'space-infix-ops': 2,

    // Require or disallow spaces before/after unary operators
    'space-unary-ops': 0,

    // require or disallow a space immediately following the // or /* in a comment
    'spaced-comment': [2, 'always', {
      exceptions: ['-', '+'],
      markers: ['=', '!']           // space here to support sprockets directives
    }],

    // require or disallow the Unicode Byte Order Mark
    // http://eslint.org/docs/rules/unicode-bom
    'unicode-bom': [2, 'never'],

    // require regex literals to be wrapped in parentheses
    'wrap-regex': 0
  }
};
<commit_msg>[eslint config] [base] add TODO for `object-curly-newline`.<commit_after>module.exports = {
  rules: {
    // enforce spacing inside array brackets
    'array-bracket-spacing': [2, 'never'],

    // enforce spacing inside single-line blocks
    // http://eslint.org/docs/rules/block-spacing
    'block-spacing': [2, 'always'],

    // enforce one true brace style
    'brace-style': [2, '1tbs', { allowSingleLine: true }],

    // require camel case names
    camelcase: [2, { properties: 'never' }],

    // enforce spacing before and after comma
    'comma-spacing': [2, { before: false, after: true }],

    // enforce one true comma style
    'comma-style': [2, 'last'],

    // disallow padding inside computed properties
    'computed-property-spacing': [2, 'never'],

    // enforces consistent naming when capturing the current execution context
    'consistent-this': 0,

    // enforce newline at the end of file, with no multiple empty lines
    'eol-last': 2,

    // require function expressions to have a name
    'func-names': 1,

    // enforces use of function declarations or expressions
    'func-style': 0,

    // Blacklist certain identifiers to prevent them being used
    // http://eslint.org/docs/rules/id-blacklist
    'id-blacklist': 0,

    // this option enforces minimum and maximum identifier lengths
    // (variable names, property names etc.)
    'id-length': 0,

    // require identifiers to match the provided regular expression
    'id-match': 0,

    // this option sets a specific tab width for your code
    // http://eslint.org/docs/rules/indent
    indent: [2, 2, { SwitchCase: 1, VariableDeclarator: 1 }],

    // specify whether double or single quotes should be used in JSX attributes
    // http://eslint.org/docs/rules/jsx-quotes
    'jsx-quotes': 0,

    // enforces spacing between keys and values in object literal properties
    'key-spacing': [2, { beforeColon: false, afterColon: true }],

    // require a space before & after certain keywords
    'keyword-spacing': [2, {
      before: true,
      after: true,
      overrides: {
        return: { after: true },
        throw: { after: true },
        case: { after: true }
      }
    }],

    // disallow mixed 'LF' and 'CRLF' as linebreaks
    'linebreak-style': 0,

    // enforces empty lines around comments
    'lines-around-comment': 0,

    // specify the maximum depth that blocks can be nested
    'max-depth': [0, 4],

    // specify the maximum length of a line in your program
    // http://eslint.org/docs/rules/max-len
    'max-len': [2, 100, 2, {
      ignoreUrls: true,
      ignoreComments: false
    }],

    // specify the max number of lines in a file
    // http://eslint.org/docs/rules/max-lines
    'max-lines': [0, {
      max: 300,
      skipBlankLines: true,
      skipComments: true
    }],

    // specify the maximum depth callbacks can be nested
    'max-nested-callbacks': 0,

    // limits the number of parameters that can be used in the function declaration.
    'max-params': [0, 3],

    // specify the maximum number of statement allowed in a function
    'max-statements': [0, 10],

    // restrict the number of statements per line
    // http://eslint.org/docs/rules/max-statements-per-line
    'max-statements-per-line': [0, { max: 1 }],

    // require a capital letter for constructors
    'new-cap': [2, { newIsCap: true }],

    // disallow the omission of parentheses when invoking a constructor with no arguments
    'new-parens': 0,

    // allow/disallow an empty newline after var statement
    'newline-after-var': 0,

    // http://eslint.org/docs/rules/newline-before-return
    'newline-before-return': 0,

    // enforces new line after each method call in the chain to make it
    // more readable and easy to maintain
    // http://eslint.org/docs/rules/newline-per-chained-call
    'newline-per-chained-call': [2, { ignoreChainWithDepth: 3 }],

    // disallow use of the Array constructor
    'no-array-constructor': 2,

    // disallow use of bitwise operators
    'no-bitwise': 0,

    // disallow use of the continue statement
    'no-continue': 0,

    // disallow comments inline after code
    'no-inline-comments': 0,

    // disallow if as the only statement in an else block
    'no-lonely-if': 0,

    // disallow un-paren'd mixes of different operators
    // http://eslint.org/docs/rules/no-mixed-operators
    'no-mixed-operators': [2, {
      groups: [
        ['+', '-', '*', '/', '%', '**'],
        ['&', '|', '^', '~', '<<', '>>', '>>>'],
        ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
        ['&&', '||'],
        ['in', 'instanceof']
      ],
      allowSamePrecedence: false
    }],

    // disallow mixed spaces and tabs for indentation
    'no-mixed-spaces-and-tabs': 2,

    // disallow multiple empty lines and only one newline at the end
    'no-multiple-empty-lines': [2, { max: 2, maxEOF: 1 }],

    // disallow negated conditions
    // http://eslint.org/docs/rules/no-negated-condition
    'no-negated-condition': 0,

    // disallow nested ternary expressions
    'no-nested-ternary': 2,

    // disallow use of the Object constructor
    'no-new-object': 2,

    // disallow use of unary operators, ++ and --
    'no-plusplus': 0,

    // disallow certain syntax forms
    // http://eslint.org/docs/rules/no-restricted-syntax
    'no-restricted-syntax': [
      2,
      'DebuggerStatement',
      'ForInStatement',
      'LabeledStatement',
      'WithStatement',
    ],

    // disallow space between function identifier and application
    'no-spaced-func': 2,

    // disallow the use of ternary operators
    'no-ternary': 0,

    // disallow trailing whitespace at the end of lines
    'no-trailing-spaces': 2,

    // disallow dangling underscores in identifiers
    'no-underscore-dangle': [2, { allowAfterThis: false }],

    // disallow the use of Boolean literals in conditional expressions
    // also, prefer `a || b` over `a ? a : b`
    // http://eslint.org/docs/rules/no-unneeded-ternary
    'no-unneeded-ternary': [2, { defaultAssignment: false }],

    // disallow whitespace before properties
    // http://eslint.org/docs/rules/no-whitespace-before-property
    'no-whitespace-before-property': 2,

    // require padding inside curly braces
    'object-curly-spacing': [2, 'always'],

    // enforce line breaks between braces
    // http://eslint.org/docs/rules/object-curly-newline
    // TODO: enable once https://github.com/eslint/eslint/issues/6488 is resolved
    'object-curly-newline': [0, {
      ObjectExpression: { minProperties: 0, multiline: true },
      ObjectPattern: { minProperties: 0, multiline: true }
    }],

    // enforce "same line" or "multiple line" on object properties.
    // http://eslint.org/docs/rules/object-property-newline
    'object-property-newline': [2, {
      allowMultiplePropertiesPerLine: true,
    }],

    // allow just one var statement per function
    'one-var': [2, 'never'],

    // require a newline around variable declaration
    // http://eslint.org/docs/rules/one-var-declaration-per-line
    'one-var-declaration-per-line': [2, 'always'],

    // require assignment operator shorthand where possible or prohibit it entirely
    'operator-assignment': 0,

    // enforce operators to be placed before or after line breaks
    'operator-linebreak': 0,

    // enforce padding within blocks
    'padded-blocks': [2, 'never'],

    // require quotes around object literal property names
    // http://eslint.org/docs/rules/quote-props.html
    'quote-props': [2, 'as-needed', { keywords: false, unnecessary: true, numbers: false }],

    // specify whether double or single quotes should be used
    quotes: [2, 'single', { avoidEscape: true }],

    // do not require jsdoc
    // http://eslint.org/docs/rules/require-jsdoc
    'require-jsdoc': 0,

    // require or disallow use of semicolons instead of ASI
    semi: [2, 'always'],

    // enforce spacing before and after semicolons
    'semi-spacing': [2, { before: false, after: true }],

    // sort variables within the same declaration block
    'sort-vars': 0,

    // require or disallow space before blocks
    'space-before-blocks': 2,

    // require or disallow space before function opening parenthesis
    // http://eslint.org/docs/rules/space-before-function-paren
    'space-before-function-paren': [2, { anonymous: 'always', named: 'never' }],

    // require or disallow spaces inside parentheses
    'space-in-parens': [2, 'never'],

    // require spaces around operators
    'space-infix-ops': 2,

    // Require or disallow spaces before/after unary operators
    'space-unary-ops': 0,

    // require or disallow a space immediately following the // or /* in a comment
    'spaced-comment': [2, 'always', {
      exceptions: ['-', '+'],
      markers: ['=', '!']           // space here to support sprockets directives
    }],

    // require or disallow the Unicode Byte Order Mark
    // http://eslint.org/docs/rules/unicode-bom
    'unicode-bom': [2, 'never'],

    // require regex literals to be wrapped in parentheses
    'wrap-regex': 0
  }
};
<|endoftext|>


<commit_before>
// TODO: write a test that imports public interfaces in every possible
// permutation to detect circular dependency errors.
// See: https://esdiscuss.org/topic/how-to-solve-this-basic-es6-module-circular-dependency-problem

import Transformable from './Transformable'
import Motor from './Motor'

import ImperativeBase, {initImperativeBase} from './ImperativeBase'
import XYZValues from './XYZValues'
import XYZNonNegativeValues from './XYZNonNegativeValues'
import ValueProcessor from './ValueProcessor'
import { default as HTMLInterface } from '../html/HTMLScene'
import documentReady from '@awaitbox/document-ready'

import {
    Scene as ThreeScene, // so as not to confuse with Infamous Scene.
    PerspectiveCamera,
    //AmbientLight,
    Color,
} from 'three'

initImperativeBase()

const instanceofSymbol = Symbol('instanceofSymbol')

let Scene = null

const SceneMixin = base => {
    class _Scene extends ValueProcessor( ImperativeBase.mixin( Transformable.mixin( base ) ) ) {
        static get defaultElementName() { return 'i-scene' }

        construct(options = {}) {
            super.construct(options)

            // Used by the this.scene getter in ImperativeBase
            // Motor's loop checks _scene on Nodes and Scenes when determining
            // modified scenes.
            this._scene = this

            // TODO get default camera values from somewhere.
            this._perspective = 1000

            // size of the element where the Scene is mounted
            // NOTE: z size is always 0, since native DOM elements are always flat.
            this._elementParentSize = {x:0, y:0, z:0}

            this._calcSize()
            this._needsToBeRendered()
        }

        _onElementParentSizeChange(newSize) {
            this._elementParentSize = newSize
            this._calcSize()
            this._needsToBeRendered()
        }

        // For now, use the same program (with shaders) for all objects.
        // Basically it has position, frag colors, point light, directional
        // light, and ambient light.
        // TODO: maybe call this in `init()`, and destroy webgl stuff in
        // `deinit()`.
        // TODO: The user might enable this by setting the attribute later, so
        // we can't simply rely on having it in constructor, we need a
        // getter/setter like node properties.
        // TODO: we need to deinit webgl too.
        async initWebGl() {
            // THREE
            // maybe keep this in sceneState in WebGLRendererThree
            super.initWebGl()

            // We don't let Three update any matrices, we supply our own world
            // matrices.
            this.threeObject3d.autoUpdate = false

            // this.threeCamera holds the active camera. There can be many
            // cameras in the scene tree, but the last one with active="true"
            // will be the one referenced here.
            // If there are no cameras in the tree, a virtual default camera is
            // referenced here, who's perspective is that of the scene's
            // perspective attribute.
            this.threeCamera = null
            this._createDefaultCamera()

            // TODO: default ambient light when no AmbientLight elements are
            // present in the Scene.
            //const ambientLight = new AmbientLight( 0x353535 )
            //this.threeObject3d.add( ambientLight )

            // holds the renderer for this scene, renderers have scene-specific
            // settings so having this reference is okay.
            this._renderer = null

            // a default orange background color. Use the backgroundColor and
            // backgroundOpacity attributes to customize.
            this._glBackgroundColor = new Color( 0xff6600 )
            this._glBackgroundOpacity = 0

            // holds active cameras found in the DOM tree (if this is empty, it
            // means no camera elements are in the DOM, but this.threeCamera
            // will still have a reference to the default camera that scenes
            // are rendered with when no camera elements exist).
            this._activeCameras = new Set

            // TODO: this needs to be cancelable too, search other codes for
            // "mountcancel" to see.
            await this.mountPromise

            this.webglEnabled = !!this.element.hasAttribute('experimental-webgl')
            if (!this.webglEnabled) return

            this._renderer = Motor.getWebGLRenderer(this, 'three')

            // set default colors
            this._renderer.setClearColor( this, this._glBackgroundColor, this._glBackgroundOpacity )
        }

        makeThreeObject3d() {
            return new ThreeScene
        }

        // TODO ability to init and destroy webgl for the whole scene.
        destroyWebGl() {
        }

        // TODO PERFORMANCE: make this static for better performance.
        _setDefaultProperties() {
            super._setDefaultProperties()

            Object.assign(this._properties, {
                sizeMode: new XYZValues('proportional', 'proportional', 'proportional'),
                size: new XYZNonNegativeValues(1, 1, 1),
            })
        }

        _setCamera( camera ) {
            if ( !camera ) {
                this._createDefaultCamera()
            }
            else {
                // TODO?: implement an changecamera event/method and emit/call
                // that here, then move this logic to the renderer
                // handler/method?
                this.threeCamera = camera.threeObject3d
                this._updateCameraAspect()
                this._updateCameraProjection()
                this._needsToBeRendered()
            }
        }

        _createDefaultCamera() {
            const size = this._calculatedSize
            // THREE-COORDS-TO-DOM-COORDS
            // We apply Three perspective the same way as CSS3D perspective here.
            // TODO CAMERA-DEFAULTS, get defaults from somewhere common.
            // TODO the "far" arg will be auto-calculated to encompass the furthest objects (like CSS3D).
            this.threeCamera = new PerspectiveCamera( 45, size.x / size.y || 1, 0.1, 10000 )
            this.perspective = 1000
        }

        // TODO can this be moved to a render task like _calcSize? It depends
        // on size values.
        _updateCameraPerspective() {
            const perspective = this._perspective
            this.threeCamera.fov = 180 * ( 2 * Math.atan( this._calculatedSize.y / 2 / perspective ) ) / Math.PI
            this.threeCamera.position.z = perspective
        }

        set perspective(value) {
            this._perspective = value
            this._updateCameraPerspective()
            this._updateCameraProjection()
            this._needsToBeRendered()
        }
        get perspective() {
            return this._perspective
        }

        _updateCameraAspect() {
            this.threeCamera.aspect = this._calculatedSize.x / this._calculatedSize.y || 1
        }

        _updateCameraProjection() {
            this.threeCamera.updateProjectionMatrix()
        }

        _addCamera( camera ) {
            this._activeCameras.add( camera )
            this._setCamera( camera )
        }

        _removeCamera( camera ) {
            this._activeCameras.delete( camera )

            if ( this._activeCameras.size ) {
                // get the last camera in the Set
                this._activeCameras.forEach(c => camera = c)
            }
            else camera = null

            this._setCamera( camera )
        }

        /** @override */
        _getParentSize() {
            return this._parent ? this._parent._calculatedSize : this._elementParentSize
        }

        /**
         * Mount the scene into the given target.
         * Resolves the Scene's mountPromise, which can be use to do something once
         * the scene is mounted.
         *
         * @param {string|HTMLElement} [mountPoint=document.body] If a string selector is provided,
         * the mount point will be selected from the DOM. If an HTMLElement is
         * provided, that will be the mount point. If no mount point is provided,
         * the scene will be mounted into document.body.
         */
        async mount(mountPoint) {
            // Wait for the document to be ready before mounting, otherwise the
            // target mount point might not exist yet when this function is called.
            if (document.readyState == 'loading') await documentReady()

            // if no mountPoint was provided, just mount onto the <body> element.
            if (mountPoint === undefined) mountPoint = document.body

            // if the user supplied a selector, mount there.
            else if (typeof mountPoint === 'string')
                mountPoint = document.querySelector(mountPoint)

            // if we have an actual mount point (the user may have supplied one)
            if (!(mountPoint instanceof HTMLElement))
                throw new Error('Invalid mount point specified in Scene.mount() call. Pass a selector, an actual HTMLElement, or don\'t pass anything to mount to <body>.')

            if (this._mounted) this.unmount()

            if (mountPoint !== this.parentNode)
                mountPoint.appendChild(this)

            this._mounted = true

            if (this._mountPromise) this._resolveMountPromise()

            this._elementOperations.shouldRender()
            this._startOrStopSizePolling()
        }

        /**
         * Unmount the scene from it's mount point. Resets the Scene's
         * mountPromise.
         */
        unmount() {
            if (!this._mounted) return

            this._elementOperations.shouldNotRender()
            this._stopSizePolling()

            if (this.parentNode)
                this.parentNode.removeChild(this)

            if (this._mountPromise) this._rejectMountPromise('mountcancel')
            this._resetMountPromise()
        }

        set sizeMode(value) {
            super.sizeMode = value
            this._startOrStopSizePolling()
        }

        static get observedAttributes() {
            const superAttrs = super.observedAttributes || []
            return superAttrs.concat( [
                'backgroundcolor',
                'background-color',
                'backgroundopacity',
                'background-opacity',
                'shadowmaptype',
                'shadowmap-type',
            ] )
        }

        // TODO: generic type system for attributes.
        async attributeChangedCallback(attr, oldVal, newVal) {
            super.attributeChangedCallback(attr, oldVal, newVal)

            // We need to await mountPromise here so that we set values *after*
            // values are set in initWebGl
            //
            // TODO: this needs to be cancelable too, search other codes for
            // "mountcancel" to see.
            await this.mountPromise

            if ( attr == 'backgroundcolor' ) {
                this.processClearColorValue( attr, newVal )
                this._needsToBeRendered()
            }
            else if ( attr == 'backgroundopacity' ) {
                this.processClearAlphaValue( attr, newVal )
                this._needsToBeRendered()
            }
            else if ( attr == 'shadowmaptype' || attr == 'shadowmap-type' ) {
                this._renderer.setShadowMapType(this, newVal)
                this._needsToBeRendered()
            }
        }

        processClearColorValue( attr, value ) {
            this.processColorValue( value, this, '_glBackgroundColor' )
            this._renderer.setClearColor( this, this._glBackgroundColor, this._glBackgroundOpacity )
        }

        processClearAlphaValue( attr, value ) {
            this.processNumberValue( '_glBackgroundOpacity', value, this )
            this._renderer.setClearAlpha( this, this._glBackgroundOpacity)
        }

    }

    Object.defineProperty(_Scene, Symbol.hasInstance, {
        value: function(obj) {
            if (this !== _Scene) return Object.getPrototypeOf(_Scene)[Symbol.hasInstance].call(this, obj)

            let currentProto = obj

            while(currentProto) {
                const desc = Object.getOwnPropertyDescriptor(currentProto, "constructor")

                if (desc && desc.value && desc.value.hasOwnProperty(instanceofSymbol))
                    return true

                currentProto = Object.getPrototypeOf(currentProto)
            }

            return false
        }
    })

    _Scene[instanceofSymbol] = true

    return _Scene
}

Scene = SceneMixin(class{})
Scene.mixin = SceneMixin

// TODO for now, hard-mixin the HTMLInterface class. We'll do this automatically later.
Scene = Scene.mixin(HTMLInterface)

export {Scene as default}
<commit_msg>TODO about fixing the camera<commit_after>
// TODO: write a test that imports public interfaces in every possible
// permutation to detect circular dependency errors.
// See: https://esdiscuss.org/topic/how-to-solve-this-basic-es6-module-circular-dependency-problem

import Transformable from './Transformable'
import Motor from './Motor'

import ImperativeBase, {initImperativeBase} from './ImperativeBase'
import XYZValues from './XYZValues'
import XYZNonNegativeValues from './XYZNonNegativeValues'
import ValueProcessor from './ValueProcessor'
import { default as HTMLInterface } from '../html/HTMLScene'
import documentReady from '@awaitbox/document-ready'

import {
    Scene as ThreeScene, // so as not to confuse with Infamous Scene.
    PerspectiveCamera,
    //AmbientLight,
    Color,
} from 'three'

initImperativeBase()

const instanceofSymbol = Symbol('instanceofSymbol')

let Scene = null

const SceneMixin = base => {
    class _Scene extends ValueProcessor( ImperativeBase.mixin( Transformable.mixin( base ) ) ) {
        static get defaultElementName() { return 'i-scene' }

        construct(options = {}) {
            super.construct(options)

            // Used by the this.scene getter in ImperativeBase
            // Motor's loop checks _scene on Nodes and Scenes when determining
            // modified scenes.
            this._scene = this

            // TODO get default camera values from somewhere.
            this._perspective = 1000

            // size of the element where the Scene is mounted
            // NOTE: z size is always 0, since native DOM elements are always flat.
            this._elementParentSize = {x:0, y:0, z:0}

            this._calcSize()
            this._needsToBeRendered()
        }

        _onElementParentSizeChange(newSize) {
            this._elementParentSize = newSize
            this._calcSize()
            this._needsToBeRendered()
        }

        // For now, use the same program (with shaders) for all objects.
        // Basically it has position, frag colors, point light, directional
        // light, and ambient light.
        // TODO: maybe call this in `init()`, and destroy webgl stuff in
        // `deinit()`.
        // TODO: The user might enable this by setting the attribute later, so
        // we can't simply rely on having it in constructor, we need a
        // getter/setter like node properties.
        // TODO: we need to deinit webgl too.
        async initWebGl() {
            // THREE
            // maybe keep this in sceneState in WebGLRendererThree
            super.initWebGl()

            // We don't let Three update any matrices, we supply our own world
            // matrices.
            this.threeObject3d.autoUpdate = false

            // this.threeCamera holds the active camera. There can be many
            // cameras in the scene tree, but the last one with active="true"
            // will be the one referenced here.
            // If there are no cameras in the tree, a virtual default camera is
            // referenced here, who's perspective is that of the scene's
            // perspective attribute.
            this.threeCamera = null
            this._createDefaultCamera()

            // TODO: default ambient light when no AmbientLight elements are
            // present in the Scene.
            //const ambientLight = new AmbientLight( 0x353535 )
            //this.threeObject3d.add( ambientLight )

            // holds the renderer for this scene, renderers have scene-specific
            // settings so having this reference is okay.
            this._renderer = null

            // a default orange background color. Use the backgroundColor and
            // backgroundOpacity attributes to customize.
            this._glBackgroundColor = new Color( 0xff6600 )
            this._glBackgroundOpacity = 0

            // holds active cameras found in the DOM tree (if this is empty, it
            // means no camera elements are in the DOM, but this.threeCamera
            // will still have a reference to the default camera that scenes
            // are rendered with when no camera elements exist).
            this._activeCameras = new Set

            // TODO: this needs to be cancelable too, search other codes for
            // "mountcancel" to see.
            await this.mountPromise

            this.webglEnabled = !!this.element.hasAttribute('experimental-webgl')
            if (!this.webglEnabled) return

            this._renderer = Motor.getWebGLRenderer(this, 'three')

            // set default colors
            this._renderer.setClearColor( this, this._glBackgroundColor, this._glBackgroundOpacity )
        }

        makeThreeObject3d() {
            return new ThreeScene
        }

        // TODO ability to init and destroy webgl for the whole scene.
        destroyWebGl() {
        }

        // TODO PERFORMANCE: make this static for better performance.
        _setDefaultProperties() {
            super._setDefaultProperties()

            Object.assign(this._properties, {
                sizeMode: new XYZValues('proportional', 'proportional', 'proportional'),
                size: new XYZNonNegativeValues(1, 1, 1),
            })
        }

        // TODO FIXME: manual camera doesn't work after we've added the
        // default-camera feature.
        _setCamera( camera ) {
            if ( !camera ) {
                this._createDefaultCamera()
            }
            else {
                // TODO?: implement an changecamera event/method and emit/call
                // that here, then move this logic to the renderer
                // handler/method?
                this.threeCamera = camera.threeObject3d
                this._updateCameraAspect()
                this._updateCameraProjection()
                this._needsToBeRendered()
            }
        }

        _createDefaultCamera() {
            const size = this._calculatedSize
            // THREE-COORDS-TO-DOM-COORDS
            // We apply Three perspective the same way as CSS3D perspective here.
            // TODO CAMERA-DEFAULTS, get defaults from somewhere common.
            // TODO the "far" arg will be auto-calculated to encompass the furthest objects (like CSS3D).
            this.threeCamera = new PerspectiveCamera( 45, size.x / size.y || 1, 0.1, 10000 )
            this.perspective = 1000
        }

        // TODO can this be moved to a render task like _calcSize? It depends
        // on size values.
        _updateCameraPerspective() {
            const perspective = this._perspective
            this.threeCamera.fov = 180 * ( 2 * Math.atan( this._calculatedSize.y / 2 / perspective ) ) / Math.PI
            this.threeCamera.position.z = perspective
        }

        set perspective(value) {
            this._perspective = value
            this._updateCameraPerspective()
            this._updateCameraProjection()
            this._needsToBeRendered()
        }
        get perspective() {
            return this._perspective
        }

        _updateCameraAspect() {
            this.threeCamera.aspect = this._calculatedSize.x / this._calculatedSize.y || 1
        }

        _updateCameraProjection() {
            this.threeCamera.updateProjectionMatrix()
        }

        _addCamera( camera ) {
            this._activeCameras.add( camera )
            this._setCamera( camera )
        }

        _removeCamera( camera ) {
            this._activeCameras.delete( camera )

            if ( this._activeCameras.size ) {
                // get the last camera in the Set
                this._activeCameras.forEach(c => camera = c)
            }
            else camera = null

            this._setCamera( camera )
        }

        /** @override */
        _getParentSize() {
            return this._parent ? this._parent._calculatedSize : this._elementParentSize
        }

        /**
         * Mount the scene into the given target.
         * Resolves the Scene's mountPromise, which can be use to do something once
         * the scene is mounted.
         *
         * @param {string|HTMLElement} [mountPoint=document.body] If a string selector is provided,
         * the mount point will be selected from the DOM. If an HTMLElement is
         * provided, that will be the mount point. If no mount point is provided,
         * the scene will be mounted into document.body.
         */
        async mount(mountPoint) {
            // Wait for the document to be ready before mounting, otherwise the
            // target mount point might not exist yet when this function is called.
            if (document.readyState == 'loading') await documentReady()

            // if no mountPoint was provided, just mount onto the <body> element.
            if (mountPoint === undefined) mountPoint = document.body

            // if the user supplied a selector, mount there.
            else if (typeof mountPoint === 'string')
                mountPoint = document.querySelector(mountPoint)

            // if we have an actual mount point (the user may have supplied one)
            if (!(mountPoint instanceof HTMLElement))
                throw new Error('Invalid mount point specified in Scene.mount() call. Pass a selector, an actual HTMLElement, or don\'t pass anything to mount to <body>.')

            if (this._mounted) this.unmount()

            if (mountPoint !== this.parentNode)
                mountPoint.appendChild(this)

            this._mounted = true

            if (this._mountPromise) this._resolveMountPromise()

            this._elementOperations.shouldRender()
            this._startOrStopSizePolling()
        }

        /**
         * Unmount the scene from it's mount point. Resets the Scene's
         * mountPromise.
         */
        unmount() {
            if (!this._mounted) return

            this._elementOperations.shouldNotRender()
            this._stopSizePolling()

            if (this.parentNode)
                this.parentNode.removeChild(this)

            if (this._mountPromise) this._rejectMountPromise('mountcancel')
            this._resetMountPromise()
        }

        set sizeMode(value) {
            super.sizeMode = value
            this._startOrStopSizePolling()
        }

        static get observedAttributes() {
            const superAttrs = super.observedAttributes || []
            return superAttrs.concat( [
                'backgroundcolor',
                'background-color',
                'backgroundopacity',
                'background-opacity',
                'shadowmaptype',
                'shadowmap-type',
            ] )
        }

        // TODO: generic type system for attributes.
        async attributeChangedCallback(attr, oldVal, newVal) {
            super.attributeChangedCallback(attr, oldVal, newVal)

            // We need to await mountPromise here so that we set values *after*
            // values are set in initWebGl
            //
            // TODO: this needs to be cancelable too, search other codes for
            // "mountcancel" to see.
            await this.mountPromise

            if ( attr == 'backgroundcolor' ) {
                this.processClearColorValue( attr, newVal )
                this._needsToBeRendered()
            }
            else if ( attr == 'backgroundopacity' ) {
                this.processClearAlphaValue( attr, newVal )
                this._needsToBeRendered()
            }
            else if ( attr == 'shadowmaptype' || attr == 'shadowmap-type' ) {
                this._renderer.setShadowMapType(this, newVal)
                this._needsToBeRendered()
            }
        }

        processClearColorValue( attr, value ) {
            this.processColorValue( value, this, '_glBackgroundColor' )
            this._renderer.setClearColor( this, this._glBackgroundColor, this._glBackgroundOpacity )
        }

        processClearAlphaValue( attr, value ) {
            this.processNumberValue( '_glBackgroundOpacity', value, this )
            this._renderer.setClearAlpha( this, this._glBackgroundOpacity)
        }

    }

    Object.defineProperty(_Scene, Symbol.hasInstance, {
        value: function(obj) {
            if (this !== _Scene) return Object.getPrototypeOf(_Scene)[Symbol.hasInstance].call(this, obj)

            let currentProto = obj

            while(currentProto) {
                const desc = Object.getOwnPropertyDescriptor(currentProto, "constructor")

                if (desc && desc.value && desc.value.hasOwnProperty(instanceofSymbol))
                    return true

                currentProto = Object.getPrototypeOf(currentProto)
            }

            return false
        }
    })

    _Scene[instanceofSymbol] = true

    return _Scene
}

Scene = SceneMixin(class{})
Scene.mixin = SceneMixin

// TODO for now, hard-mixin the HTMLInterface class. We'll do this automatically later.
Scene = Scene.mixin(HTMLInterface)

export {Scene as default}
<|endoftext|>