aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-02-07 19:08:03 +0000
committers-ol <s-ol@users.noreply.github.com>2020-02-07 19:08:03 +0000
commit64f212a9b219f5eb9c75723b627ac501afe1899f (patch)
treefecbdbd578443a286b9c37a7f77a07f0ff62676e /spec
parent50% of functions (diff)
downloadalive-64f212a9b219f5eb9c75723b627ac501afe1899f.tar.gz
alive-64f212a9b219f5eb9c75723b627ac501afe1899f.zip
new AST approach, testing
Diffstat (limited to 'spec')
-rw-r--r--spec/ast_spec.moon91
-rw-r--r--spec/const_spec.moon123
-rw-r--r--spec/parsing_spec.moon97
-rw-r--r--spec/registry_spec.moon66
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
+