Lambda calculus-like library written in TypeScript.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
jlc/test/string.spec.ts

376 lines
10 KiB

import { describe, expect, it } from '@jest/globals';
import { Term, _, g, l, n, undef } from '../src/core';
import { NOrd, toNOrd } from '../src/ord';
import { toBoolean as $b } from '../src/bool';
import { toNumber as $n, Zero, gt as ngt } from '../src/num';
import { toChar as $c, fromChar as _c } from '../src/char';
import { toString as $s, Cons, Empty, fromString as _s, append, cmp, empty, eq, ge, gt, le, len, lt, wrap } from '../src/string';
import { show } from '../src/string.show';
n('string.spec');
describe('String', () => {
const infinite: Term = g('infinite', Cons._(_c('a'))._('string.spec', 'infinite'));
describe('toString', () => {
it('converts ""', () => {
expect($s(Empty)).toBe('');
});
it('converts "a"', () => {
expect($s(Cons._(_c('a'))._(Empty))).toBe('a');
});
it('converts "abc"', () => {
expect($s(Cons._(_c('a'))._(Cons._(_c('b'))._(Cons._(_c('c'))._(Empty))))).toBe('abc');
});
});
describe('fromString', () => {
it('converts ""', () => {
expect($s(_s(''))).toBe('');
});
it('converts "a"', () => {
expect($s(_s('a'))).toBe('a');
});
it('converts "2"', () => {
expect($s(_s('abc'))).toBe('abc');
});
});
// describe('repeat', () => {
// it('repeat "a" is "aaa..."', () => {
// expect($na(
// repeat(_s('a'))<String>(_((x0: Char) => _((x1s: String) =>
// x1s<String>(_((x1: Char) => _((x2s: String) =>
// x2s<String>(_((x2: Char) => _((_xrs: String): String => cons(x0)._(cons(x1)._(cons(x2)._(Nil)))))))))))))).toEqual('aaa');
// });
// });
// describe('iterate', () => {
// it('iterate succ "a" is "abc..."', () => {
// expect($na(
// iterate(_s('a'))<String>(_((x0: Char) => _((x1s: String) =>
// x1s<String>(_((x1: Char) => _((x2s: String) =>
// x2s<String>(_((x2: Char) => _((_xrs: String): String => cons(x0)._(cons(x1)._(cons(x2)._(Nil)))))))))))))).toEqual('abc');
// });
// });
describe('empty', () => {
it('empty "" is True', () => {
expect($b(empty._(_s('')))).toEqual(true);
});
it('empty "a" is False', () => {
expect($b(empty._(_s('a')))).toEqual(false);
});
it('empty "ab" is False', () => {
expect($b(empty._(_s('ab')))).toEqual(false);
});
it('handles infinite lists', () => {
expect($b(empty._(infinite))).toEqual(false);
});
});
describe('len', () => {
it('len "" is 0', () => {
expect($n(len._(_s('')))).toEqual(0);
});
it('len "a" is 1', () => {
expect($n(len._(_s('a')))).toEqual(1);
});
it('len "ab" is 2', () => {
expect($n(len._(_s('ab')))).toEqual(2);
});
it('handles infinite lists', () => {
expect($b(ngt._(len._(infinite))._(Zero))).toEqual(true);
});
});
describe('append', () => {
it('"" append "" is ""', () => {
expect($s(append._(Empty)._(Empty))).toBe('');
});
it('"a" append "b" is "ab"', () => {
expect($s(append._(_s('a'))._(_s('b')))).toBe('ab');
});
it('"abc" append "def" is "abcdef"', () => {
expect($s(append._(_s('abc'))._(_s('def')))).toBe('abcdef');
});
it('handles infinite strings', () => {
expect($c(append._(infinite)._(infinite)._(undef)._(l('x', l('_', 'x'))))).toBe('a');
});
});
describe('wrap', () => {
it('"" wrap "" is ""', () => {
expect($s(wrap._(Empty)._(Empty))).toBe('');
});
it('"a" wrap "b" is "aba"', () => {
expect($s(wrap._(_s('a'))._(_s('b')))).toBe('aba');
});
it('handles infinite strings', () => {
expect($c(wrap._(infinite)._(infinite)._(undef)._(l('x', l('_', 'x'))))).toBe('a');
});
});
describe('cmp', () => {
it('"" cmp "" is EQ', () => {
expect(toNOrd(cmp._(_s(''))._(_s('')))).toEqual(NOrd.EQ);
});
it('"" cmp "abc" is LT', () => {
expect(toNOrd(cmp._(_s(''))._(_s('abc')))).toEqual(NOrd.LT);
});
it('"abc" cmp "" is GT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('')))).toEqual(NOrd.GT);
});
it('"a" cmp "abc" is LT', () => {
expect(toNOrd(cmp._(_s('a'))._(_s('abc')))).toEqual(NOrd.LT);
});
it('"abc" cmp "a" is GT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('a')))).toEqual(NOrd.GT);
});
it('"bca" cmp "abc" is GT', () => {
expect(toNOrd(cmp._(_s('bca'))._(_s('abc')))).toEqual(NOrd.GT);
});
it('"abc" cmp "bca" is LT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('bca')))).toEqual(NOrd.LT);
});
it('"abc" cmp "abc" is EQ', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('abc')))).toEqual(NOrd.EQ);
});
it('handles infinite strings', () => {
expect(toNOrd(cmp._(_s('abc'))._(infinite))).toEqual(NOrd.GT);
expect(toNOrd(cmp._(infinite)._(_s('abc')))).toEqual(NOrd.LT);
});
});
describe('lt', () => {
it('"" lt "" is False', () => {
expect($b(lt._(_s(''))._(_s('')))).toEqual(false);
});
it('"" lt "abc" is True', () => {
expect($b(lt._(_s(''))._(_s('abc')))).toEqual(true);
});
it('"abc" lt "" is False', () => {
expect($b(lt._(_s('abc'))._(_s('')))).toEqual(false);
});
it('"a" lt "abc" is True', () => {
expect($b(lt._(_s('a'))._(_s('abc')))).toEqual(true);
});
it('"abc" lt "a" is False', () => {
expect($b(lt._(_s('abc'))._(_s('a')))).toEqual(false);
});
it('"bca" lt "abc" is False', () => {
expect($b(lt._(_s('bca'))._(_s('abc')))).toEqual(false);
});
it('"abc" lt "bca" is True', () => {
expect($b(lt._(_s('abc'))._(_s('bca')))).toEqual(true);
});
it('"abc" lt "abc" is False', () => {
expect($b(lt._(_s('abc'))._(_s('abc')))).toEqual(false);
});
it('handles infinite strings', () => {
expect($b(lt._(_s('abc'))._(infinite))).toEqual(false);
expect($b(lt._(infinite)._(_s('abc')))).toEqual(true);
});
});
describe('le', () => {
it('"" le "" is True', () => {
expect($b(le._(_s(''))._(_s('')))).toEqual(true);
});
it('"" le "abc" is True', () => {
expect($b(le._(_s(''))._(_s('abc')))).toEqual(true);
});
it('"abc" le "" is False', () => {
expect($b(le._(_s('abc'))._(_s('')))).toEqual(false);
});
it('"a" le "abc" is True', () => {
expect($b(le._(_s('a'))._(_s('abc')))).toEqual(true);
});
it('"abc" le "a" is False', () => {
expect($b(le._(_s('abc'))._(_s('a')))).toEqual(false);
});
it('"bca" le "abc" is False', () => {
expect($b(le._(_s('bca'))._(_s('abc')))).toEqual(false);
});
it('"abc" le "bca" is True', () => {
expect($b(le._(_s('abc'))._(_s('bca')))).toEqual(true);
});
it('"abc" le "abc" is True', () => {
expect($b(le._(_s('abc'))._(_s('abc')))).toEqual(true);
});
it('handles infinite strings', () => {
expect($b(le._(_s('abc'))._(infinite))).toEqual(false);
expect($b(le._(infinite)._(_s('abc')))).toEqual(true);
});
});
describe('eq', () => {
it('"" eq "" is True', () => {
expect($b(eq._(_s(''))._(_s('')))).toEqual(true);
});
it('"" eq "abc" is False', () => {
expect($b(eq._(_s(''))._(_s('abc')))).toEqual(false);
});
it('"abc" eq "" is False', () => {
expect($b(eq._(_s('abc'))._(_s('')))).toEqual(false);
});
it('"a" eq "abc" is False', () => {
expect($b(eq._(_s('a'))._(_s('abc')))).toEqual(false);
});
it('"abc" eq "a" is False', () => {
expect($b(eq._(_s('abc'))._(_s('a')))).toEqual(false);
});
it('"bca" eq "abc" is False', () => {
expect($b(eq._(_s('bca'))._(_s('abc')))).toEqual(false);
});
it('"abc" eq "bca" is False', () => {
expect($b(eq._(_s('abc'))._(_s('bca')))).toEqual(false);
});
it('"abc" eq "abc" is True', () => {
expect($b(eq._(_s('abc'))._(_s('abc')))).toEqual(true);
});
it('handles infinite strings', () => {
expect($b(eq._(_s('abc'))._(infinite))).toEqual(false);
expect($b(eq._(infinite)._(_s('abc')))).toEqual(false);
});
});
describe('ge', () => {
it('"" ge "" is True', () => {
expect($b(ge._(_s(''))._(_s('')))).toEqual(true);
});
it('"" ge "abc" is False', () => {
expect($b(ge._(_s(''))._(_s('abc')))).toEqual(false);
});
it('"abc" ge "" is True', () => {
expect($b(ge._(_s('abc'))._(_s('')))).toEqual(true);
});
it('"a" ge "abc" is False', () => {
expect($b(ge._(_s('a'))._(_s('abc')))).toEqual(false);
});
it('"abc" ge "a" is True', () => {
expect($b(ge._(_s('abc'))._(_s('a')))).toEqual(true);
});
it('"bca" ge "abc" is True', () => {
expect($b(ge._(_s('bca'))._(_s('abc')))).toEqual(true);
});
it('"abc" ge "bca" is False', () => {
expect($b(ge._(_s('abc'))._(_s('bca')))).toEqual(false);
});
it('"abc" ge "abc" is True', () => {
expect($b(ge._(_s('abc'))._(_s('abc')))).toEqual(true);
});
it('handles infinite strings', () => {
expect($b(ge._(_s('abc'))._(infinite))).toEqual(true);
expect($b(ge._(infinite)._(_s('abc')))).toEqual(false);
});
});
describe('gt', () => {
it('"" gt "" is False', () => {
expect($b(gt._(_s(''))._(_s('')))).toEqual(false);
});
it('"" gt "abc" is False', () => {
expect($b(gt._(_s(''))._(_s('abc')))).toEqual(false);
});
it('"abc" gt "" is True', () => {
expect($b(gt._(_s('abc'))._(_s('')))).toEqual(true);
});
it('"a" gt "abc" is False', () => {
expect($b(gt._(_s('a'))._(_s('abc')))).toEqual(false);
});
it('"abc" gt "a" is True', () => {
expect($b(gt._(_s('abc'))._(_s('a')))).toEqual(true);
});
it('"bca" gt "abc" is True', () => {
expect($b(gt._(_s('bca'))._(_s('abc')))).toEqual(true);
});
it('"abc" gt "bca" is False', () => {
expect($b(gt._(_s('abc'))._(_s('bca')))).toEqual(false);
});
it('"abc" gt "abc" is False', () => {
expect($b(gt._(_s('abc'))._(_s('abc')))).toEqual(false);
});
it('handles infinite strings', () => {
expect($b(gt._(_s('abc'))._(infinite))).toEqual(true);
expect($b(gt._(infinite)._(_s('abc')))).toEqual(false);
});
});
describe('show', () => {
it('show "" is """"', () => {
expect($s(show._(_s('')))).toBe('""');
});
it('show "a" is ""a""', () => {
expect($s(show._(_s('a')))).toBe('"a"');
});
it('show "abc" is ""abc""', () => {
expect($s(show._(_s('abc')))).toBe('"abc"');
});
});
});