stsys
Version:
String rewriting system (semi-Thue system)
241 lines (223 loc) • 7.96 kB
JavaScript
const assert = require('assert');
const comparer = require('../lib/cmp');
describe('Comparer', function(){
it('creation failing (no ordering name)', function(){
try
{
comparer.createComparer();
}
catch (error)
{
assert.equal(error.message, 'no ordering specified');
return;
}
assert.fail('expected exception not thrown');
});
it('creation failing (invalid ordering name)', function(){
try
{
comparer.createComparer('bogus');
}
catch (error)
{
assert.equal(error.message, 'unknown ordering: bogus');
return;
}
assert.fail('expected exception not thrown');
});
describe('LPO', function(){
it('creation failing (no preorder)', function(){
try
{
comparer.createComparer('lpo');
}
catch (error)
{
assert.equal(error.message, 'invalid preorder: non-empty array of letters expected');
return;
}
assert.fail('expected exception not thrown');
});
it('creation failing (invalid single character element in preorder)', function(){
try
{
comparer.createComparer('lpo', ['a', '-', 'b']);
}
catch (error)
{
assert.equal(error.message, 'invalid element in preorder: -');
return;
}
assert.fail('expected exception not thrown');
});
it('creation failing (non-string element in preorder)', function(){
try
{
comparer.createComparer('lpo', [42, 'b']);
}
catch (error)
{
assert.equal(error.message, 'invalid element in preorder: 42');
return;
}
assert.fail('expected exception not thrown');
});
it('compare', function(){
const preorder = ['a', 'b', 'c'];
const cmp = comparer.createComparer('lpo', preorder);
assert.equal(cmp.toString(), 'LPO using preorder a > b > c');
assert.equal(cmp.getOrdering(), 'lpo');
assert.deepEqual(cmp.getPreorder(), preorder);
assert.ok(cmp.getPreorder() !== preorder);
assert.equal(cmp.compare('ab','ab'), 0);
assert.equal(cmp.compare('a','b'), 1);
assert.equal(cmp.compare('b','a'), -1);
assert.equal(cmp.compare('a','bbcb'), 1);
assert.equal(cmp.compare('ab','bab'), -1);
assert.equal(cmp.compare('bb','a'), -1);
assert.equal(cmp.compare('aa','abb'), 1);
assert.equal(cmp.compare('bb','aa'), -1);
assert.equal(cmp.compare('abbaba','abbabbbb'), 1);
});
});
describe('Length/lexicographic ordering', function(){
it('creation failing (invalid preorder)', function(){
try
{
comparer.createComparer('lex', 42);
}
catch (error)
{
assert.equal(error.message, 'invalid preorder: non-empty array of letters expected');
return;
}
assert.fail('expected exception not thrown');
});
it('creation failing (multi-character element in preorder)', function(){
try
{
comparer.createComparer('lpo', ['a', 'abba', 'b']);
}
catch (error)
{
assert.equal(error.message, 'invalid element in preorder: abba');
return;
}
assert.fail('expected exception not thrown');
});
it('creation failing (element with direction in preorder)', function(){
try
{
comparer.createComparer('lpo', ['a', 'b:l']);
}
catch (error)
{
assert.equal(error.message, 'invalid element in preorder: b:l');
return;
}
assert.fail('expected exception not thrown');
});
it('compare', function(){
const cmp = comparer.createComparer('lex', ['a', 'b', 'c']);
assert.equal(cmp.toString(), 'Length/lexicographic ordering using preorder a > b > c');
assert.equal(cmp.compare('ab','ab'), 0);
assert.equal(cmp.compare('a','b'), 1);
assert.equal(cmp.compare('b','a'), -1);
assert.equal(cmp.compare('a','bbcb'), -3);
assert.equal(cmp.compare('cab','bab'), -1);
assert.equal(cmp.compare('bb','a'), 1);
assert.equal(cmp.compare('aab','abb'), 1);
assert.equal(cmp.compare('bb','aa'), -1);
assert.equal(cmp.compare('abbaba','abbaca'), 1);
});
it('change preorder', function(){
let preorder = ['a', 'b'];
const cmp = comparer.createComparer('lex', preorder);
assert.equal(cmp.toString(), 'Length/lexicographic ordering using preorder a > b');
assert.deepEqual(cmp.getPreorder(), preorder);
assert.equal(cmp.compare('a','b'), 1);
assert.equal(cmp.compare('b','a'), -1);
cmp.setPreorder(preorder.reverse());
assert.equal(cmp.toString(), 'Length/lexicographic ordering using preorder b > a');
assert.deepEqual(cmp.getPreorder(), preorder);
assert.equal(cmp.compare('a','b'), -1);
assert.equal(cmp.compare('b','a'), 1);
});
});
describe('Syllable ordering', function(){
it('creation failing (empty preorder)', function(){
try
{
comparer.createComparer('syl-l', []);
}
catch (error)
{
assert.equal(error.message, 'invalid preorder: non-empty array of letters expected');
return;
}
assert.fail('expected exception not thrown');
});
it('creation failing (invalid direction in preorder)', function(){
try
{
comparer.createComparer('syl-l', ['a', 'b:l', 'c:x']);
}
catch (error)
{
assert.equal(error.message, 'invalid element in preorder: c:x');
return;
}
assert.fail('expected exception not thrown');
});
it('creation failing (duplicates in preorder)', function(){
try
{
comparer.createComparer('syl-l', ['a', 'b:l', 'a:r']);
}
catch (error)
{
assert.equal(error.message, 'duplicates in preorder: a');
return;
}
assert.fail('expected exception not thrown');
});
it('compare (default: left to right)', function(){
const cmp = comparer.createComparer('syl-l', ['a', 'b', 'c']);
assert.equal(cmp.toString(), 'Syllable ordering with default direction l nested as per preorder a > b > c');
assert.equal(cmp.compare('ab','ab'), 0);
assert.equal(cmp.compare('ab','ba'), -1);
assert.equal(cmp.compare('a','b'), 1);
assert.equal(cmp.compare('b','a'), -1);
assert.equal(cmp.compare('a','bbcb'), 1);
assert.equal(cmp.compare('cab','bab'), -1);
assert.equal(cmp.compare('bb','a'), -1);
assert.equal(cmp.compare('cb', 'bc'), 1);
assert.equal(cmp.compare('aaba','aaa'), 1);
assert.equal(cmp.compare('abbabcbca','abbabcba'), 1);
assert.equal(cmp.compare('bcab','bacb'), 1);
});
it('compare (right to left)', function(){
const cmp = comparer.createComparer('syl-r', ['a', 'b', 'c']);
assert.equal(cmp.toString(), 'Syllable ordering with default direction r nested as per preorder a > b > c');
assert.equal(cmp.compare('ab','ab'), 0);
assert.equal(cmp.compare('ab','ba'), 1);
assert.equal(cmp.compare('a','b'), 1);
assert.equal(cmp.compare('b','a'), -1);
assert.equal(cmp.compare('a','bbcb'), 1);
assert.equal(cmp.compare('cab','bab'), -1);
assert.equal(cmp.compare('bb','a'), -1);
assert.equal(cmp.compare('aaba','aaa'), 1);
assert.equal(cmp.compare('cb', 'bc'), -1);
assert.equal(cmp.compare('abbabcbca','abbabcba'), 1);
assert.equal(cmp.compare('bcab','bacb'), -1);
});
it('compare (mixed left/right)', function(){
const cmp = comparer.createComparer('syl-l', ['a', 'b:r', 'c:l']);
assert.equal(cmp.toString(), 'Syllable ordering with default direction l nested as per preorder a > b:r > c');
assert.equal(cmp.compare('ab','ab'), 0);
assert.equal(cmp.compare('a','b'), 1);
assert.equal(cmp.compare('cb', 'bc'), -1);
assert.equal(cmp.compare('ccc', 'ccc'), 0);
});
});
});