Skeleton.match
This commit is contained in:
parent
14bb7f3d6f
commit
0f4a572393
|
@ -423,6 +423,32 @@ function unpackScoped(a, k) {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function match(p, v) {
|
||||
let captures = Immutable.List();
|
||||
|
||||
function walk(p, v) {
|
||||
if (Capture.isClassOf(p)) {
|
||||
if (!walk(p.get(0), v)) return false;
|
||||
captures = captures.push(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Discard.isClassOf(p)) return true;
|
||||
|
||||
const pcls = classOf(p);
|
||||
const vcls = classOf(v);
|
||||
if (!Immutable.is(pcls, vcls)) return false;
|
||||
|
||||
if (pcls === null) return Immutable.is(p, v);
|
||||
if (typeof pcls === 'number') return p.every((pv, i) => walk(pv, v.get(i)));
|
||||
return p.fields.every((pv, i) => walk(pv, v.fields.get(i)));
|
||||
}
|
||||
|
||||
return walk(p, v) ? captures : false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module.exports.EVENT_ADDED = EVENT_ADDED;
|
||||
module.exports.EVENT_REMOVED = EVENT_REMOVED;
|
||||
module.exports.EVENT_MESSAGE = EVENT_MESSAGE;
|
||||
|
@ -430,3 +456,4 @@ module.exports.Index = Index;
|
|||
|
||||
module.exports.analyzeAssertion = analyzeAssertion;
|
||||
module.exports.instantiateAssertion = instantiateAssertion;
|
||||
module.exports.match = match;
|
||||
|
|
|
@ -266,4 +266,71 @@ describe('skeleton', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('matching a single pattern against a value', () => {
|
||||
it('should accept matching simple records', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS(A(1, 2)),
|
||||
Immutable.fromJS(A(1, 2))))
|
||||
.to.equal(Immutable.List());
|
||||
});
|
||||
it('should capture from matching simple records', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS(A(1, _$)),
|
||||
Immutable.fromJS(A(1, 2))))
|
||||
.to.equal(Immutable.List([2]));
|
||||
});
|
||||
it('should reject mismatching simple records', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS(A(1, 2)),
|
||||
Immutable.fromJS(A(1, "hi"))))
|
||||
.to.equal(false);
|
||||
});
|
||||
it('should accept matching simple lists', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, 2, 3]),
|
||||
Immutable.fromJS([1, 2, 3])))
|
||||
.to.equal(Immutable.List());
|
||||
});
|
||||
it('should accept matching nested lists', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, [2, 4], 3]),
|
||||
Immutable.fromJS([1, [2, 4], 3])))
|
||||
.to.equal(Immutable.List());
|
||||
});
|
||||
it('should capture matches from simple lists', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, Capture(2), 3]),
|
||||
Immutable.fromJS([1, 2, 3])))
|
||||
.to.equal(Immutable.List([2]));
|
||||
});
|
||||
it('should capture discards from simple lists', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, Capture(__), 3]),
|
||||
Immutable.fromJS([1, 2, 3])))
|
||||
.to.equal(Immutable.List([2]));
|
||||
});
|
||||
it('should capture discards from nested lists', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, Capture(__), 3]),
|
||||
Immutable.fromJS([1, [2, 4], 3])))
|
||||
.to.equal(Immutable.fromJS([[2, 4]]));
|
||||
});
|
||||
it('should capture nested discards from nested lists', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, Capture([__, 4]), 3]),
|
||||
Immutable.fromJS([1, [2, 4], 3])))
|
||||
.to.equal(Immutable.fromJS([[2, 4]]));
|
||||
});
|
||||
it('should reject nested mismatches from nested lists', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, Capture([__, 5]), 3]),
|
||||
Immutable.fromJS([1, [2, 4], 3])))
|
||||
.to.equal(false);
|
||||
});
|
||||
it('should reject mismatching captures from simple lists', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, Capture(9), 3]),
|
||||
Immutable.fromJS([1, 2, 3])))
|
||||
.to.equal(false);
|
||||
});
|
||||
it('should reject simple lists varying in arity', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, 2, 3, 4]),
|
||||
Immutable.fromJS([1, 2, 3])))
|
||||
.to.equal(false);
|
||||
});
|
||||
it('should reject simple lists varying in order', () => {
|
||||
expect(Skeleton.match(Immutable.fromJS([1, 3, 2]),
|
||||
Immutable.fromJS([1, 2, 3])))
|
||||
.to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue