diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-02-07 19:08:03 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-02-07 19:08:03 +0000 |
| commit | 64f212a9b219f5eb9c75723b627ac501afe1899f (patch) | |
| tree | fecbdbd578443a286b9c37a7f77a07f0ff62676e /spec | |
| parent | 50% of functions (diff) | |
| download | alive-64f212a9b219f5eb9c75723b627ac501afe1899f.tar.gz alive-64f212a9b219f5eb9c75723b627ac501afe1899f.zip | |
new AST approach, testing
Diffstat (limited to 'spec')
| -rw-r--r-- | spec/ast_spec.moon | 91 | ||||
| -rw-r--r-- | spec/const_spec.moon | 123 | ||||
| -rw-r--r-- | spec/parsing_spec.moon | 97 | ||||
| -rw-r--r-- | spec/registry_spec.moon | 66 |
4 files changed, 240 insertions, 137 deletions
diff --git a/spec/ast_spec.moon b/spec/ast_spec.moon deleted file mode 100644 index 1cf6c30..0000000 --- a/spec/ast_spec.moon +++ /dev/null @@ -1,91 +0,0 @@ -import Atom, Xpr from require 'ast' -import Scope from require 'scope' -import Logger from require 'logger' -Logger.init 'silent' - -describe 'Atom', -> - expand = (typ, str, ...) -> - atom = Atom["make_#{typ}"] str - atom\expand ... - atom.value\getc! - - describe 'sym', -> - it 'expand correctly', -> - values = { a: 1, b: 2, c: 44, 'long_name': 'str', - 'name/with/slash': 3 } - - scope = Scope.from_table values - - for k,v in pairs values - assert.is.equal v, expand 'sym', k, scope - - describe 'num', -> - it 'expand correctly', -> - assert.is.equal 1, expand 'num', '1' - assert.is.equal 0, expand 'num', '0' - assert.is.equal .1, expand 'num', '.1' - assert.is.equal .123, expand 'num', '.123' - assert.is.equal 20, expand 'num', '20' - assert.is.equal 20, expand 'num', '20.' - assert.is.equal 20.1, expand 'num', '20.1' - - describe 'strd', -> - it 'expand correctly', -> - assert.is.equal 'hello', expand 'strd', 'hello' - assert.is.equal 'hello world', expand 'strd', 'hello world' - assert.is.equal '', expand 'strd', '' - assert.is.equal '\\', expand 'strd', '\\\\' - assert.is.equal "'", expand 'strd', "\\'" - assert.is.equal '"', expand 'strd', '\\"' - assert.is.equal "a string with ' inside", - expand 'strd', "a string with ' inside" - - describe 'strq', -> - it 'expand correctly', -> - assert.is.equal 'hello', expand 'strq', 'hello' - assert.is.equal 'hello world', expand 'strq', 'hello world' - assert.is.equal '', expand 'strq', '' - assert.is.equal '\\', expand 'strq', '\\\\' - assert.is.equal "'", expand 'strq', "\\'" - assert.is.equal '"', expand 'strq', '\\"' - assert.is.equal 'a string with " inside', - expand 'strq', 'a string with " inside' - -describe 'Xpr', -> - describe 'can be tagged', -> - xpr = Xpr.make_sexpr 2, {''} - assert.is.equal 2, xpr.tag - assert.is.equal '([2])', xpr\stringify! - - describe 'can be walked', -> - a1 = Atom.make_num '1' - a2 = Atom.make_num '2' - a3 = Atom.make_num '3' - x1 = Xpr.make_sexpr { '', a1, '' } - x21 = Xpr.make_sexpr { '', a2, '' } - x22 = Xpr.make_sexpr { '', a3, '' } - x2 = Xpr.make_sexpr { '', x21, ' ', x22, '' } - root = Xpr.make_nexpr { '', x1, ' ', x2, '' } - - assert_yields = (expected_order, iter) -> - for val in *expected_order - got_typ, got_val = iter! - assert.is.equal val.type, got_typ - assert.is.equal val, got_val - assert.is.nil iter! - - it 'inside-out', -> - assert_yields { a1, x1, a2, x21, a3, x22, x2, root }, root\walk 'inout' - - it 'inside-out, skipping the root', -> - assert_yields { a1, x1, a2, x21, a3, x22, x2 }, root\walk 'inout', false - - it 'outside-in', -> - assert_yields { root, x1, a1, x2, x21, a2, x22, a3 }, root\walk 'outin' - - it 'outside-in, skipping the root', -> - assert_yields { x1, a1, x2, x21, a2, x22, a3 }, root\walk 'outin', false - - it 'errors when direction is wrong or absent', -> - assert.has.errors -> root\walk! - assert.has.errors -> root\walk 'backandforth' diff --git a/spec/const_spec.moon b/spec/const_spec.moon new file mode 100644 index 0000000..4e4028f --- /dev/null +++ b/spec/const_spec.moon @@ -0,0 +1,123 @@ +import Const, Op, Action from require 'base' +import Scope from require 'scope' +import Logger from require 'logger' +Logger.init 'silent' + +class TestOp extends Op + new: (...) => super ... + +class TestAction extends Action + new: (...) => + +describe 'Const', -> + describe 'wraps', -> + test 'numbers', -> + got = Const.wrap 3 + assert.is.equal 'num', got.type + assert.is.equal 3, got.value + + test 'strings', -> + got = Const.wrap "im a happy string" + assert.is.equal 'str', got.type + assert.is.equal "im a happy string", got.value + + test 'Consts', -> + pi = Const 'num', 3.14 + got = Const.wrap pi + + assert.is.equal pi, got + + test 'Opdefs', -> + got = Const.wrap TestOp + + assert.is.equal 'opdef', got.type + assert.is.equal TestOp, got.value + + test 'Bultins', -> + got = Const.wrap TestAction + + assert.is.equal 'builtin', got.type + assert.is.equal TestAction, got.value + + test 'Scopes', -> + sub = Scope! + got = Const.wrap sub + + assert.is.equal 'scope', got.type + assert.is.equal sub, got.value + + test 'tables', -> + pi = Const 'num', 3.14 + got = Const.wrap { :pi } + + assert.is.equal 'scope', got.type + assert.is.equal pi, got.value\get 'pi' + + describe 'unwraps', -> + test 'get!, getc!', -> + assert.is.equal 3.14, (Const.num 3.14)\getc! + assert.is.equal 'hi', (Const.str 'hi')\getc! + assert.is.equal 'hi', (Const.sym 'hi')\getc! + + assert.is.equal 3.14, (Const.num 3.14)\get! + assert.is.equal 'hi', (Const.str 'hi')\get! + assert.is.equal 'hi', (Const.sym 'hi')\get! + + test 'with type assert', -> + assert.is.equal 3.14, (Const.num 3.14)\getc 'num' + assert.is.equal 'hi', (Const.str 'hi')\getc 'str' + assert.is.equal 'hi', (Const.sym 'hi')\getc 'sym' + assert.has_error -> (Const.num 3.14)\getc 'sym' + assert.has_error -> (Const.str 'hi')\getc 'num' + assert.has_error -> (Const.sym 'hi')\getc 'str' + + assert.is.equal 3.14, (Const.num 3.14)\get 'num' + assert.is.equal 'hi', (Const.str 'hi')\get 'str' + assert.is.equal 'hi', (Const.sym 'hi')\get 'sym' + assert.has_error -> (Const.num 3.14)\get 'sym' + assert.has_error -> (Const.str 'hi')\get 'num' + assert.has_error -> (Const.sym 'hi')\get 'str' + + describe 'checks equality', -> + test 'using the type', -> + val = Const 'num', 3 + assert.is.equal (Const.num 3), val + assert.not.equal (Const.str '3'), val + + val = Const 'str', 'hello' + assert.is.equal (Const.str 'hello'), val + assert.not.equal (Const.sym 'hello'), val + + test 'using the value', -> + val = Const 'num', 3 + assert.is.equal (Const.num 3), val + assert.not.equal (Const.num 4), val + + describe 'evaluates literal', -> + test 'constants to themselves', -> + assert_noop = (val) -> assert.is.equal val, val\eval! + + assert_noop Const.num 2 + assert_noop Const.str 'hello' + + test 'symbols in the scope', -> + scope = with Scope! + \set 'number', Const.num 3 + \set 'hello', Const.str "world" + \set 'goodbye', Const.sym "again" + + assert_eval = (sym, val) -> + const = Const.sym sym + assert.is.equal val, const\eval scope + + assert_eval 'number', Const.num 3 + assert_eval 'hello', Const.str "world" + assert_eval 'goodbye', Const.sym "again" + + describe 'quotes literals', -> + test 'as themselves', -> + assert_noop = (val) -> assert.is.equal val, val\quote! + + assert_noop Const.num 2 + assert_noop Const.str 'hello' + assert_noop Const.sym 'world' diff --git a/spec/parsing_spec.moon b/spec/parsing_spec.moon index 05f1f85..4bd5067 100644 --- a/spec/parsing_spec.moon +++ b/spec/parsing_spec.moon @@ -1,4 +1,5 @@ -import space, atom, expr, explist, sexpr, nexpr, program, comment from require 'parsing' +import space, atom, expr, explist, cell, program, comment from require 'parsing' +import Const from require 'base' import Logger from require 'logger' Logger.init 'silent' @@ -14,58 +15,81 @@ verify_parse_nope = (parser, str) -> describe 'atom parsing', -> test 'symbols', -> sym = verify_parse_nope atom, 'some-toast nope' - assert.is.equal 'sym', sym.atom_type - assert.is.equal 'some-toast', sym.raw + assert.is.equal 'sym', sym.type + assert.is.equal 'some-toast', sym\getc! assert.is.equal 'some-toast', sym\stringify! describe 'numbers', -> it 'parses ints', -> num = verify_parse_nope atom, '1234 nope' - assert.is.equal 'num', num.atom_type - assert.is.equal '1234', num.raw + assert.is.equal 'num', num.type + assert.is.equal 1234, num\getc! assert.is.equal '1234', num\stringify! it 'parses floats', -> num = verify_parse_nope atom, '0.123 nope' - assert.is.equal 'num', num.atom_type - assert.is.equal '0.123', num\stringify! + assert.is.equal 'num', num.type + assert.is.equal 0.123, num\getc! num = verify_parse_nope atom, '.123 nope' - assert.is.equal 'num', num.atom_type - assert.is.equal '.123', num\stringify! + assert.is.equal 'num', num.type + assert.is.equal 0.123, num\getc! num = verify_parse_nope atom, '0. nope' - assert.is.equal 'num', num.atom_type - assert.is.equal '0.', num\stringify! + assert.is.equal 'num', num.type + assert.is.equal 0, num\getc! describe 'strings', -> it 'parses double-quote strings', -> str = verify_parse_nope atom, '"help some stuff!" nope' - assert.is.equal 'strd', str.atom_type - assert.is.equal 'help some stuff!', str.raw - assert.is.equal '"help some stuff!"', str\stringify! + assert.is.equal 'str', str.type + assert.is.equal 'help some stuff!', str\getc! it 'parses single-quote strings', -> str = verify_parse_nope atom, "'help some stuff!' nope" - assert.is.equal 'strq', str.atom_type - assert.is.equal "help some stuff!", str.raw - assert.is.equal "'help some stuff!'", str\stringify! + assert.is.equal 'str', str.type + assert.is.equal "help some stuff!", str\getc! it 'handles escapes', -> - str = verify_parse_nope atom, '"string with \\"quote\\"s" nope' - assert.is.equal 'strd', str.atom_type - assert.is.equal 'string with \\"quote\\"s', str.raw - assert.is.equal '"string with \\"quote\\"s"', str\stringify! + str = verify_parse_nope atom, '"string with \\"quote\\"s and \\\\" nope' + assert.is.equal 'str', str.type + assert.is.equal 'string with \"quote\"s and \\', str\getc! -describe 'nexpr parsing', -> + str = verify_parse_nope atom, "'string with \\'quote\\'s and \\\\' nope" + assert.is.equal 'str', str.type + assert.is.equal "string with \'quote\'s and \\", str\getc! + +describe 'Cell', -> + test 'basic parsing', -> + node = verify_parse cell, '( 3 ok-yes + "friend" )' + + assert.is.equal 3, #node.children + assert.is.equal (Const.num 3), node.children[1] + assert.is.equal (Const.sym 'ok-yes'), node.children[2] + assert.is.equal (Const.str 'friend'), node.children[3] + + test 'tag parsing', -> + node = verify_parse cell, '([42]tagged 2)' + + assert.is.equal 2, #node.children + assert.is.equal (Const.num 42), node.tag + + test 'tag parsing with whitespace', -> + node = verify_parse cell, '([42] + tagged 2)' + + assert.is.equal 2, #node.children + assert.is.equal (Const.num 42), node.tag + +describe 'RootCell parsing', -> describe 'handles whitespace', -> verify = (str) -> - node = verify_parse nexpr, str + node = verify_parse program, str - assert.is.equal 'naked', node.style - assert.is.equal 2, #node - assert.is.equal '3', node[1].raw - assert.is.equal 'ok-yes', node[2].raw + assert.is.equal 2, #node.children + assert.is.equal (Const.num 3), node.children[1] + assert.is.equal (Const.sym 'ok-yes'), node.children[2] it 'at the front of the string', -> verify ' 3\tok-yes' @@ -76,25 +100,6 @@ describe 'nexpr parsing', -> it 'everywhere', -> verify ' 3\tok-yes\n' -describe 'sexpr', -> - test 'basic parsing', -> - node = verify_parse sexpr, '( 3 ok-yes - "friend" )' - - assert.is.equal '(', node.style - assert.is.equal 3, #node - assert.is.equal '3', node[1].raw - assert.is.equal 'ok-yes', node[2].raw - assert.is.equal 'friend', node[3].raw - - test 'tag parsing', -> - node = verify_parse sexpr, '([42]tagged 2)' - - assert.is.equal '(', node.style - assert.is.equal 2, #node - - assert.is.equal 42, node.tag - test 'whitespace', -> assert.is.equal ' ', space\match ' ' assert.is.equal '\n\t ', space\match '\n\t ' diff --git a/spec/registry_spec.moon b/spec/registry_spec.moon new file mode 100644 index 0000000..fd33981 --- /dev/null +++ b/spec/registry_spec.moon @@ -0,0 +1,66 @@ +import Registry from require 'registry' +import Const from require 'base' + +mk = -> + mock { + destroy: => + } + +describe 'registry', -> + registry = Registry! + + a, b, c = mk!, mk!, mk! + + it 'registers new items', -> + assert.is.equal (Const.num 1), registry\register a, nil + assert.is.equal (Const.num 2), registry\register b, nil + + it 'is empty until stepped', -> + assert.is.nil registry\prev Const.num 1 + assert.is.nil registry\prev Const.num 2 + assert.is.nil registry\prev Const.num 3 + + registry\step! + + it 'memorizes items', -> + assert.is.equal a, registry\prev Const.num 1 + assert.is.equal b, registry\prev Const.num 2 + assert.is.nil registry\prev Const.num 3 + + it 'destroyes lost items', -> + assert.is.equal (Const.num 2), registry\register b, Const.num 2 + assert.is.equal (Const.num 3), registry\register c, nil + + assert.is.equal a, registry\prev Const.num 1 + assert.is.equal b, registry\prev Const.num 2 + assert.is.nil registry\prev Const.num 3 + + assert.stub(a.destroy).was.not_called! + assert.stub(b.destroy).was.not_called! + assert.stub(c.destroy).was.not_called! + + registry\step! + + assert.stub(a.destroy).was.called_with a + assert.stub(b.destroy).was.not_called! + assert.stub(c.destroy).was.not_called! + + assert.is.nil registry\prev Const.num 1 + assert.is.equal b, registry\prev Const.num 2 + assert.is.equal c, registry\prev Const.num 3 + + it 'fills holes', -> + assert.is.equal (Const.num 1), registry\register a, nil + assert.is.equal (Const.num 2), registry\register b, Const.num 2 + assert.is.equal (Const.num 3), registry\register c, Const.num 3 + + assert.is.nil registry\prev Const.num 1 + assert.is.equal b, registry\prev Const.num 2 + assert.is.equal c, registry\prev Const.num 3 + + registry\step! + + assert.is.equal a, registry\prev Const.num 1 + assert.is.equal b, registry\prev Const.num 2 + assert.is.equal c, registry\prev Const.num 3 + |
