<commit_before>var mouse = require('mouse').create(casper);
var u = require('utils');
var c = require('colorizer').create('Colorizer');

var NB_TESTS = 10;
var nippleIndex = 0;
var collectionIndex = 0;
var showClientLog = false;

/*
    CONFIGURE CASPER
*/

casper.options.viewportSize = {width: 1100, height: 900};
casper.options.logLevel = 'debug';

/*
    LISTEN TO CASPER
*/

casper.on('remote.message', function(message) {
    if (!showClientLog) {
        return;
    }
    if (typeof message === 'string') {
        casper.echo('>> [CLIENT] ' + message, 'WARN_BAR');
    } else {
        casper.echo('>> [CLIENT] DUMP', 'WARN_BAR');
        u.dump(message);
    }
});

casper.on('resource.error', function(message) {
    if (!showClientLog) {
        return;
    }
    if (typeof message === 'string') {
        casper.echo('>> [CLIENT] ' + message, 'RED_BAR');
    } else {
        casper.echo('>> [CLIENT] DUMP', 'RED_BAR');
        u.dump(message);
    }
});

casper.on('page.error', function(message, trace) {
    if (!showClientLog) {
        return;
    }
    if (typeof message === 'string') {
        casper.echo('>> [CLIENT] ' + message, 'RED_BAR');
    } else {
        casper.echo('>> [CLIENT] DUMP', 'RED_BAR');
        u.dump(message);
    }
    u.dump(trace);
});

/*
    ACTIONS
*/

function clickZone () {
    mouse.down('.zone.active');
}

function assertNipple (test) {
    return function () {
        test.assertExists('#nipple_' + collectionIndex +
            '_' + nippleIndex,
            'Nipple ' + nippleIndex + ' from collection ' +
            collectionIndex + ' is found');
        nippleIndex += 1;
    };
}

function assertNotNipple (test) {
    return function () {
        test.assertDoesntExist('#nipple_' + collectionIndex +
            '_' + nippleIndex,
            'Nipple ' + nippleIndex + ' from collection ' +
            collectionIndex + ' is NOT found');
        nippleIndex += 1;
    };
}

casper.test.begin('NippleJS test page loads correctly', NB_TESTS,
    function suite(test) {
        var box;
        casper
            .start('http://127.0.0.1:8080')
            .then(function () {
                // Assert that active zone is here.
                test.assertExists('#zone_joystick', 'Active zone is found');
                test.assertExists('.zone.dynamic', 'Dynamic zone is default');
            })
            .then(function () {
                // Get position of active zone.
                box = casper.evaluate(function () {
                    return document.getElementById('zone_joystick')
                        .getBoundingClientRect();
                });
            })
            /**********************************\
            *
            *				DYNAMIC
            *
            \**********************************/
            // Assert we can create more than one nipple on dynamic
            .then(clickZone)
            .then(assertNipple(test))
            .then(clickZone)
            .then(assertNipple(test))
            /**********************************\
            *
            *				SEMI
            *
            \**********************************/
            .then(function () {
                mouse.click('.button.semi');
                collectionIndex += 1;
            })
            .then(function () {
                test.assertVisible('.zone.semi', 'Semi zone should be visible');
            })
            // Assert we can't create more than one nipple on semi
            .then(clickZone)
            .then(assertNipple(test))
            .then(clickZone)
            .then(assertNotNipple(test))
            .then(function () {
                // Revert increment because last nipple doesn't exist
                nippleIndex -= 1;
            })
            /**********************************\
            *
            *				STATIC
            *
            \**********************************/
            .then(function () {
                mouse.click('.button.static');
                collectionIndex += 1;
            })
            .then(function () {
                test.assertVisible('.zone.static',
                    'Static zone should be visible');
            })
            // Assert we can't create more than one nipple on semi
            .then(clickZone)
            .then(assertNipple(test))
            .then(clickZone)
            .then(assertNotNipple(test))
            .then(function () {
                // Revert increment because last nipple doesn't exist
                nippleIndex -= 1;
            })
            .run(function () {
                // End tests
                test.done();
            });
    }
);
<commit_msg>test: fix phantom tests to use fileSystem to access pages<commit_after>var mouse = require('mouse').create(casper);
var u = require('utils');
var c = require('colorizer').create('Colorizer');

var NB_TESTS = 10;
var nippleIndex = 0;
var collectionIndex = 0;
var showClientLog = false;
var currentFile = require('system').args[3];
var curFilePath = fs.absolute(currentFile);

/*
    CONFIGURE CASPER
*/

casper.options.viewportSize = {width: 1100, height: 900};
casper.options.logLevel = 'debug';

/*
    LISTEN TO CASPER
*/

casper.on('remote.message', function(message) {
    if (!showClientLog) {
        return;
    }
    if (typeof message === 'string') {
        casper.echo('>> [CLIENT] ' + message, 'WARN_BAR');
    } else {
        casper.echo('>> [CLIENT] DUMP', 'WARN_BAR');
        u.dump(message);
    }
});

casper.on('resource.error', function(message) {
    if (!showClientLog) {
        return;
    }
    if (typeof message === 'string') {
        casper.echo('>> [CLIENT] ' + message, 'RED_BAR');
    } else {
        casper.echo('>> [CLIENT] DUMP', 'RED_BAR');
        u.dump(message);
    }
});

casper.on('page.error', function(message, trace) {
    if (!showClientLog) {
        return;
    }
    if (typeof message === 'string') {
        casper.echo('>> [CLIENT] ' + message, 'RED_BAR');
    } else {
        casper.echo('>> [CLIENT] DUMP', 'RED_BAR');
        u.dump(message);
    }
    u.dump(trace);
});

/*
    ACTIONS
*/

function clickZone () {
    mouse.down('.zone.active');
}

function assertNipple (test) {
    return function () {
        test.assertExists('#nipple_' + collectionIndex +
            '_' + nippleIndex,
            'Nipple ' + nippleIndex + ' from collection ' +
            collectionIndex + ' is found');
        nippleIndex += 1;
    };
}

function assertNotNipple (test) {
    return function () {
        test.assertDoesntExist('#nipple_' + collectionIndex +
            '_' + nippleIndex,
            'Nipple ' + nippleIndex + ' from collection ' +
            collectionIndex + ' is NOT found');
        nippleIndex += 1;
    };
}

casper.test.begin('NippleJS test page loads correctly', NB_TESTS,
    function suite(test) {
        var box;
        casper
            .start(curFilePath + '/index.html')
            .then(function () {
                // Assert that active zone is here.
                test.assertExists('#zone_joystick', 'Active zone is found');
                test.assertExists('.zone.dynamic', 'Dynamic zone is default');
            })
            .then(function () {
                // Get position of active zone.
                box = casper.evaluate(function () {
                    return document.getElementById('zone_joystick')
                        .getBoundingClientRect();
                });
            })
            /**********************************\
            *
            *				DYNAMIC
            *
            \**********************************/
            // Assert we can create more than one nipple on dynamic
            .then(clickZone)
            .then(assertNipple(test))
            .then(clickZone)
            .then(assertNipple(test))
            /**********************************\
            *
            *				SEMI
            *
            \**********************************/
            .then(function () {
                mouse.click('.button.semi');
                collectionIndex += 1;
            })
            .then(function () {
                test.assertVisible('.zone.semi', 'Semi zone should be visible');
            })
            // Assert we can't create more than one nipple on semi
            .then(clickZone)
            .then(assertNipple(test))
            .then(clickZone)
            .then(assertNotNipple(test))
            .then(function () {
                // Revert increment because last nipple doesn't exist
                nippleIndex -= 1;
            })
            /**********************************\
            *
            *				STATIC
            *
            \**********************************/
            .then(function () {
                mouse.click('.button.static');
                collectionIndex += 1;
            })
            .then(function () {
                test.assertVisible('.zone.static',
                    'Static zone should be visible');
            })
            // Assert we can't create more than one nipple on semi
            .then(clickZone)
            .then(assertNipple(test))
            .then(clickZone)
            .then(assertNotNipple(test))
            .then(function () {
                // Revert increment because last nipple doesn't exist
                nippleIndex -= 1;
            })
            .run(function () {
                // End tests
                test.done();
            });
    }
);
<|endoftext|>


<commit_before>'use strict';

/*
 * this test must run as an npm script for the library to work properly
 *
 * the fixtures are actually the package.json fields, so the root package.json is used for that,
 * and the "config" field is there solely for testing purposes.
 */

const assert = require('assert');

describe(`npm-package-env > `, function () {

    let env, expectedEnv;

    before(function init() {
        expectedEnv = require('../package.json');
    });

    describe(`requiring the module,`, function () {

        beforeEach(function init() {
            env = require('../lib/npm-package-env');
        });

        it(`should return an instance`, function () {
            assert.ok(env);
        });

        it(`should return a new instance of the same type on another invocation`, function () {
            let required = require('../lib/npm-package-env');
            assert.ok(required);
            assert.equal(typeof required, typeof env, 'disparate types!');
            assert.notStrictEqual(required, env);
        });
    });

    describe(`property access,`, function () {

        beforeEach(function init() {
            env = require('../lib/npm-package-env');
        });

        describe(`on existing value,`, function () {

            it(`should return truthy`, function () {
                assert.ok(env.version);
            });

            it(`should work with both dot and bracket notation`, function () {
                assert.ok(env.version);
                assert.ok(env['version']);
            });

            it(`should be reflectable`, function () {
                assert.ok(Reflect.has({'npm-package-env': 'wat'}, env.name));
            });

            describe(`on multiple invocations of the same instance,`, function () {

                it(`should return the same result`, function () {
                    assert.equal(env.name, expectedEnv.name);
                    assert.equal(env.name, expectedEnv.name);
                });

                it(`should return the same result after assigning the chained proxy`, function () {
                    let data = env.config['wrap-obj'];
                    let expected = expectedEnv.config['wrap-obj'].foo;
                    assert.equal(data.foo, expected);
                    assert.equal(data.foo, expected);
                });

                it(`should return the same result after assigning the chained proxy (deep access)`, function () {
                    let data = env.config['wrap-obj'];
                    let expected = expectedEnv.config['wrap-obj'].obj.foo;
                    assert.equal(data.obj.foo, expected);
                    assert.equal(data.obj.foo, expected);
                });

                it(`should keep having the expected values after accessing another namespace`, function () {
                    env.config['wrap-obj'].foo;
                    assert.equal(env.version, expectedEnv.version);
                });
            });

            it(`should not interfere with other instances' accessor calls`, function () {
                let conf1 = env.config;
                let conf2 = require('../lib/npm-package-env').config;
                conf1.foo;
                let expected = conf2.foo;
                let actual = expectedEnv.config.foo;
                assert.strictEqual(actual, expected);
            });

            it(`should return the property value as string`, function () {
                let expected = expectedEnv.config.foo;
                let actual = env.config.foo;
                assert.ok(typeof actual === 'string');
                assert.strictEqual(actual, expected);
            });

            describe(`inside an array,`, function () {

                it(`should return the property value as string`, function () {
                    let expected = expectedEnv.config['wrap-obj'].arr[1];
                    let actual = env.config['wrap-obj'].arr[1];
                    assert.ok(typeof actual === 'string');
                    assert.strictEqual(actual, expected);
                });
            });

            describe(`inside an object,`, function () {

                it(`should return the property value as string`, function () {
                    let expected = expectedEnv.config['wrap-obj'].obj.foo;
                    let actual = env.config['wrap-obj'].obj.foo;
                    assert.ok(typeof actual === 'string');
                    assert.strictEqual(actual, expected);
                });
            });
        });

        describe(`on non-existing value,`, function () {

            it(`should return truthy`, function () {
                assert.ok(env.watwatwat);
            });

            it(`should return a similar instance`, function () {
                assert.notStrictEqual(env.watwatwat, env);
            });

            it(`should work with both dot and bracket notation`, function () {
                assert.ok(env.watwatwat);
                assert.ok(env['watwatwat']);
            });
        });
    });

    describe(`property write,`, function () {

        beforeEach(function init() {
            env = require('../lib/npm-package-env');
        });

        describe(`on existing value,`, function () {

            beforeEach(function init() {
                env.config.foo = expectedEnv.config.foo;
            });

            it(`should set a new value`, function () {
                let original = env.config.foo;
                env.config.foo = 'lol';
                let updated = env.config.foo;
                assert.notEqual(updated, original);
            });

            it(`should not fail on a falsish value`, function () {
                let setter = () => env.config.foo = 0;
                assert.doesNotThrow(setter, TypeError);
            });

            it(`should set a new value even if its falsish`, function () {
                let original = env.config.foo;
                env.config.foo = 0;
                let updated = env.config.foo;
                assert.notEqual(updated, original);
            });

            describe(`when the value is not a string,`, function () {

                it(`should coerce the value to a string`, function () {
                    env.config.foo = 1;
                    let coerced = env.config.foo;
                    console.log('typeof coerced: ', typeof coerced);
                    assert(typeof coerced === 'string');
                });

                it(`should coerce the value to a string even if it does not exist`, function () {
                    env.lalala = 1;
                    let coerced = env.lalala;
                    assert(typeof coerced === 'string');
                });

                it(`should coerce the value to a string even if it does not exist (deep access)`, function () {
                    env.config.lalala = 1;
                    let coerced = env.config.lalala;
                    assert(typeof coerced === 'string');
                });
            });

            describe(`inside an array,`, function () {

                beforeEach(function init() {
                    env.config['wrap-obj'].arr[1] = expectedEnv.config['wrap-obj'].arr[1];
                });

                it(`should set a new value`, function () {
                    let original = env.config['wrap-obj'].arr[1];
                    env.config['wrap-obj'].arr[1] = 'lol';
                    let updated = env.config['wrap-obj'].arr[1];
                    assert.notEqual(updated, original);
                });
            });

            describe(`inside an object,`, function () {

                beforeEach(function init() {
                    env.config['wrap-obj'].obj.foo = expectedEnv.config['wrap-obj'].obj.foo;
                });

                it(`should set a new value`, function () {
                    let original = env.config['wrap-obj'].obj.foo;
                    env.config['wrap-obj'].obj.foo = 'lol';
                    let updated = env.config['wrap-obj'].obj.foo;
                    assert.notEqual(updated, original);
                });
            });

            describe(`on multiple invocations of the same instance,`, function () {

                it(`should set a new value`, function () {
                    let original = env.config.foo;
                    env.config.foo = 'lol';
                    env.config.foo = 'lol';
                    let updated = env.config.foo;
                    assert.notEqual(updated, original);
                });

                it(`should set the last value assigned`, function () {
                    env.config.foo = 'wat';
                    env.config.foo = 'lol';
                    let last = env.config.foo;
                    assert.equal(last, 'lol');
                });
            });
        });

        describe(`on non-existing value,`, function () {

            it(`should set a new value`, function () {
                let original = env.config['wrap-obj'].obj.watwatwat;
                env.config['wrap-obj'].obj.watwatwat = 'lol';
                let updated = env.config['wrap-obj'].obj.watwatwat;
                assert.notEqual(updated, original);
            });
        });
    });

    xdescribe(`property removal,`, function () {

        it(`should delete the property value`, function () {
            let original = env.config['wrap-obj'].obj.watwatwat;
            env.config['wrap-obj'].obj.watwatwat = 'lol';
            let updated = env.config['wrap-obj'].obj.watwatwat;
            assert.notEqual(updated, original);
        });
    });
});
                    <commit_msg>remove log<commit_after>'use strict';

/*
 * this test must run as an npm script for the library to work properly
 *
 * the fixtures are actually the package.json fields, so the root package.json is used for that,
 * and the "config" field is there solely for testing purposes.
 */

const assert = require('assert');

describe(`npm-package-env > `, function () {

    let env, expectedEnv;

    before(function init() {
        expectedEnv = require('../package.json');
    });

    describe(`requiring the module,`, function () {

        beforeEach(function init() {
            env = require('../lib/npm-package-env');
        });

        it(`should return an instance`, function () {
            assert.ok(env);
        });

        it(`should return a new instance of the same type on another invocation`, function () {
            let required = require('../lib/npm-package-env');
            assert.ok(required);
            assert.equal(typeof required, typeof env, 'disparate types!');
            assert.notStrictEqual(required, env);
        });
    });

    describe(`property access,`, function () {

        beforeEach(function init() {
            env = require('../lib/npm-package-env');
        });

        describe(`on existing value,`, function () {

            it(`should return truthy`, function () {
                assert.ok(env.version);
            });

            it(`should work with both dot and bracket notation`, function () {
                assert.ok(env.version);
                assert.ok(env['version']);
            });

            it(`should be reflectable`, function () {
                assert.ok(Reflect.has({'npm-package-env': 'wat'}, env.name));
            });

            describe(`on multiple invocations of the same instance,`, function () {

                it(`should return the same result`, function () {
                    assert.equal(env.name, expectedEnv.name);
                    assert.equal(env.name, expectedEnv.name);
                });

                it(`should return the same result after assigning the chained proxy`, function () {
                    let data = env.config['wrap-obj'];
                    let expected = expectedEnv.config['wrap-obj'].foo;
                    assert.equal(data.foo, expected);
                    assert.equal(data.foo, expected);
                });

                it(`should return the same result after assigning the chained proxy (deep access)`, function () {
                    let data = env.config['wrap-obj'];
                    let expected = expectedEnv.config['wrap-obj'].obj.foo;
                    assert.equal(data.obj.foo, expected);
                    assert.equal(data.obj.foo, expected);
                });

                it(`should keep having the expected values after accessing another namespace`, function () {
                    env.config['wrap-obj'].foo;
                    assert.equal(env.version, expectedEnv.version);
                });
            });

            it(`should not interfere with other instances' accessor calls`, function () {
                let conf1 = env.config;
                let conf2 = require('../lib/npm-package-env').config;
                conf1.foo;
                let expected = conf2.foo;
                let actual = expectedEnv.config.foo;
                assert.strictEqual(actual, expected);
            });

            it(`should return the property value as string`, function () {
                let expected = expectedEnv.config.foo;
                let actual = env.config.foo;
                assert.ok(typeof actual === 'string');
                assert.strictEqual(actual, expected);
            });

            describe(`inside an array,`, function () {

                it(`should return the property value as string`, function () {
                    let expected = expectedEnv.config['wrap-obj'].arr[1];
                    let actual = env.config['wrap-obj'].arr[1];
                    assert.ok(typeof actual === 'string');
                    assert.strictEqual(actual, expected);
                });
            });

            describe(`inside an object,`, function () {

                it(`should return the property value as string`, function () {
                    let expected = expectedEnv.config['wrap-obj'].obj.foo;
                    let actual = env.config['wrap-obj'].obj.foo;
                    assert.ok(typeof actual === 'string');
                    assert.strictEqual(actual, expected);
                });
            });
        });

        describe(`on non-existing value,`, function () {

            it(`should return truthy`, function () {
                assert.ok(env.watwatwat);
            });

            it(`should return a similar instance`, function () {
                assert.notStrictEqual(env.watwatwat, env);
            });

            it(`should work with both dot and bracket notation`, function () {
                assert.ok(env.watwatwat);
                assert.ok(env['watwatwat']);
            });
        });
    });

    describe(`property write,`, function () {

        beforeEach(function init() {
            env = require('../lib/npm-package-env');
        });

        describe(`on existing value,`, function () {

            beforeEach(function init() {
                env.config.foo = expectedEnv.config.foo;
            });

            it(`should set a new value`, function () {
                let original = env.config.foo;
                env.config.foo = 'lol';
                let updated = env.config.foo;
                assert.notEqual(updated, original);
            });

            it(`should not fail on a falsish value`, function () {
                let setter = () => env.config.foo = 0;
                assert.doesNotThrow(setter, TypeError);
            });

            it(`should set a new value even if its falsish`, function () {
                let original = env.config.foo;
                env.config.foo = 0;
                let updated = env.config.foo;
                assert.notEqual(updated, original);
            });

            describe(`when the value is not a string,`, function () {

                it(`should coerce the value to a string`, function () {
                    env.config.foo = 1;
                    let coerced = env.config.foo;
                    assert(typeof coerced === 'string');
                });

                it(`should coerce the value to a string even if it does not exist`, function () {
                    env.lalala = 1;
                    let coerced = env.lalala;
                    assert(typeof coerced === 'string');
                });

                it(`should coerce the value to a string even if it does not exist (deep access)`, function () {
                    env.config.lalala = 1;
                    let coerced = env.config.lalala;
                    assert(typeof coerced === 'string');
                });
            });

            describe(`inside an array,`, function () {

                beforeEach(function init() {
                    env.config['wrap-obj'].arr[1] = expectedEnv.config['wrap-obj'].arr[1];
                });

                it(`should set a new value`, function () {
                    let original = env.config['wrap-obj'].arr[1];
                    env.config['wrap-obj'].arr[1] = 'lol';
                    let updated = env.config['wrap-obj'].arr[1];
                    assert.notEqual(updated, original);
                });
            });

            describe(`inside an object,`, function () {

                beforeEach(function init() {
                    env.config['wrap-obj'].obj.foo = expectedEnv.config['wrap-obj'].obj.foo;
                });

                it(`should set a new value`, function () {
                    let original = env.config['wrap-obj'].obj.foo;
                    env.config['wrap-obj'].obj.foo = 'lol';
                    let updated = env.config['wrap-obj'].obj.foo;
                    assert.notEqual(updated, original);
                });
            });

            describe(`on multiple invocations of the same instance,`, function () {

                it(`should set a new value`, function () {
                    let original = env.config.foo;
                    env.config.foo = 'lol';
                    env.config.foo = 'lol';
                    let updated = env.config.foo;
                    assert.notEqual(updated, original);
                });

                it(`should set the last value assigned`, function () {
                    env.config.foo = 'wat';
                    env.config.foo = 'lol';
                    let last = env.config.foo;
                    assert.equal(last, 'lol');
                });
            });
        });

        describe(`on non-existing value,`, function () {

            it(`should set a new value`, function () {
                let original = env.config['wrap-obj'].obj.watwatwat;
                env.config['wrap-obj'].obj.watwatwat = 'lol';
                let updated = env.config['wrap-obj'].obj.watwatwat;
                assert.notEqual(updated, original);
            });
        });
    });

    xdescribe(`property removal,`, function () {

        it(`should delete the property value`, function () {
            let original = env.config['wrap-obj'].obj.watwatwat;
            env.config['wrap-obj'].obj.watwatwat = 'lol';
            let updated = env.config['wrap-obj'].obj.watwatwat;
            assert.notEqual(updated, original);
        });
    });
});
                    <|endoftext|>


<commit_before>var Promise = require('promise');

var RDF = require('../includes/Erics_RDF.js');
var N3 = require('n3');
var N3Util = N3.Util;

exports.parseData = function parseData(dataText) {
    return parseWithN3(dataText);
};

function parseNode(text, prefixes) {

    if (prefixes && N3Util.isPrefixedName(text)) {
        text = N3Util.expandPrefixedName(text, prefixes);
    }

    if (N3Util.isLiteral(text)) {
        return RDF.RDFLiteral(
            N3Util.getLiteralValue(text),
            RDF.LangTag(N3Util.getLiteralLanguage(text)),
            RDF.IRI(N3Util.getLiteralType(text))
        );
    }
    else if (N3Util.isIRI(text)) {
        return RDF.IRI(text);
    }
    else if (N3Util.isBlank(text)) {
        return RDF.BNode(text);
    }
    throw new Error("Unknown Type of Node");
}

exports.parseNode = parseNode;

function parseWithN3(dataText) {
    var parser = N3.Parser();

    return new Promise(function (resolve, reject) {
        var resolver = RDF.createIRIResolver();
        var db = RDF.Dataset();

        parser.parse(dataText, function (error, N3triple, prefixes) {
            if (error) reject(parseN3Error(error));
            else if (N3triple) {
                var triple = RDF.Triple(
                    parseNode(N3triple.subject),
                    parseNode(N3triple.predicate),
                    parseNode(N3triple.object)
                );

                triple.line = N3triple.line;

                db.push(triple);
            }
            else {
                resolver.Prefixes = prefixes;
                resolve({db: db, resolver: resolver, resources: db.uniqueSubjects(), triples:db.triples});
            }
        });
    });
}

function parseN3Error(error) {
    var line = error.message.match(/line [0-9]*/g);

    line = (line && line.length > 0 && line[0].length > 5)?Number(line[0].substr(5)):null;

    return {
        message: error.message,
        line: line,
        column: 0
    }
}
<commit_msg>support for blank subjects<commit_after>var Promise = require('promise');

var RDF = require('../includes/Erics_RDF.js');
var N3 = require('n3');
var N3Util = N3.Util;

exports.parseData = function parseData(dataText) {
    return parseWithN3(dataText);
};

function parseNode(text, prefixes) {

    if (prefixes && N3Util.isPrefixedName(text)) {
        text = N3Util.expandPrefixedName(text, prefixes);
    }

    if (N3Util.isLiteral(text)) {
        return RDF.RDFLiteral(
            N3Util.getLiteralValue(text),
            RDF.LangTag(N3Util.getLiteralLanguage(text)),
            RDF.IRI(N3Util.getLiteralType(text))
        );
    }
    else if (N3Util.isIRI(text) || text === "") {
        return RDF.IRI(text);
    }
    else if (N3Util.isBlank(text)) {
        return RDF.BNode(text);
    }
    throw new Error("Unknown Type of Node");
}

exports.parseNode = parseNode;

function parseWithN3(dataText) {
    var parser = N3.Parser();

    return new Promise(function (resolve, reject) {
        var resolver = RDF.createIRIResolver();
        var db = RDF.Dataset();

        parser.parse(dataText, function (error, N3triple, prefixes) {
            if (error) reject(parseN3Error(error));
            else if (N3triple) {
                var triple = RDF.Triple(
                    parseNode(N3triple.subject),
                    parseNode(N3triple.predicate),
                    parseNode(N3triple.object)
                );

                triple.line = N3triple.line;

                db.push(triple);
            }
            else {
                resolver.Prefixes = prefixes;
                resolve({db: db, resolver: resolver, resources: db.uniqueSubjects(), triples:db.triples});
            }
        });
    });
}

function parseN3Error(error) {
    var line = error.message.match(/line [0-9]*/g);

    line = (line && line.length > 0 && line[0].length > 5)?Number(line[0].substr(5)):null;

    return {
        message: error.message,
        line: line,
        column: 0
    }
}
<|endoftext|>


<commit_before>const chai = require('chai'),
  assert = chai.assert,
  expect = chai.expect;

const Hex = require('../src/hex');

const { Board, Unit, Game } = require('../src/model');
const pathfind = require('../src/pathfind');

function parse_map_array(map_array) {
  //map_array = [
  // ". @ .",
  //  ". # .",
  // ". X ."
  //];

  var board = new Board((map_array[0].length+1) / 2, map_array.length);
  var start = null;
  var finish = null;
  var pivot = null;
  var members = [];

  for (var y=0; y<board.height; y++) {
    for (var x=0; x<board.width; x++) {

      const cell = map_array[y].charAt(x * 2);
      if (cell == '.') {
        // noop
      } else if (cell == '#') {
        board.fill(x, y);
      } else if (cell == '@') {
        start = { x: x, y: y };
        pivot = start;
        members.push(start);
      } else if (cell == '+') {
        start = { x: x, y: y };
        pivot = start;
      } else if (cell == '*') {
        members.push({ x: x, y: y });
      } else if (cell == 'X') {
        finish = { x: x, y: y };
      } else {
        throw Error('Bad map at ' + x + ',' + y);
      }
    }
  }

  var unit = null;
  if (pivot && members) {
    unit = new Unit(pivot, members);
  }
  //return {
  //  board: board,
  //  start: start,
  //  finish: finish
  //  unit: unit;
  //}
  return [board, start, finish, unit]
}

describe('A* test', () => {
  it('should find a path', () => {
    const map_array = [
      ". @ .",
       ". # .",
      ". X ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    //console.log(path.commands);
    expect(path.status).to.equal('success');
    expect(path.commands).to.deep.equal(['SW', 'SE']);
    expect(path.cost).to.equal(2);
  });

  it('should fail with no path', () => {
    const map_array = [
      ". @ .",
       "# # #",
      ". X ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    expect(path.status).to.equal('noPath');
  });

  it('should find a path when needs to turn to squeeze', () => {
    const map_array = [
      ". @ *",
       "# . #",
      ". X .",
       ". . ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    expect(path.status).to.equal('success');
    expect(path.commands).to.deep.equal(['CW', 'SE', 'SW']);
    expect(path.cost).to.equal(3);
  });

  it('should find a path with pivot outside of the glass', () => {
    const map_array = [
      "+ . * .",
       ". # # #",
      ". X . ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    expect(path.status).to.equal('success');
    expect(path.commands).to.deep.equal(['W', 'SW', 'SE', 'E', 'E']);
    expect(path.cost).to.equal(5);
  });

  it('should find a path rotating different ways', () => {
    const map_array = [
      "* + * .",
       ". . . .",
      "# # . #",
       "# # . #",
      ". . . .",
       ". . . .",
      ". . . .",
       ". # . #",
      ". # . #",
       ". X . #"
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    expect(path.status).to.equal('success');
    expect(path.commands).to.deep.equal(['SE', 'CW', 'SE', 'SE', 'SE', 'SW', 'SW', 'CCW', 'SW', 'SW', 'SE']);
    expect(path.cost).to.equal(11);
  });

  it('should find a path on a harder map', () => {
    const map_array = [
      ". @ . . . . .",
       ". . . . . . .",
      ". . . . . . .",
       "# # # # # . .",
      ". . . . . # .",
       ". . . X . . .",
      ". . . . . . .",
       ". . . . . . ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    //console.log(path.commands);
    expect(path.status).to.equal('success');
    expect(path.cost).to.equal(10);
  });

  it('should have some rollercoaster', () => {
    const map_array = [
      ". @ . . . . .",
       ". # # # # # #",
      ". . . . . . .",
       "# # # # # # .",
      ". # . # . . .",
       ". . . . # . .",
      ". # # # # # .",
       ". . . . X # #"
    ];

    const [board, start, finish] = parse_map_array(map_array);
    const unit = new Unit(start, [start]);
    const path = pathfind(board, unit, start, finish);

    //console.log(path.commands);
    expect(path.status).to.equal('success');
    expect(path.cost).to.equal(21);
  });

  it('should return correct path for empty map (regression: problem_0)', () => {
    const map_array = [
      ". . . . @ . . . . .",
       ". . . . . . . . . .",
      ". . . . . . . . . .",
       ". . . . . . . . . .",
      ". . . . . . . . . .",
       ". . . . . . . . . .",
      ". . . . . . . . . .",
       ". . . . . . . . . .",
      ". . . . . . . . . .",
       ". . . . . . . . . X"
    ];
    const [board, start, finish] = parse_map_array(map_array);
    const unit = new Unit(start, [start]);
    const path = pathfind(board, unit, start, finish);

    // for (var i = 0; i < 10; i++) {
    //   var line = i % 2 ? ' ' : '';
    //   for (var j = 0; j < 10; j++) {
    //     let pp = path.path.filter(p => {
    //       return p.x == j && p.y == i;
    //     });
    //     const isOnPath = pp.length > 0;
    //     line = line + ' ' + (isOnPath ? '*' : '.');
    //   };
    //   console.log(line);
    // };
    expect(path.commands.indexOf('E')).to.equal(path.commands.lastIndexOf('E'));
    // expect(path.commands).to.deep.equal([ 'SE', 'SE', 'SE', 'SE', 'SE', 'SE', 'SE', 'SE', 'SE', 'E' ]);
  });

  it('should close path', () => {
    const map_array = [
      ". @ . . . . .",
       ". . . . . . .",
      ". . . . . . .",
       "# X . . . . .",
      "# # . . . . .",
       "# # . . . . .",
      "# # # . . . .",
       "# # # . . . ."
    ];
    const [board, start, finish] = parse_map_array(map_array);
    const unit = new Unit(start, [start]);
    const path = pathfind(board, unit, start, finish, 'close');

    console.log(path.commands);
    expect(path.commands).to.deep.equal([ 'SE', 'SW', 'SE', 'W' ]);
    expect(path.status).to.equal('success');
  })
});
<commit_msg>no console log<commit_after>const chai = require('chai'),
  assert = chai.assert,
  expect = chai.expect;

const Hex = require('../src/hex');

const { Board, Unit, Game } = require('../src/model');
const pathfind = require('../src/pathfind');

function parse_map_array(map_array) {
  //map_array = [
  // ". @ .",
  //  ". # .",
  // ". X ."
  //];

  var board = new Board((map_array[0].length+1) / 2, map_array.length);
  var start = null;
  var finish = null;
  var pivot = null;
  var members = [];

  for (var y=0; y<board.height; y++) {
    for (var x=0; x<board.width; x++) {

      const cell = map_array[y].charAt(x * 2);
      if (cell == '.') {
        // noop
      } else if (cell == '#') {
        board.fill(x, y);
      } else if (cell == '@') {
        start = { x: x, y: y };
        pivot = start;
        members.push(start);
      } else if (cell == '+') {
        start = { x: x, y: y };
        pivot = start;
      } else if (cell == '*') {
        members.push({ x: x, y: y });
      } else if (cell == 'X') {
        finish = { x: x, y: y };
      } else {
        throw Error('Bad map at ' + x + ',' + y);
      }
    }
  }

  var unit = null;
  if (pivot && members) {
    unit = new Unit(pivot, members);
  }
  //return {
  //  board: board,
  //  start: start,
  //  finish: finish
  //  unit: unit;
  //}
  return [board, start, finish, unit]
}

describe('A* test', () => {
  it('should find a path', () => {
    const map_array = [
      ". @ .",
       ". # .",
      ". X ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    //console.log(path.commands);
    expect(path.status).to.equal('success');
    expect(path.commands).to.deep.equal(['SW', 'SE']);
    expect(path.cost).to.equal(2);
  });

  it('should fail with no path', () => {
    const map_array = [
      ". @ .",
       "# # #",
      ". X ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    expect(path.status).to.equal('noPath');
  });

  it('should find a path when needs to turn to squeeze', () => {
    const map_array = [
      ". @ *",
       "# . #",
      ". X .",
       ". . ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    expect(path.status).to.equal('success');
    expect(path.commands).to.deep.equal(['CW', 'SE', 'SW']);
    expect(path.cost).to.equal(3);
  });

  it('should find a path with pivot outside of the glass', () => {
    const map_array = [
      "+ . * .",
       ". # # #",
      ". X . ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    expect(path.status).to.equal('success');
    expect(path.commands).to.deep.equal(['W', 'SW', 'SE', 'E', 'E']);
    expect(path.cost).to.equal(5);
  });

  it('should find a path rotating different ways', () => {
    const map_array = [
      "* + * .",
       ". . . .",
      "# # . #",
       "# # . #",
      ". . . .",
       ". . . .",
      ". . . .",
       ". # . #",
      ". # . #",
       ". X . #"
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    expect(path.status).to.equal('success');
    expect(path.commands).to.deep.equal(['SE', 'CW', 'SE', 'SE', 'SE', 'SW', 'SW', 'CCW', 'SW', 'SW', 'SE']);
    expect(path.cost).to.equal(11);
  });

  it('should find a path on a harder map', () => {
    const map_array = [
      ". @ . . . . .",
       ". . . . . . .",
      ". . . . . . .",
       "# # # # # . .",
      ". . . . . # .",
       ". . . X . . .",
      ". . . . . . .",
       ". . . . . . ."
    ];

    const [board, start, finish, unit] = parse_map_array(map_array);
    const path = pathfind(board, unit, start, finish);

    //console.log(path.commands);
    expect(path.status).to.equal('success');
    expect(path.cost).to.equal(10);
  });

  it('should have some rollercoaster', () => {
    const map_array = [
      ". @ . . . . .",
       ". # # # # # #",
      ". . . . . . .",
       "# # # # # # .",
      ". # . # . . .",
       ". . . . # . .",
      ". # # # # # .",
       ". . . . X # #"
    ];

    const [board, start, finish] = parse_map_array(map_array);
    const unit = new Unit(start, [start]);
    const path = pathfind(board, unit, start, finish);

    //console.log(path.commands);
    expect(path.status).to.equal('success');
    expect(path.cost).to.equal(21);
  });

  it('should return correct path for empty map (regression: problem_0)', () => {
    const map_array = [
      ". . . . @ . . . . .",
       ". . . . . . . . . .",
      ". . . . . . . . . .",
       ". . . . . . . . . .",
      ". . . . . . . . . .",
       ". . . . . . . . . .",
      ". . . . . . . . . .",
       ". . . . . . . . . .",
      ". . . . . . . . . .",
       ". . . . . . . . . X"
    ];
    const [board, start, finish] = parse_map_array(map_array);
    const unit = new Unit(start, [start]);
    const path = pathfind(board, unit, start, finish);

    // for (var i = 0; i < 10; i++) {
    //   var line = i % 2 ? ' ' : '';
    //   for (var j = 0; j < 10; j++) {
    //     let pp = path.path.filter(p => {
    //       return p.x == j && p.y == i;
    //     });
    //     const isOnPath = pp.length > 0;
    //     line = line + ' ' + (isOnPath ? '*' : '.');
    //   };
    //   console.log(line);
    // };
    expect(path.commands.indexOf('E')).to.equal(path.commands.lastIndexOf('E'));
    // expect(path.commands).to.deep.equal([ 'SE', 'SE', 'SE', 'SE', 'SE', 'SE', 'SE', 'SE', 'SE', 'E' ]);
  });

  it('should close path', () => {
    const map_array = [
      ". @ . . . . .",
       ". . . . . . .",
      ". . . . . . .",
       "# X . . . . .",
      "# # . . . . .",
       "# # . . . . .",
      "# # # . . . .",
       "# # # . . . ."
    ];
    const [board, start, finish] = parse_map_array(map_array);
    const unit = new Unit(start, [start]);
    const path = pathfind(board, unit, start, finish, 'close');

    expect(path.commands).to.deep.equal([ 'SE', 'SW', 'SE', 'W' ]);
    expect(path.status).to.equal('success');
  })
});
<|endoftext|>


<commit_before>import _ from 'lodash';
import moment from 'moment';
import scriptjs from './libs/script.js';

export class GoogleCalendarDatasource {

  constructor(instanceSettings, $q, templateSrv) {
    this.type = instanceSettings.type;
    this.name = instanceSettings.name;
    this.clientId = instanceSettings.jsonData.clientId;
    this.scopes = 'https://www.googleapis.com/auth/calendar.readonly';
    this.discoveryDocs = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
    this.q = $q;
    this.templateSrv = templateSrv;
    this.initialized = false;
  }

  load() {
    let deferred = this.q.defer();
    scriptjs('https://apis.google.com/js/api.js', () => {
      gapi.load('client:auth2', () => {
        return deferred.resolve();
      });
    });
    return deferred.promise;
  }

  testDatasource() {
    return this.initialize().then(() => {
      return { status: 'success', message: 'Data source is working', title: 'Success' };
    }).catch(err => {
      console.log(err);
      return { status: "error", message: err.message, title: "Error" };
    });
  }

  initialize() {
    if (this.initialized) {
      return Promise.resolve(gapi.auth2.getAuthInstance().currentUser.get());
    }

    return this.load().then(() => {
      return gapi.client.init({
        clientId: this.clientId,
        scope: this.scopes,
        discoveryDocs: this.discoveryDocs
      }).then(() => {
        let authInstance = gapi.auth2.getAuthInstance();
        if (!authInstance) {
          throw { message: 'failed to initialize' };
        }
        let isSignedIn = authInstance.isSignedIn.get();
        if (isSignedIn) {
          this.initialized = true;
          return authInstance.currentUser.get();
        }
        return authInstance.signIn().then(user => {
          this.initialized = true;
          return user;
        });
      }, err => {
        console.log(err);
        throw { message: 'failed to initialize' };
      });
    });
  }

  annotationQuery(options) {
    var annotation = options.annotation;
    var calendarId = annotation.calendarId;

    if (_.isEmpty(calendarId)) {
      return this.q.when([]);
    }

    return this.initialize().then(() => {
      return gapi.client.calendar.events.list({
        'calendarId': calendarId,
        'timeMin': options.range.from.toISOString(),
        'timeMax': options.range.to.toISOString(),
        'showDeleted': false,
        'singleEvents': true,
        'maxResults': 250,
        'orderBy': 'startTime'
      }).then((response) => {
        var events = response.result.items;

        var result = _.chain(events)
          .map((event) => {
            var start = moment(event.start.dateTime || event.start.date);
            var end = moment(event.end.dateTime || event.end.date);

            return [
              {
		regionId: event.id,
                annotation: annotation,
                time: start.valueOf(),
                title: event.summary,
                tags: ['Google Calender', event.organizer.displayName],
                text: event.description ? event.description:"",
              },
              {
		regionId: event.id,
                annotation: annotation,
                time: end.valueOf(),
                title: event.summary,
                tags: ['Google Calendar', event.organizer.displayName],
                text: event.description ? event.description:"",
              }
            ];
          }).flatten().value();

        return result;
      });
    });
  }
}
<commit_msg>cosmetic change<commit_after>import _ from 'lodash';
import moment from 'moment';
import scriptjs from './libs/script.js';

export class GoogleCalendarDatasource {

  constructor(instanceSettings, $q, templateSrv) {
    this.type = instanceSettings.type;
    this.name = instanceSettings.name;
    this.clientId = instanceSettings.jsonData.clientId;
    this.scopes = 'https://www.googleapis.com/auth/calendar.readonly';
    this.discoveryDocs = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
    this.q = $q;
    this.templateSrv = templateSrv;
    this.initialized = false;
  }

  load() {
    let deferred = this.q.defer();
    scriptjs('https://apis.google.com/js/api.js', () => {
      gapi.load('client:auth2', () => {
        return deferred.resolve();
      });
    });
    return deferred.promise;
  }

  testDatasource() {
    return this.initialize().then(() => {
      return { status: 'success', message: 'Data source is working', title: 'Success' };
    }).catch(err => {
      console.log(err);
      return { status: "error", message: err.message, title: "Error" };
    });
  }

  initialize() {
    if (this.initialized) {
      return Promise.resolve(gapi.auth2.getAuthInstance().currentUser.get());
    }

    return this.load().then(() => {
      return gapi.client.init({
        clientId: this.clientId,
        scope: this.scopes,
        discoveryDocs: this.discoveryDocs
      }).then(() => {
        let authInstance = gapi.auth2.getAuthInstance();
        if (!authInstance) {
          throw { message: 'failed to initialize' };
        }
        let isSignedIn = authInstance.isSignedIn.get();
        if (isSignedIn) {
          this.initialized = true;
          return authInstance.currentUser.get();
        }
        return authInstance.signIn().then(user => {
          this.initialized = true;
          return user;
        });
      }, err => {
        console.log(err);
        throw { message: 'failed to initialize' };
      });
    });
  }

  annotationQuery(options) {
    var annotation = options.annotation;
    var calendarId = annotation.calendarId;

    if (_.isEmpty(calendarId)) {
      return this.q.when([]);
    }

    return this.initialize().then(() => {
      return gapi.client.calendar.events.list({
        'calendarId': calendarId,
        'timeMin': options.range.from.toISOString(),
        'timeMax': options.range.to.toISOString(),
        'showDeleted': false,
        'singleEvents': true,
        'maxResults': 250,
        'orderBy': 'startTime'
      }).then((response) => {
        var events = response.result.items;

        var result = _.chain(events)
          .map((event) => {
            var start = moment(event.start.dateTime || event.start.date);
            var end = moment(event.end.dateTime || event.end.date);

            return [
              {
                regionId: event.id,
                annotation: annotation,
                time: start.valueOf(),
                title: event.summary,
                tags: ['Google Calender', event.organizer.displayName],
                text: event.description ? event.description : "",
              },
              {
                regionId: event.id,
                annotation: annotation,
                time: end.valueOf(),
                title: event.summary,
                tags: ['Google Calendar', event.organizer.displayName],
                text: event.description ? event.description : "",
              }
            ];
          }).flatten().value();

        return result;
      });
    });
  }
}
<|endoftext|>


<commit_before>import bind from 'lodash.bind'
import isArray from 'lodash.isarray'
import isFunction from 'lodash.isfunction'

import {
  isPromise,
  noop,
  pFinally
} from './utils'

// ===================================================================

const {
  defineProperties,
  defineProperty,
  getOwnPropertyDescriptor
} = Object

// ===================================================================

// See: https://github.com/jayphelps/core-decorators.js#autobind
//
// TODO: make it work for all class methods.
export const autobind = (target, key, {
  configurable,
  enumerable,
  value: fn,
  writable
}) => ({
  configurable,
  enumerable,

  get () {
    const bounded = bind(fn, this)

    defineProperty(this, key, {
      configurable: true,
      enumerable: false,
      value: bounded,
      writable: true
    })

    return bounded
  },
  set (newValue) {
    if (this === target) {
      // New value directly set on the prototype.
      delete this[key]
      this[key] = newValue
    } else {
      // New value set on a child object.

      // Cannot use assignment because it will call the setter on
      // the prototype.
      defineProperty(this, key, {
        configurable: true,
        enumerable: true,
        value: newValue,
        writable: true
      })
    }
  }
})

// -------------------------------------------------------------------

// Debounce decorator for methods.
//
// See: https://github.com/wycats/javascript-decorators
//
// TODO: make it work for single functions.
export const debounce = duration => (target, name, descriptor) => {
  const fn = descriptor.value

  // This symbol is used to store the related data directly on the
  // current object.
  const s = Symbol()

  function debounced () {
    const data = this[s] || (this[s] = {
      lastCall: 0,
      wrapper: null
    })

    const now = Date.now()
    if (now > data.lastCall + duration) {
      data.lastCall = now
      try {
        const result = fn.apply(this, arguments)
        data.wrapper = () => result
      } catch (error) {
        data.wrapper = () => { throw error }
      }
    }
    return data.wrapper()
  }
  debounced.reset = obj => { delete obj[s] }

  descriptor.value = debounced
  return descriptor
}

// -------------------------------------------------------------------

const _push = Array.prototype.push

export const deferrable = (target, name, descriptor) => {
  let fn
  function newFn () {
    const deferreds = []
    const defer = fn => {
      deferreds.push(fn)
    }
    defer.clear = () => {
      deferreds.length = 0
    }

    const args = [ defer ]
    _push.apply(args, arguments)

    let executeDeferreds = () => {
      let i = deferreds.length
      while (i) {
        deferreds[--i]()
      }
    }

    try {
      const result = fn.apply(this, args)

      if (isPromise(result)) {
        result::pFinally(executeDeferreds)

        // Do not execute the deferreds in the finally block.
        executeDeferreds = noop
      }

      return result
    } finally {
      executeDeferreds()
    }
  }

  if (descriptor) {
    fn = descriptor.value
    descriptor.value = newFn

    return descriptor
  }

  fn = target
  return newFn
}

// Deferred functions are only executed on failures.
//
// i.e.: defer.clear() is automatically called in case of success.
deferrable.onFailure = (target, name, descriptor) => {
  let fn
  function newFn (defer) {
    const result = fn.apply(this, arguments)

    return isPromise(result)
      ? result.then(result => {
        defer.clear()
        return result
      })
      : (defer.clear(), result)
  }

  if (descriptor) {
    fn = descriptor.value
    descriptor.value = newFn
  } else {
    fn = target
    target = newFn
  }

  return deferrable(target, name, descriptor)
}

// Deferred functions are only executed on success.
//
// i.e.: defer.clear() is automatically called in case of failure.
deferrable.onSuccess = (target, name, descriptor) => {
  let fn
  function newFn (defer) {
    try {
      const result = fn.apply(this, arguments)

      return isPromise(result)
        ? result.then(null, error => {
          defer.clear()
          throw error
        })
        : result
    } catch (error) {
      defer.clear()
      throw error
    }
  }

  if (descriptor) {
    fn = descriptor.value
    descriptor.value = newFn
  } else {
    fn = target
    target = newFn
  }

  return deferrable(target, name, descriptor)
}

// -------------------------------------------------------------------

const _ownKeys = (
  typeof Reflect !== 'undefined' && Reflect.ownKeys ||
  (({
    getOwnPropertyNames: names,
    getOwnPropertySymbols: symbols
  }) => symbols
    ? obj => names(obj).concat(symbols(obj))
    : names
  )(Object)
)

const _bindPropertyDescriptor = (descriptor, thisArg) => {
  const { get, set, value } = descriptor
  if (get) {
    descriptor.get = bind(get, thisArg)
  }
  if (set) {
    descriptor.set = bind(set, thisArg)
  }

  if (isFunction(value)) {
    descriptor.value = bind(value, thisArg)
  }

  return descriptor
}

const _isIgnoredProperty = name => (
  name[0] === '_' ||
  name === 'constructor'
)

const _isIgnoredStaticProperty = name => (
  name === 'length' ||
  name === 'name' ||
  name === 'prototype'
)

export const mixin = MixIns => Class => {
  if (!isArray(MixIns)) {
    MixIns = [ MixIns ]
  }

  const { name } = Class

  const Decorator = (...args) => {
    const instance = new Class(...args)

    for (const MixIn of MixIns) {
      const { prototype } = MixIn
      const mixinInstance = new MixIn(instance)
      const descriptors = { __proto__: null }
      for (const prop of _ownKeys(prototype)) {
        if (_isIgnoredProperty(prop)) {
          continue
        }

        if (prop in instance) {
          throw new Error(`${name}#${prop} is already defined`)
        }

        descriptors[prop] = _bindPropertyDescriptor(
          getOwnPropertyDescriptor(prototype, prop),
          mixinInstance
        )
      }
      defineProperties(instance, descriptors)
    }

    return instance
  }

  // Copy original and mixed-in static properties on Decorator class.
  const descriptors = { __proto__: null }
  for (const prop of _ownKeys(Class)) {
    descriptors[prop] = getOwnPropertyDescriptor(Class, prop)
  }
  for (const MixIn of MixIns) {
    for (const prop of _ownKeys(MixIn)) {
      if (_isIgnoredStaticProperty(prop)) {
        continue
      }

      if (prop in descriptors) {
        throw new Error(`${name}.${prop} is already defined`)
      }

      descriptors[prop] = getOwnPropertyDescriptor(MixIn, prop)
    }
  }
  defineProperties(Decorator, descriptors)

  return Decorator
}
<commit_msg>@mixin(): compatibility with Node 0.12 (fix #202).<commit_after>import bind from 'lodash.bind'
import isArray from 'lodash.isarray'
import isFunction from 'lodash.isfunction'

import {
  isPromise,
  noop,
  pFinally
} from './utils'

// ===================================================================

const {
  defineProperties,
  defineProperty,
  getOwnPropertyDescriptor
} = Object

// ===================================================================

// See: https://github.com/jayphelps/core-decorators.js#autobind
//
// TODO: make it work for all class methods.
export const autobind = (target, key, {
  configurable,
  enumerable,
  value: fn,
  writable
}) => ({
  configurable,
  enumerable,

  get () {
    const bounded = bind(fn, this)

    defineProperty(this, key, {
      configurable: true,
      enumerable: false,
      value: bounded,
      writable: true
    })

    return bounded
  },
  set (newValue) {
    if (this === target) {
      // New value directly set on the prototype.
      delete this[key]
      this[key] = newValue
    } else {
      // New value set on a child object.

      // Cannot use assignment because it will call the setter on
      // the prototype.
      defineProperty(this, key, {
        configurable: true,
        enumerable: true,
        value: newValue,
        writable: true
      })
    }
  }
})

// -------------------------------------------------------------------

// Debounce decorator for methods.
//
// See: https://github.com/wycats/javascript-decorators
//
// TODO: make it work for single functions.
export const debounce = duration => (target, name, descriptor) => {
  const fn = descriptor.value

  // This symbol is used to store the related data directly on the
  // current object.
  const s = Symbol()

  function debounced () {
    const data = this[s] || (this[s] = {
      lastCall: 0,
      wrapper: null
    })

    const now = Date.now()
    if (now > data.lastCall + duration) {
      data.lastCall = now
      try {
        const result = fn.apply(this, arguments)
        data.wrapper = () => result
      } catch (error) {
        data.wrapper = () => { throw error }
      }
    }
    return data.wrapper()
  }
  debounced.reset = obj => { delete obj[s] }

  descriptor.value = debounced
  return descriptor
}

// -------------------------------------------------------------------

const _push = Array.prototype.push

export const deferrable = (target, name, descriptor) => {
  let fn
  function newFn () {
    const deferreds = []
    const defer = fn => {
      deferreds.push(fn)
    }
    defer.clear = () => {
      deferreds.length = 0
    }

    const args = [ defer ]
    _push.apply(args, arguments)

    let executeDeferreds = () => {
      let i = deferreds.length
      while (i) {
        deferreds[--i]()
      }
    }

    try {
      const result = fn.apply(this, args)

      if (isPromise(result)) {
        result::pFinally(executeDeferreds)

        // Do not execute the deferreds in the finally block.
        executeDeferreds = noop
      }

      return result
    } finally {
      executeDeferreds()
    }
  }

  if (descriptor) {
    fn = descriptor.value
    descriptor.value = newFn

    return descriptor
  }

  fn = target
  return newFn
}

// Deferred functions are only executed on failures.
//
// i.e.: defer.clear() is automatically called in case of success.
deferrable.onFailure = (target, name, descriptor) => {
  let fn
  function newFn (defer) {
    const result = fn.apply(this, arguments)

    return isPromise(result)
      ? result.then(result => {
        defer.clear()
        return result
      })
      : (defer.clear(), result)
  }

  if (descriptor) {
    fn = descriptor.value
    descriptor.value = newFn
  } else {
    fn = target
    target = newFn
  }

  return deferrable(target, name, descriptor)
}

// Deferred functions are only executed on success.
//
// i.e.: defer.clear() is automatically called in case of failure.
deferrable.onSuccess = (target, name, descriptor) => {
  let fn
  function newFn (defer) {
    try {
      const result = fn.apply(this, arguments)

      return isPromise(result)
        ? result.then(null, error => {
          defer.clear()
          throw error
        })
        : result
    } catch (error) {
      defer.clear()
      throw error
    }
  }

  if (descriptor) {
    fn = descriptor.value
    descriptor.value = newFn
  } else {
    fn = target
    target = newFn
  }

  return deferrable(target, name, descriptor)
}

// -------------------------------------------------------------------

const _ownKeys = (
  typeof Reflect !== 'undefined' && Reflect.ownKeys ||
  (({
    getOwnPropertyNames: names,
    getOwnPropertySymbols: symbols
  }) => symbols
    ? obj => names(obj).concat(symbols(obj))
    : names
  )(Object)
)

const _bindPropertyDescriptor = (descriptor, thisArg) => {
  const { get, set, value } = descriptor
  if (get) {
    descriptor.get = bind(get, thisArg)
  }
  if (set) {
    descriptor.set = bind(set, thisArg)
  }

  if (isFunction(value)) {
    descriptor.value = bind(value, thisArg)
  }

  return descriptor
}

const _isIgnoredProperty = name => (
  name[0] === '_' ||
  name === 'constructor'
)

const _IGNORED_STATIC_PROPERTIES = {
  __proto__: null,

  arguments: true,
  caller: true,
  length: true,
  name: true,
  prototype: true
}
const _isIgnoredStaticProperty = name => _IGNORED_STATIC_PROPERTIES[name]

export const mixin = MixIns => Class => {
  if (!isArray(MixIns)) {
    MixIns = [ MixIns ]
  }

  const { name } = Class

  const Decorator = (...args) => {
    const instance = new Class(...args)

    for (const MixIn of MixIns) {
      const { prototype } = MixIn
      const mixinInstance = new MixIn(instance)
      const descriptors = { __proto__: null }
      for (const prop of _ownKeys(prototype)) {
        if (_isIgnoredProperty(prop)) {
          continue
        }

        if (prop in instance) {
          throw new Error(`${name}#${prop} is already defined`)
        }

        descriptors[prop] = _bindPropertyDescriptor(
          getOwnPropertyDescriptor(prototype, prop),
          mixinInstance
        )
      }
      defineProperties(instance, descriptors)
    }

    return instance
  }

  // Copy original and mixed-in static properties on Decorator class.
  const descriptors = { __proto__: null }
  for (const prop of _ownKeys(Class)) {
    let descriptor
    if (!(
      // Special properties are not defined...
      _isIgnoredStaticProperty(prop) &&

      // if they already exist...
      (descriptor = getOwnPropertyDescriptor(Decorator, prop)) &&

      // and are not configurable.
      !descriptor.configurable
    )) {
      descriptors[prop] = getOwnPropertyDescriptor(Class, prop)
    }
  }
  for (const MixIn of MixIns) {
    for (const prop of _ownKeys(MixIn)) {
      if (_isIgnoredStaticProperty(prop)) {
        continue
      }

      if (prop in descriptors) {
        throw new Error(`${name}.${prop} is already defined`)
      }

      descriptors[prop] = getOwnPropertyDescriptor(MixIn, prop)
    }
  }
  defineProperties(Decorator, descriptors)

  return Decorator
}
<|endoftext|>


<commit_before>import lodash from 'lodash';

export function listeningTo(storeNames, getterMethodName = 'getStateFromDependencies') {
    return decorator;

    function decorator(fn) {
        const originalCDM = fn.prototype.componentDidMount;
        const originalCWU = fn.prototype.componentWillUnmount;

        fn.prototype.componentDidMount = function componentWillMount() {
            if (originalCDM) {
                originalCDM.apply(this, arguments);
            }

            const stores = storeNames.map(name => this.dependencies[name]);
            const getterMethod = this[getterMethodName];

            this._setStateFromStores = () => {
                this.setState(getterMethod.call(this));
            };

            lodash.each(stores, store => {
                store.on('change', this._setStateFromStores);
            });
        };

        fn.prototype.componentWillUnmount = function componentWillMount() {
            if (originalCWU) {
                originalCWU.apply(this, arguments);
            }

            const stores = storeNames.map(name => this.dependencies[name]);
            const getterMethod = this[getterMethodName];

            lodash.each(stores, store => {
                store.removeListener('change', this._setStateFromStores);
            });
        };
    }
}
<commit_msg>Fix bug where dependencies aren't part of the context<commit_after>import lodash from 'lodash';

export function listeningTo(storeNames, getterMethodName = 'getStateFromDependencies') {
    return decorator;

    function decorator(fn) {
        const originalCDM = fn.prototype.componentDidMount;
        const originalCWU = fn.prototype.componentWillUnmount;

        fn.prototype.componentDidMount = function componentWillMount() {
            if (originalCDM) {
                originalCDM.apply(this, arguments);
            }

            const stores = storeNames.map(name => this.context.dependencies[name]);
            const getterMethod = this[getterMethodName];

            this._setStateFromStores = () => {
                this.setState(getterMethod.call(this));
            };

            lodash.each(stores, store => {
                store.on('change', this._setStateFromStores);
            });
        };

        fn.prototype.componentWillUnmount = function componentWillMount() {
            if (originalCWU) {
                originalCWU.apply(this, arguments);
            }

            const stores = storeNames.map(name => this.context.dependencies[name]);
            const getterMethod = this[getterMethodName];

            lodash.each(stores, store => {
                store.removeListener('change', this._setStateFromStores);
            });
        };
    }
}
<|endoftext|>


<commit_before>/**
 * Improves Backbone Model support when nested attributes are used.
 * get() and set() can take paths e.g. 'user.name'
 */
;(function(Backbone) {

    /**
     * Takes a nested object and returns a shallow object keyed with the path names
     * e.g. { "level1.level2": "value" }
     *
     * @param  {Object}      Nested object e.g. { level1: { level2: 'value' } }
     * @return {Object}      Shallow object with path names e.g. { 'level1.level2': 'value' }
     */
    function objToPaths(obj) {
        var ret = {};

        for (var key in obj) {
            var val = obj[key];

            if (val && val.constructor === Object) {
                //Recursion for embedded objects
                var obj2 = objToPaths(val);

                for (var key2 in obj2) {
                    var val2 = obj2[key2];

                    ret[key+'.'+key2] = val2;
                }
            } else {
                ret[key] = val;
            }
        }

        return ret;
    }

    /**
     * @param {Object}  Object to fetch attribute from
     * @param {String}  Object path e.g. 'user.name'
     * @return {Mixed}
     */
    function getNested(obj, path) {
        var fields = path.split(".");
        var result = obj;
        for (var i = 0, n = fields.length; i < n; i++) {
            result = result[fields[i]];

            if (typeof result === 'undefined') {
                return result;
            }
        }
        return result;
    }

    /**
     * @param {Object}  Object to fetch attribute from
     * @param {String}  Object path e.g. 'user.name'
     * @param {Mixed}   Value to set
     */
    function setNested(obj, path, val) {
        var fields = path.split(".");
        var result = obj;
        for (var i = 0, n = fields.length; i < n; i++) {
            var field = fields[i];

            //If the last in the path, set the value
            if (i === n - 1) {
                result[field] = val;
            } else {
                //Create the child object if it doesn't exist
                if (typeof result[field] === 'undefined') {
                    result[field] = {};
                }

                //Move onto the next part of the path
                result = result[field];
            }
        }
    }

    var DeepModel = Backbone.Model.extend({

        // Override get
        // Supports nested attributes via the syntax 'obj.attr' e.g. 'author.user.name'
        get: function(attr) {
            return getNested(this.attributes, attr);
        },

        // Override set
        // Supports nested attributes via the syntax 'obj.attr' e.g. 'author.user.name'
        set: function(key, value, options) {
            var attrs, attr;

            if (_.isObject(key) || key == null) {
                attrs = key;
                options = value;
            } else {
                attrs = {};
                attrs[key] = value;
            }

            // Extract attributes and options.
            options || (options = {});
            if (!attrs) return this;
            if (attrs.attributes) attrs = attrs.attributes;
            if (options.unset) for (attr in attrs) attrs[attr] = void 0;
            var now = this.attributes, escaped = this._escapedAttributes;

            // Run validation.
            if (!this._validate(attrs, options)) return false;

            // Check for changes of `id`.
            if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];

            // We're about to start triggering change events.
            var alreadyChanging = this._changing;
            this._changing = true;

            //START CUSTOM CODE
            var self = this;

            this._changed = {};
            function performSet(attrs) {
                // Update attributes.
                for (var attr in attrs) {
                    var val = attrs[attr];

                    if (val && val.constructor === Object) {
                        //Recursion for nested objects
                        performSet(val);
                    } else {
                        if (_.isObject(val) || !_.isEqual(getNested(now, attr), val)) {
                            setNested(now, attr, val);
                            //deleteNested(escaped, attr); //TODO: Create this and use instead of setNested line below?
                            setNested(escaped, attr, undefined);

                            // This needs to be set for things like changedAttributes() to work
                            self._changed[attr] = val;
                        }
                    }
                }
            }

            attrs = objToPaths(attrs);

            performSet(attrs)

            //END CUSTOM CODE

            this._changing = false;
            // Fire the `"change"` event, if the model has been changed.
            if (!alreadyChanging && !options.silent && this._changed)
            {
                this.change(options);
            }
            return this;
        },

        // Override has
        has: function(attr) {
            return getNested(this.attributes, attr) != null;
        },

        // Remove an attribute from the model, firing `"change"` unless you choose
        // to silence it. `unset` is a noop if the attribute doesn't exist.

        unset : function(attr, options) {
          //if (!(attr in this.attributes)) return this;
          // New code to check if attribute exists
          if (getNested(this.attributes, attr) === undefined) return this;
          options || (options = {});

          //var value = this.attributes[attr]; //Why is this needed?

          // Run validation.
          var validObj = {};
          validObj[attr] = void 0;
          if (!this._validate(attrs, options)) return false;

          // changedAttributes needs to know if an attribute has been unset.
          (this._unsetAttributes || (this._unsetAttributes = [])).push(attr);

          // Remove the attribute.

          //Test if path
          var path = attr.split('.')
          if(path.length === 1){
            delete this.attributes[attr];
            delete this._escapedAttributes[attr];
            if (attr == this.idAttribute) delete this.id;
          } else {
            //Get parent
            var deep_property = path[path.length -1];
            var parent = (path.slice(0,(path.length-1))).join('.')
            var parent_value = getNested(this.attributes, parent);
            var escaped_value = getNested(this._escapedAttributes, parent);
            delete parent_value[deep_property];
            delete escaped_value[deep_property];
          }
          this._changed = true;
          if (!options.silent) {
            this.trigger('change:' + attr, this, void 0, options);
            this.change(options);
          }

          return this;
        }

    });

    //Exports
    Backbone.DeepModel = DeepModel;

})(Backbone);
<commit_msg>Fixed a unit test that requires setting (or unsetting) an attribute with an undefined value to fire change events.<commit_after>/**
 * Improves Backbone Model support when nested attributes are used.
 * get() and set() can take paths e.g. 'user.name'
 */
;(function(Backbone) {

    /**
     * Takes a nested object and returns a shallow object keyed with the path names
     * e.g. { "level1.level2": "value" }
     *
     * @param  {Object}      Nested object e.g. { level1: { level2: 'value' } }
     * @return {Object}      Shallow object with path names e.g. { 'level1.level2': 'value' }
     */
    function objToPaths(obj) {
        var ret = {};

        for (var key in obj) {
            var val = obj[key];

            if (val && val.constructor === Object) {
                //Recursion for embedded objects
                var obj2 = objToPaths(val);

                for (var key2 in obj2) {
                    var val2 = obj2[key2];

                    ret[key+'.'+key2] = val2;
                }
            } else {
                ret[key] = val;
            }
        }

        return ret;
    }

    /**
     * @param {Object}  Object to fetch attribute from
     * @param {String}  Object path e.g. 'user.name'
     * @return {Mixed}
     */
    function getNested(obj, path) {
        var fields = path.split(".");
        var result = obj;
        for (var i = 0, n = fields.length; i < n; i++) {
            result = result[fields[i]];

            if (typeof result === 'undefined') {
                return result;
            }
        }
        return result;
    }

    /**
     * @param {Object}  Object to fetch attribute from
     * @param {String}  Object path e.g. 'user.name'
     * @param {Mixed}   Value to set
     */
    function setNested(obj, path, val) {
        var fields = path.split(".");
        var result = obj;
        for (var i = 0, n = fields.length; i < n; i++) {
            var field = fields[i];

            //If the last in the path, set the value
            if (i === n - 1) {
                result[field] = val;
            } else {
                //Create the child object if it doesn't exist
                if (typeof result[field] === 'undefined') {
                    result[field] = {};
                }

                //Move onto the next part of the path
                result = result[field];
            }
        }
    }

    var DeepModel = Backbone.Model.extend({

        // Override get
        // Supports nested attributes via the syntax 'obj.attr' e.g. 'author.user.name'
        get: function(attr) {
            return getNested(this.attributes, attr);
        },

        // Override set
        // Supports nested attributes via the syntax 'obj.attr' e.g. 'author.user.name'
        set: function(key, value, options) {
            var attrs, attr;

            if (_.isObject(key) || key == null) {
                attrs = key;
                options = value;
            } else {
                attrs = {};
                attrs[key] = value;
            }

            // Extract attributes and options.
            options || (options = {});
            if (!attrs) return this;
            if (attrs.attributes) attrs = attrs.attributes;
            if (options.unset) for (attr in attrs) attrs[attr] = void 0;
            var now = this.attributes, escaped = this._escapedAttributes;

            // Run validation.
            if (!this._validate(attrs, options)) return false;

            // Check for changes of `id`.
            if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];

            // We're about to start triggering change events.
            var alreadyChanging = this._changing;
            this._changing = true;

            //START CUSTOM CODE
            var self = this;

            this._changed = {};
            function performSet(attrs) {
                // Update attributes.
                for (var attr in attrs) {
                    var val = attrs[attr];

                    if (val && val.constructor === Object) {
                        //Recursion for nested objects
                        performSet(val);
                    } else {
                        // It seems like this check for undefined is handled more elegantly in the parent
                        // but i'm just not seeing it. This was added to satisfy a backbone unit test that
                        // requires setting an undefined attribute to fire change events.
                        if ((getNested(now, attr) === undefined) ||
                            _.isObject(val) || !_.isEqual(getNested(now, attr), val)) {
                            setNested(now, attr, val);
                            //deleteNested(escaped, attr); //TODO: Create this and use instead of setNested line below?
                            setNested(escaped, attr, undefined);

                            // This needs to be set for things like changedAttributes() to work
                            self._changed[attr] = val;
                        }
                    }
                }
            }

            attrs = objToPaths(attrs);

            performSet(attrs)

            //END CUSTOM CODE

            this._changing = false;
            // Fire the `"change"` event, if the model has been changed.
            if (!alreadyChanging && !options.silent && this._changed)
            {
                this.change(options);
            }
            return this;
        },

        // Override has
        has: function(attr) {
            return getNested(this.attributes, attr) != null;
        },

        // Remove an attribute from the model, firing `"change"` unless you choose
        // to silence it. `unset` is a noop if the attribute doesn't exist.

        unset : function(attr, options) {
          //if (!(attr in this.attributes)) return this;
          // New code to check if attribute exists
          if (getNested(this.attributes, attr) === undefined) return this;
          options || (options = {});

          //var value = this.attributes[attr]; //Why is this needed?

          // Run validation.
          var validObj = {};
          validObj[attr] = void 0;
          if (!this._validate(attrs, options)) return false;

          // changedAttributes needs to know if an attribute has been unset.
          (this._unsetAttributes || (this._unsetAttributes = [])).push(attr);

          // Remove the attribute.

          //Test if path
          var path = attr.split('.')
          if(path.length === 1){
            delete this.attributes[attr];
            delete this._escapedAttributes[attr];
            if (attr == this.idAttribute) delete this.id;
          } else {
            //Get parent
            var deep_property = path[path.length -1];
            var parent = (path.slice(0,(path.length-1))).join('.')
            var parent_value = getNested(this.attributes, parent);
            var escaped_value = getNested(this._escapedAttributes, parent);
            delete parent_value[deep_property];
            delete escaped_value[deep_property];
          }
          this._changed = true;
          if (!options.silent) {
            this.trigger('change:' + attr, this, void 0, options);
            this.change(options);
          }

          return this;
        }

    });

    //Exports
    Backbone.DeepModel = DeepModel;

})(Backbone);
<|endoftext|>