You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.9 KiB

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();
});
});