Skip to content

Commit

Permalink
fix: Resolve issues in environments with frozen Symbol
Browse files Browse the repository at this point in the history
- Also adds a test for frozen Symbol.
  • Loading branch information
benlesh committed Sep 1, 2020
1 parent 7a396df commit 2323882
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
14 changes: 12 additions & 2 deletions es/ponyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,18 @@ export default function symbolObservablePonyfill(root) {
if (Symbol.observable) {
result = Symbol.observable;
} else {
result = Symbol('observable');
Symbol.observable = result;

// This just needs to be something that won't trample other user's Symbol.for use
// It also will guide people to the source of their issues, if this is problematic.
// META: It's a resource locator!
result = Symbol.for('https://github.com/benlesh/symbol-observable');
try {
Symbol.observable = result;
} catch (err) {
// Do nothing. In some environments, users have frozen `Symbol` for security reasons,
// if it is frozen assigning to it will throw. In this case, we don't care, because
// they will need to use the returned value from the ponyfill.
}
}
} else {
result = '@@observable';
Expand Down
46 changes: 40 additions & 6 deletions test/ponyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,53 @@ describe('ponyfill unit tests', function () {
});

describe('and Symbol.observable does NOT exist', function () {
it('should use Symbol(), polyfill Symbol.observable and return it', function () {
var Symbol = function (description) {
return 'Symbol(' + description + ')';
it('should use Symbol.for(), polyfill Symbol.observable and return it', function () {

var FakeSymbol = createFakeSymbolImpl();
var root = {
Symbol: FakeSymbol
};

var result = ponyfill(root);

expect(FakeSymbol.observable).to.equal('@@_fakesymbol_0_https://github.com/benlesh/symbol-observable');
expect(result).to.equal('@@_fakesymbol_0_https://github.com/benlesh/symbol-observable');
});

it('should not throw if Symbol is frozen', function () {
'use strict';
var FakeSymbol = createFakeSymbolImpl();

Object.freeze(FakeSymbol);
var root = {
Symbol: Symbol
Symbol: FakeSymbol
};

// If this throws, the test fails.
var result = ponyfill(root);

expect(Symbol.observable).to.equal('Symbol(observable)');
expect(result).to.equal('Symbol(observable)');
expect(FakeSymbol.observable).not.to.equal('@@_fakesymbol_0_https://github.com/benlesh/symbol-observable');
expect(result).to.equal('@@_fakesymbol_0_https://github.com/benlesh/symbol-observable');
});
});
});
});


function createFakeSymbolImpl() {
var symbolCounter = 0;
function FakeSymbol(description) {
return '@@_fakesymbol_' + (symbolCounter++) + '_' + description;
}

var forLookup = {};

FakeSymbol.for = function (id) {
if (!forLookup[id]) {
forLookup[id] = FakeSymbol(id);
}
return forLookup[id];
};

return FakeSymbol;
}

0 comments on commit 2323882

Please sign in to comment.