require('babel/register'); var assert = require( 'assert' ); var Scope = require( '../src/Scope' ); describe( 'Scope', function () { it( 'can define and bind names', function () { const scope = new Scope(); // If I define 'a'... scope.define( 'a' ); // ... and bind 'b' to a reference to 'a'... scope.bind( 'b', scope.reference( 'a' ) ); // ... lookups for 'a' and 'b' should both // resolve to the same identifier. assert.equal( scope.lookup( 'b' ), scope.lookup( 'a' ) ); }); describe( 'parent:', function () { var parent = new Scope(), child = new Scope( parent ); it( 'allows children access to its names', function () { parent.define( 'a' ); assert.equal( child.lookup( 'a' ), parent.lookup( 'a' ) ); }); it( 'names in the child scope shadows the parent', function () { child.define( 'a' ); assert.notEqual( child.lookup( 'a' ), parent.lookup( 'a' ) ); child.define( 'b' ); assert.equal( parent.lookup( 'b' ), undefined ); }); }); describe( 'virtual scope:', function () { var real, a, b; beforeEach(function () { real = new Scope(); a = real.virtual(); b = real.virtual(); }); it( 'is created within another scope', function () { // The actual ids are the same. assert.equal( real.ids, a.ids ); assert.equal( real.ids, b.ids ); }); it( 'lookups different identifiers', function () { // If I define 'a' in both scopes... a.define( 'a' ); b.define( 'a' ); // ... the name 'a' should lookup different identifiers. assert.notEqual( a.lookup( 'a' ), b.lookup( 'b' ) ); }); it( 'can deconflict names', function () { a.define( 'a' ); b.define( 'a' ); // Deconflicting the actual scope should make all identifiers unique. real.deconflict(); assert.deepEqual( real.usedNames(), [ '_a', 'a' ] ); }); it( 'deconflicts with a custom function, if provided', function () { for (var i = 0; i < 26; i++) { // Create 26 scopes, all of which define 'a'. real.virtual().define( 'a' ); } // Custom deconfliction function which ignores the current name. var num = 10; real.deconflict( function () { return (num++).toString(36); }); assert.deepEqual( real.usedNames(), 'abcdefghijklmnopqrstuvwxyz'.split('') ); // Deconflicting twice has no additional effect. real.deconflict(); assert.deepEqual( real.usedNames(), 'abcdefghijklmnopqrstuvwxyz'.split('') ); }); }); it( 'dedupes-external-imports', function () { var real = new Scope(); var external = real.virtual(), locals = real.virtual(), exports = real.virtual(); external.define( 'Component' ); locals.bind( 'Comp', external.reference( 'Component' ) ); exports.bind( 'default', locals.reference( 'Foo' ) ); try { real.deconflict(); assert.ok( false, 'Scope.deconflict should throw with "Foo" undefined' ); } catch ( ignore ) { // as expected } locals.define( 'Foo' ); real.deconflict(); }); });