Be stricter about permissible assertions; repair error in Structure instantiation which led to raw arrays sneaking in
This commit is contained in:
parent
0552de7987
commit
2688c09639
|
@ -77,7 +77,7 @@ const Bag = Immutable.Map;
|
||||||
function fromSet(s) {
|
function fromSet(s) {
|
||||||
return Bag().withMutations(function (b) {
|
return Bag().withMutations(function (b) {
|
||||||
for (let v of Immutable.Set(s)) {
|
for (let v of Immutable.Set(s)) {
|
||||||
b = b.set(v, 1);
|
b = b.set(Immutable.fromJS(v), 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,6 +344,20 @@ Actor.prototype.pendingPatch = function () {
|
||||||
Actor.prototype.assert = function (a) { this.pendingPatch().adjust(a, +1); };
|
Actor.prototype.assert = function (a) { this.pendingPatch().adjust(a, +1); };
|
||||||
Actor.prototype.retract = function (a) { this.pendingPatch().adjust(a, -1); };
|
Actor.prototype.retract = function (a) { this.pendingPatch().adjust(a, -1); };
|
||||||
|
|
||||||
|
Actor.prototype.adhocRetract = function (a) {
|
||||||
|
a = Immutable.fromJS(a);
|
||||||
|
if (this.adhocAssertions.change(a, -1, true) === Bag.PRESENT_TO_ABSENT) {
|
||||||
|
this.retract(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Actor.prototype.adhocAssert = function (a) {
|
||||||
|
a = Immutable.fromJS(a);
|
||||||
|
if (this.adhocAssertions.change(a, +1) === Bag.ABSENT_TO_PRESENT) {
|
||||||
|
this.assert(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Actor.prototype.toString = function () {
|
Actor.prototype.toString = function () {
|
||||||
let s = 'Actor(' + this.id;
|
let s = 'Actor(' + this.id;
|
||||||
if (this.name !== void 0) s = s + ',' + JSON.stringify(this.name);
|
if (this.name !== void 0) s = s + ',' + JSON.stringify(this.name);
|
||||||
|
@ -360,7 +374,7 @@ Patch.prototype.perform = function (ds, ac) {
|
||||||
|
|
||||||
Patch.prototype.adjust = function (a, count) {
|
Patch.prototype.adjust = function (a, count) {
|
||||||
var _net;
|
var _net;
|
||||||
({bag: this.changes, net: _net} = Bag.change(this.changes, a, count));
|
({bag: this.changes, net: _net} = Bag.change(this.changes, Immutable.fromJS(a), count));
|
||||||
};
|
};
|
||||||
|
|
||||||
function Message(body) {
|
function Message(body) {
|
||||||
|
@ -369,7 +383,7 @@ function Message(body) {
|
||||||
|
|
||||||
Message.prototype.perform = function (ds, ac) {
|
Message.prototype.perform = function (ds, ac) {
|
||||||
if (this.body !== void 0) {
|
if (this.body !== void 0) {
|
||||||
ds.index.sendMessage(this.body);
|
ds.index.sendMessage(Immutable.fromJS(this.body));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,6 @@ function del_from_handler(h, vs) {
|
||||||
|
|
||||||
Index.prototype.adjustAssertion = function(outerValue, delta) {
|
Index.prototype.adjustAssertion = function(outerValue, delta) {
|
||||||
let net;
|
let net;
|
||||||
outerValue = Immutable.fromJS(outerValue);
|
|
||||||
({bag: this.allAssertions, net: net} = Bag.change(this.allAssertions, outerValue, delta));
|
({bag: this.allAssertions, net: net} = Bag.change(this.allAssertions, outerValue, delta));
|
||||||
switch (net) {
|
switch (net) {
|
||||||
case Bag.ABSENT_TO_PRESENT:
|
case Bag.ABSENT_TO_PRESENT:
|
||||||
|
@ -265,7 +264,7 @@ Index.prototype.addAssertion = function(v) { this.adjustAssertion(v, +1); };
|
||||||
Index.prototype.removeAssertion = function (v) { this.adjustAssertion(v, -1); };
|
Index.prototype.removeAssertion = function (v) { this.adjustAssertion(v, -1); };
|
||||||
|
|
||||||
Index.prototype.sendMessage = function(v) {
|
Index.prototype.sendMessage = function(v) {
|
||||||
this.root.modify(Immutable.fromJS(v), ()=>{}, ()=>{}, (h, vs) => {
|
this.root.modify(v, ()=>{}, ()=>{}, (h, vs) => {
|
||||||
h.callbacks.forEach((cb) => {
|
h.callbacks.forEach((cb) => {
|
||||||
cb(EVENT_MESSAGE, vs);
|
cb(EVENT_MESSAGE, vs);
|
||||||
return true;
|
return true;
|
||||||
|
@ -321,7 +320,7 @@ function analyzeAssertion(a) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let skeleton = walk(Immutable.List(), Immutable.fromJS(a));
|
let skeleton = walk(Immutable.List(), a);
|
||||||
|
|
||||||
return { skeleton, constPaths, constVals, capturePaths };
|
return { skeleton, constPaths, constVals, capturePaths };
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,14 @@ const __ = new $Special("wildcard"); /* wildcard marker */
|
||||||
function StructureType(label, arity) {
|
function StructureType(label, arity) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.arity = arity;
|
this.arity = arity;
|
||||||
this.pattern = this.instantiate(Immutable.Repeat(__, arity).toArray());
|
// this.pattern = this.instantiate(Immutable.Repeat(__, arity).toArray());
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this.ctor = function () {
|
this.ctor = function () {
|
||||||
return self.instantiate(Array.prototype.slice.call(arguments));
|
return self.instantiate(Array.prototype.slice.call(arguments));
|
||||||
};
|
};
|
||||||
this.ctor.meta = this;
|
this.ctor.meta = this;
|
||||||
this.ctor.pattern = this.pattern;
|
// this.ctor.pattern = this.pattern;
|
||||||
this.ctor.isClassOf = function (v) { return self.isClassOf(v); };
|
this.ctor.isClassOf = function (v) { return self.isClassOf(v); };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,9 +68,10 @@ function Structure(meta, fields) {
|
||||||
throw new Error("Structure: cannot instantiate meta "+JSON.stringify(meta.label)+
|
throw new Error("Structure: cannot instantiate meta "+JSON.stringify(meta.label)+
|
||||||
" expecting "+meta.arity+" fields with "+fields.length+" fields");
|
" expecting "+meta.arity+" fields with "+fields.length+" fields");
|
||||||
}
|
}
|
||||||
|
fields = fields.slice(0);
|
||||||
this.meta = meta;
|
this.meta = meta;
|
||||||
this.length = meta.arity;
|
this.length = meta.arity;
|
||||||
this.fields = fields.slice(0);
|
this.fields = fields;
|
||||||
for (var i = 0; i < fields.length; i++) {
|
for (var i = 0; i < fields.length; i++) {
|
||||||
this[i] = fields[i] = Immutable.fromJS(fields[i]);
|
this[i] = fields[i] = Immutable.fromJS(fields[i]);
|
||||||
if (this[i] === void 0) {
|
if (this[i] === void 0) {
|
||||||
|
@ -98,9 +99,11 @@ Structure.prototype.equals = function (other) {
|
||||||
if (!(other instanceof Structure)) return false;
|
if (!(other instanceof Structure)) return false;
|
||||||
if (!other.meta.equals(this.meta)) return false;
|
if (!other.meta.equals(this.meta)) return false;
|
||||||
for (let i = 0; i < this.length; i++) {
|
for (let i = 0; i < this.length; i++) {
|
||||||
if (this[i] === other[i]) continue;
|
const a = this[i];
|
||||||
if (typeof this[i].equals !== 'function') return false;
|
const b = other[i];
|
||||||
if (!this[i].equals(other[i])) return false;
|
if (a === b) continue;
|
||||||
|
if (!a || typeof a.equals !== 'function') return false;
|
||||||
|
if (!a.equals(b)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,6 +45,10 @@ function skeletonTrace(f) {
|
||||||
return traceHolder.trace;
|
return traceHolder.trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _analyzeAssertion(a) {
|
||||||
|
return Skeleton.analyzeAssertion(Immutable.fromJS(a));
|
||||||
|
}
|
||||||
|
|
||||||
describe('skeleton', () => {
|
describe('skeleton', () => {
|
||||||
|
|
||||||
const A = Struct.makeConstructor('A', ['x', 'y']);
|
const A = Struct.makeConstructor('A', ['x', 'y']);
|
||||||
|
@ -53,14 +57,14 @@ describe('skeleton', () => {
|
||||||
|
|
||||||
describe('pattern analysis', () => {
|
describe('pattern analysis', () => {
|
||||||
it('should handle leaf captures', () => {
|
it('should handle leaf captures', () => {
|
||||||
expect(Immutable.fromJS(Skeleton.analyzeAssertion(A(B(_$), _$))))
|
expect(Immutable.fromJS(_analyzeAssertion(A(B(_$), _$))))
|
||||||
.to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, null], null],
|
.to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, null], null],
|
||||||
constPaths: Immutable.fromJS([]),
|
constPaths: Immutable.fromJS([]),
|
||||||
constVals: Immutable.fromJS([]),
|
constVals: Immutable.fromJS([]),
|
||||||
capturePaths: Immutable.fromJS([[0, 0], [1]])}));
|
capturePaths: Immutable.fromJS([[0, 0], [1]])}));
|
||||||
});
|
});
|
||||||
it('should handle atomic constants', () => {
|
it('should handle atomic constants', () => {
|
||||||
expect(Immutable.fromJS(Skeleton.analyzeAssertion(A(B("x"), _$))))
|
expect(Immutable.fromJS(_analyzeAssertion(A(B("x"), _$))))
|
||||||
.to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, null], null],
|
.to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, null], null],
|
||||||
constPaths: Immutable.fromJS([[0, 0]]),
|
constPaths: Immutable.fromJS([[0, 0]]),
|
||||||
constVals: Immutable.fromJS(["x"]),
|
constVals: Immutable.fromJS(["x"]),
|
||||||
|
@ -74,7 +78,7 @@ describe('skeleton', () => {
|
||||||
// that situation without the static analysis half of the code.
|
// that situation without the static analysis half of the code.
|
||||||
// TODO later.
|
// TODO later.
|
||||||
let complexPlaceholder = new Object();
|
let complexPlaceholder = new Object();
|
||||||
expect(Immutable.fromJS(Skeleton.analyzeAssertion(A(complexPlaceholder, C(_$)))))
|
expect(Immutable.fromJS(_analyzeAssertion(A(complexPlaceholder, C(_$)))))
|
||||||
.to.equal(Immutable.fromJS({skeleton: [A.meta, null, [C.meta, null]],
|
.to.equal(Immutable.fromJS({skeleton: [A.meta, null, [C.meta, null]],
|
||||||
constPaths: Immutable.fromJS([[0]]),
|
constPaths: Immutable.fromJS([[0]]),
|
||||||
constVals: Immutable.fromJS([complexPlaceholder]),
|
constVals: Immutable.fromJS([complexPlaceholder]),
|
||||||
|
@ -87,21 +91,21 @@ describe('skeleton', () => {
|
||||||
// will end up being complex at runtime. We can't properly test
|
// will end up being complex at runtime. We can't properly test
|
||||||
// that situation without the static analysis half of the code.
|
// that situation without the static analysis half of the code.
|
||||||
// TODO later.
|
// TODO later.
|
||||||
expect(Immutable.fromJS(Skeleton.analyzeAssertion(A(B(B("y")), _$("rhs", C(__))))))
|
expect(Immutable.fromJS(_analyzeAssertion(A(B(B("y")), _$("rhs", C(__))))))
|
||||||
.to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, [B.meta, null]], [C.meta, null]],
|
.to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, [B.meta, null]], [C.meta, null]],
|
||||||
constPaths: Immutable.fromJS([[0, 0, 0]]),
|
constPaths: Immutable.fromJS([[0, 0, 0]]),
|
||||||
constVals: Immutable.fromJS(["y"]),
|
constVals: Immutable.fromJS(["y"]),
|
||||||
capturePaths: Immutable.fromJS([[1]])}));
|
capturePaths: Immutable.fromJS([[1]])}));
|
||||||
});
|
});
|
||||||
it('should handle list patterns with discards', () => {
|
it('should handle list patterns with discards', () => {
|
||||||
expect(Immutable.fromJS(Skeleton.analyzeAssertion([__, __])))
|
expect(Immutable.fromJS(_analyzeAssertion([__, __])))
|
||||||
.to.equal(Immutable.fromJS({skeleton: [2, null, null],
|
.to.equal(Immutable.fromJS({skeleton: [2, null, null],
|
||||||
constPaths: Immutable.fromJS([]),
|
constPaths: Immutable.fromJS([]),
|
||||||
constVals: Immutable.fromJS([]),
|
constVals: Immutable.fromJS([]),
|
||||||
capturePaths: Immutable.fromJS([])}));
|
capturePaths: Immutable.fromJS([])}));
|
||||||
});
|
});
|
||||||
it('should handle list patterns with constants and captures', () => {
|
it('should handle list patterns with constants and captures', () => {
|
||||||
expect(Immutable.fromJS(Skeleton.analyzeAssertion(["hi", _$, _$])))
|
expect(Immutable.fromJS(_analyzeAssertion(["hi", _$, _$])))
|
||||||
.to.equal(Immutable.fromJS({skeleton: [3, null, null, null],
|
.to.equal(Immutable.fromJS({skeleton: [3, null, null, null],
|
||||||
constPaths: Immutable.fromJS([[0]]),
|
constPaths: Immutable.fromJS([[0]]),
|
||||||
constVals: Immutable.fromJS(["hi"]),
|
constVals: Immutable.fromJS(["hi"]),
|
||||||
|
@ -111,8 +115,8 @@ describe('skeleton', () => {
|
||||||
|
|
||||||
describe('nested structs', () => {
|
describe('nested structs', () => {
|
||||||
let trace = skeletonTrace((i, traceHolder) => {
|
let trace = skeletonTrace((i, traceHolder) => {
|
||||||
i.addHandler(Skeleton.analyzeAssertion(A(B(_$), _$)), eventCallback(traceHolder, "AB"));
|
i.addHandler(_analyzeAssertion(A(B(_$), _$)), eventCallback(traceHolder, "AB"));
|
||||||
i.addHandler(Skeleton.analyzeAssertion(A(B("x"), _$)), eventCallback(traceHolder, "ABx"));
|
i.addHandler(_analyzeAssertion(A(B("x"), _$)), eventCallback(traceHolder, "ABx"));
|
||||||
let complexConstantPattern1 = {skeleton: [A.meta, null, [C.meta, null]],
|
let complexConstantPattern1 = {skeleton: [A.meta, null, [C.meta, null]],
|
||||||
constPaths: Immutable.fromJS([[0]]),
|
constPaths: Immutable.fromJS([[0]]),
|
||||||
constVals: Immutable.fromJS([B("y")]),
|
constVals: Immutable.fromJS([B("y")]),
|
||||||
|
@ -125,10 +129,10 @@ describe('skeleton', () => {
|
||||||
capturePaths: Immutable.fromJS([[1]])};
|
capturePaths: Immutable.fromJS([[1]])};
|
||||||
i.addHandler(complexConstantPattern2, eventCallback(traceHolder, "ABByC"));
|
i.addHandler(complexConstantPattern2, eventCallback(traceHolder, "ABByC"));
|
||||||
|
|
||||||
i.addAssertion(A(B("x"),C(1)));
|
i.addAssertion(Immutable.fromJS(A(B("x"),C(1))));
|
||||||
i.addAssertion(A(B("y"),C(2)));
|
i.addAssertion(Immutable.fromJS(A(B("y"),C(2))));
|
||||||
i.addAssertion(A(B(B("y")),C(2)));
|
i.addAssertion(Immutable.fromJS(A(B(B("y")),C(2))));
|
||||||
i.addAssertion(A(B("z"),C(3)));
|
i.addAssertion(Immutable.fromJS(A(B("z"),C(3))));
|
||||||
});
|
});
|
||||||
|
|
||||||
// trace.forEach((e) => { console.log(e.toString()) });
|
// trace.forEach((e) => { console.log(e.toString()) });
|
||||||
|
@ -146,12 +150,12 @@ describe('skeleton', () => {
|
||||||
|
|
||||||
describe('simple detail-erasing trace', () => {
|
describe('simple detail-erasing trace', () => {
|
||||||
let trace = skeletonTrace((i, traceHolder) => {
|
let trace = skeletonTrace((i, traceHolder) => {
|
||||||
i.addHandler(Skeleton.analyzeAssertion([__, __]), eventCallback(traceHolder, "2-EVENT"));
|
i.addHandler(_analyzeAssertion([__, __]), eventCallback(traceHolder, "2-EVENT"));
|
||||||
|
|
||||||
i.addAssertion(["hi", 123]);
|
i.addAssertion(Immutable.fromJS(["hi", 123]));
|
||||||
i.addAssertion(["hi", 234]);
|
i.addAssertion(Immutable.fromJS(["hi", 234]));
|
||||||
i.removeAssertion(["hi", 123]);
|
i.removeAssertion(Immutable.fromJS(["hi", 123]));
|
||||||
i.removeAssertion(["hi", 234]);
|
i.removeAssertion(Immutable.fromJS(["hi", 234]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have one add and one remove', () => {
|
it('should have one add and one remove', () => {
|
||||||
|
@ -164,9 +168,9 @@ describe('skeleton', () => {
|
||||||
|
|
||||||
describe('handler added after assertion (1)', () => {
|
describe('handler added after assertion (1)', () => {
|
||||||
let trace = skeletonTrace((i, traceHolder) => {
|
let trace = skeletonTrace((i, traceHolder) => {
|
||||||
i.addAssertion(["hi", 123, 234]);
|
i.addAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
i.addHandler(Skeleton.analyzeAssertion(["hi", _$, _$]), eventCallback(traceHolder, "X"));
|
i.addHandler(_analyzeAssertion(["hi", _$, _$]), eventCallback(traceHolder, "X"));
|
||||||
i.removeAssertion(["hi", 123, 234]);
|
i.removeAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get two events', () => {
|
it('should get two events', () => {
|
||||||
|
@ -178,9 +182,9 @@ describe('skeleton', () => {
|
||||||
|
|
||||||
describe('handler added after assertion (2)', () => {
|
describe('handler added after assertion (2)', () => {
|
||||||
let trace = skeletonTrace((i, traceHolder) => {
|
let trace = skeletonTrace((i, traceHolder) => {
|
||||||
i.addAssertion(["hi", 123, 234]);
|
i.addAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
i.addHandler(Skeleton.analyzeAssertion(_$), eventCallback(traceHolder, "X"));
|
i.addHandler(_analyzeAssertion(_$), eventCallback(traceHolder, "X"));
|
||||||
i.removeAssertion(["hi", 123, 234]);
|
i.removeAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get two events', () => {
|
it('should get two events', () => {
|
||||||
|
@ -192,12 +196,12 @@ describe('skeleton', () => {
|
||||||
|
|
||||||
describe('handler removed before assertion removed', () => {
|
describe('handler removed before assertion removed', () => {
|
||||||
let trace = skeletonTrace((i, traceHolder) => {
|
let trace = skeletonTrace((i, traceHolder) => {
|
||||||
i.addAssertion(["hi", 123, 234]);
|
i.addAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
let h = Skeleton.analyzeAssertion(["hi", _$, _$]);
|
let h = _analyzeAssertion(["hi", _$, _$]);
|
||||||
h.callback = eventCallback(traceHolder, "X")
|
h.callback = eventCallback(traceHolder, "X")
|
||||||
i.addHandler(h, h.callback);
|
i.addHandler(h, h.callback);
|
||||||
i.removeHandler(h, h.callback);
|
i.removeHandler(h, h.callback);
|
||||||
i.removeAssertion(["hi", 123, 234]);
|
i.removeAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get one event', () => {
|
it('should get one event', () => {
|
||||||
|
@ -208,24 +212,24 @@ describe('skeleton', () => {
|
||||||
|
|
||||||
describe('simple list assertions trace', () => {
|
describe('simple list assertions trace', () => {
|
||||||
let trace = skeletonTrace((i, traceHolder) => {
|
let trace = skeletonTrace((i, traceHolder) => {
|
||||||
i.addHandler(Skeleton.analyzeAssertion(["hi", _$, _$]), eventCallback(traceHolder, "3-EVENT"));
|
i.addHandler(_analyzeAssertion(["hi", _$, _$]), eventCallback(traceHolder, "3-EVENT"));
|
||||||
i.addHandler(Skeleton.analyzeAssertion([__, __]), eventCallback(traceHolder, "2-EVENT"));
|
i.addHandler(_analyzeAssertion([__, __]), eventCallback(traceHolder, "2-EVENT"));
|
||||||
|
|
||||||
i.addAssertion(["hi", 123, 234]);
|
i.addAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
i.addAssertion(["hi", 999, 999]);
|
i.addAssertion(Immutable.fromJS(["hi", 999, 999]));
|
||||||
i.addAssertion(["hi", 123]);
|
i.addAssertion(Immutable.fromJS(["hi", 123]));
|
||||||
i.addAssertion(["hi", 123, 234]);
|
i.addAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
i.sendMessage(["hi", 303]);
|
i.sendMessage(Immutable.fromJS(["hi", 303]));
|
||||||
i.sendMessage(["hi", 303, 404]);
|
i.sendMessage(Immutable.fromJS(["hi", 303, 404]));
|
||||||
i.sendMessage(["hi", 303, 404, 808]);
|
i.sendMessage(Immutable.fromJS(["hi", 303, 404, 808]));
|
||||||
i.removeAssertion(["hi", 123, 234]);
|
i.removeAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
i.removeAssertion(["hi", 999, 999]);
|
i.removeAssertion(Immutable.fromJS(["hi", 999, 999]));
|
||||||
i.removeAssertion(["hi", 123, 234]);
|
i.removeAssertion(Immutable.fromJS(["hi", 123, 234]));
|
||||||
i.addAssertion(["hi", 123]);
|
i.addAssertion(Immutable.fromJS(["hi", 123]));
|
||||||
i.addAssertion(["hi", 234]);
|
i.addAssertion(Immutable.fromJS(["hi", 234]));
|
||||||
i.removeAssertion(["hi", 123]);
|
i.removeAssertion(Immutable.fromJS(["hi", 123]));
|
||||||
i.removeAssertion(["hi", 123]);
|
i.removeAssertion(Immutable.fromJS(["hi", 123]));
|
||||||
i.removeAssertion(["hi", 234]);
|
i.removeAssertion(Immutable.fromJS(["hi", 234]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have 8 entries', () => {
|
it('should have 8 entries', () => {
|
||||||
|
|
Loading…
Reference in New Issue