Skip to content

Commit

Permalink
fix(repl): render the unjsonable things described in #2278
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed May 12, 2021
1 parent 3d9080f commit bef7d37
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 13 deletions.
22 changes: 22 additions & 0 deletions packages/vats/src/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ import { getInterfaceOf, Remotable, Far } from '@agoric/marshal';
import { Nat } from '@agoric/nat';
import makeUIAgentMakers from './ui-agent';

const UNJSONABLES = new Map([
[NaN, 'NaN'],
[Infinity, 'Infinity'],
[-Infinity, '-Infinity'],
[undefined, 'undefined'],
]);

for (const [name, { value }] of Object.entries(
Object.getOwnPropertyDescriptors(Symbol),
)) {
if (typeof value === 'symbol' && typeof name === 'string') {
UNJSONABLES.set(value, `Symbol(Symbol.${name})`);
}
}

// A REPL-specific JSON stringify.
export function stringify(
value,
Expand All @@ -17,6 +32,13 @@ export function stringify(
if (typeof value === 'bigint') {
return `${value}n`;
}
const rawString = UNJSONABLES.get(value);
if (rawString) {
return rawString;
}
if (typeof value === 'symbol') {
return `Symbol(?)`;
}
return JSON.stringify(value, null, spaces);
}

Expand Down
71 changes: 58 additions & 13 deletions packages/vats/test/test-repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,68 @@ test('repl: bigInts', async t => {
t.deepEqual(sentMessages, []);
});

// TODO(2278) The bug describes failures for Symbol, undefined, NaN, infinities
test.failing('repl: NaN', async t => {
test('repl: Symbols', async t => {
const { doEval, sentMessages } = make();

let m = sentMessages.shift();
t.deepEqual(doEval(0, 'NaN'), {});
m = sentMessages.shift();
t.deepEqual(m.type, 'updateHistory');
t.is(sentMessages.length, 1);

t.is(m.histnum, 0);
t.is(m.display, 'working on eval(NaN)');
m = sentMessages.shift();
t.is(m.type, 'updateHistory');
t.is(m.histnum, 0);
t.is(m.display, 'NaN');
t.deepEqual(sentMessages, []);
let histnum = 0;
for (const expr of ['asyncIterator', 'toStringTag', 'hasInstance'].map(
name => `Symbol.${name}`,
)) {
t.deepEqual(doEval(histnum, expr), {});
m = sentMessages.shift();
t.deepEqual(m.type, 'updateHistory');
t.is(sentMessages.length, 1);

t.is(m.histnum, histnum);
t.is(m.display, `working on eval(${expr})`);
m = sentMessages.shift();
t.is(m.type, 'updateHistory');
t.is(m.histnum, histnum);
t.is(m.display, `Symbol(${expr})`);
t.deepEqual(sentMessages, []);
histnum += 1;
}

for (const expr of [`Symbol.for('foo')`, `Symbol('foo')`]) {
t.deepEqual(doEval(histnum, expr), {});
m = sentMessages.shift();
t.deepEqual(m.type, 'updateHistory');
t.is(sentMessages.length, 1);

t.is(m.histnum, histnum);
t.is(m.display, `working on eval(${expr})`);
m = sentMessages.shift();
t.is(m.type, 'updateHistory');
t.is(m.histnum, histnum);
t.is(m.display, `Symbol(?)`);
t.deepEqual(sentMessages, []);
histnum += 1;
}
});

test('repl: unjsonables', async t => {
const { doEval, sentMessages } = make();

let m = sentMessages.shift();

let histnum = 0;
for (const valStr of ['NaN', 'Infinity', '-Infinity', 'undefined']) {
t.deepEqual(doEval(histnum, valStr), {});
m = sentMessages.shift();
t.deepEqual(m.type, 'updateHistory');
t.is(sentMessages.length, 1);

t.is(m.histnum, histnum);
t.is(m.display, `working on eval(${valStr})`);
m = sentMessages.shift();
t.is(m.type, 'updateHistory');
t.is(m.histnum, histnum);
t.is(m.display, valStr);
t.deepEqual(sentMessages, []);
histnum += 1;
}
});

test('repl: sloppyGlobals, home, endowments', async t => {
Expand Down

0 comments on commit bef7d37

Please sign in to comment.