Files

182 lines
6.1 KiB
TypeScript

/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { expect } from 'chai';
import { FieldPath, ResourcePath } from '../../../src/model/path';
import { addEqualityMatcher } from '../../util/equality_matcher';
import { path } from '../../util/helpers';
function expectEqual(s1: string[], s2: string[]): void {
expect(
ResourcePath.comparator(new ResourcePath(s1), new ResourcePath(s2))
).to.equal(0);
}
function expectLess(s1: string[], s2: string[]): void {
expect(
ResourcePath.comparator(new ResourcePath(s1), new ResourcePath(s2))
).to.equal(-1);
expect(
ResourcePath.comparator(new ResourcePath(s2), new ResourcePath(s1))
).to.equal(1);
}
describe('Path', () => {
addEqualityMatcher();
it('can be constructed', () => {
new ResourcePath(['rooms', 'Eros', 'messages']);
});
it('can index into itself', () => {
const path = new ResourcePath(['rooms', 'Eros', 'messages']);
expect(path.get(0)).to.equal('rooms');
expect(path.get(1)).to.equal('Eros');
expect(path.get(2)).to.equal('messages');
});
it('can be constructed with offsets', () => {
let path = new ResourcePath(['rooms', 'Eros', 'messages'], 2);
expect(path).to.deep.equal(new ResourcePath(['messages']));
expect(path.length).to.equal(1);
path = new ResourcePath(['rooms', 'Eros', 'messages'], 3);
expect(path).to.deep.equal(new ResourcePath([]));
expect(path.length).to.equal(0);
});
it('can pop front repeatedly', () => {
const path = new ResourcePath(['rooms', 'Eros', 'messages']);
expect(path.popFirst()).to.deep.equal(
new ResourcePath(['Eros', 'messages'])
);
expect(path.popFirst().popFirst()).to.deep.equal(
new ResourcePath(['messages'])
);
expect(path.popFirst().popFirst().popFirst()).to.deep.equal(
new ResourcePath([])
);
expect(path.popFirst(0)).to.deep.equal(
new ResourcePath(['rooms', 'Eros', 'messages'])
);
expect(path.popFirst(1)).to.deep.equal(
new ResourcePath(['Eros', 'messages'])
);
expect(path.popFirst(2)).to.deep.equal(new ResourcePath(['messages']));
expect(path.popFirst(3)).to.deep.equal(new ResourcePath([]));
// unmodified original
expect(path).to.deep.equal(new ResourcePath(['rooms', 'Eros', 'messages']));
});
it('can yield the last segment', () => {
const path = new ResourcePath(['rooms', 'Eros', 'messages']);
expect(path.lastSegment()).to.equal('messages');
expect(path.popLast().lastSegment()).to.equal('Eros');
expect(path.popLast().popLast().lastSegment()).to.equal('rooms');
});
it('can create child path', () => {
const p: ResourcePath = path('rooms');
expect(p.child('eros')).to.deep.equal(path('rooms/eros'));
expect(p.child('eros').child('1')).to.deep.equal(path('rooms/eros/1'));
// unmodified original
expect(p).to.deep.equal(path('rooms'));
});
it('can pop last repeatedly', () => {
const path = new ResourcePath(['rooms', 'Eros', 'messages']);
expect(path.popLast()).to.deep.equal(new ResourcePath(['rooms', 'Eros']));
expect(path.popLast().popLast()).to.deep.equal(new ResourcePath(['rooms']));
expect(path.popLast().popLast().popLast()).to.deep.equal(
new ResourcePath([])
);
// original remains unmodified
expect(path).to.deep.equal(new ResourcePath(['rooms', 'Eros', 'messages']));
});
it('compares correctly', () => {
expectEqual([], []);
expectEqual(['a'], ['a']);
expectEqual(['a', 'b', 'c'], ['a', 'b', 'c']);
expectLess([], ['a']);
expectLess(['a'], ['b']);
expectLess(['a'], ['a', 'b']);
});
it('determines prefix correctly', () => {
const empty = new ResourcePath([]);
const a = new ResourcePath(['a']);
const ab = new ResourcePath(['a', 'b']);
const abc = new ResourcePath(['a', 'b', 'c']);
const b = new ResourcePath(['b']);
const ba = new ResourcePath(['b', 'a']);
expect(empty.isPrefixOf(a)).to.equal(true);
expect(empty.isPrefixOf(ab)).to.equal(true);
expect(empty.isPrefixOf(abc)).to.equal(true);
expect(empty.isPrefixOf(empty)).to.equal(true);
expect(empty.isPrefixOf(b)).to.equal(true);
expect(empty.isPrefixOf(ba)).to.equal(true);
expect(a.isPrefixOf(a)).to.equal(true);
expect(a.isPrefixOf(ab)).to.equal(true);
expect(a.isPrefixOf(abc)).to.equal(true);
expect(a.isPrefixOf(empty)).to.equal(false);
expect(a.isPrefixOf(b)).to.equal(false);
expect(a.isPrefixOf(ba)).to.equal(false);
expect(ab.isPrefixOf(a)).to.equal(false);
expect(ab.isPrefixOf(ab)).to.equal(true);
expect(ab.isPrefixOf(abc)).to.equal(true);
expect(ab.isPrefixOf(empty)).to.equal(false);
expect(ab.isPrefixOf(b)).to.equal(false);
expect(ab.isPrefixOf(ba)).to.equal(false);
expect(abc.isPrefixOf(a)).to.equal(false);
expect(abc.isPrefixOf(ab)).to.equal(false);
expect(abc.isPrefixOf(abc)).to.equal(true);
expect(abc.isPrefixOf(empty)).to.equal(false);
expect(abc.isPrefixOf(b)).to.equal(false);
expect(abc.isPrefixOf(ba)).to.equal(false);
});
it('escapes FieldPath with segments', () => {
const path = new FieldPath(['\\foo\\.`bar`']);
expect(path.canonicalString()).to.equal('`\\\\foo\\\\.\\`bar\\``');
});
it('can be constructed from field path.', () => {
const path = FieldPath.fromServerFormat('foo\\..bar\\\\.baz');
expect(path.toArray()).to.deep.equal(['foo.', 'bar\\', 'baz']);
});
describe('fails to construct from invalid field path', () => {
for (const bad of ['', 'foo\\', 'foo\\x', 'foo.', '.foo', 'foo..bar']) {
it('"' + bad + '"', () => {
expect(() => FieldPath.fromServerFormat(bad)).to.throw();
});
}
});
});