aboutsummaryrefslogtreecommitdiffstats
path: root/spec/lib/struct_spec.moon
blob: 0c8ce5b3e6a033c7539ccde915937fbdc55d63b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import TestPilot from require 'spec.test_setup'
import T, Struct from require 'alv'

describe "struct", ->
  test = TestPilot '', '(import* struct)\n'

  ab = Struct { a: T.num, b: T.bool }

  describe "literal", ->
    it "can't be empty", ->
      err = assert.has.error -> COPILOT\eval_once '{}'
      assert.matches "syntax error: struct literal can't be empty", err

    it "can't have uneven args", ->
      err = assert.has.error -> COPILOT\eval_once '{3}'
      assert.matches "syntax error: struct literal must have even number of values", err

  describe "(set)", ->
    it "can update values", ->
      rt = COPILOT\eval_once '(set {"a" 1 "b" false} "a" 2)'
      assert.is.true rt\is_const!
      assert.is.equal ab\mk_const({ a: 2, b: false }), rt.result

    it "cannot add members", ->
      err = assert.has.error -> COPILOT\eval_once '(set {"a" 1} "b" 2)'
      assert.matches "{a: num} has no 'b' key", err

    it "checks value type", ->
      err = assert.has.error -> COPILOT\eval_once '(set {"a" 1} "a" "str")'
      assert.matches "expected value for key 'a' to be num, not str", err

  describe "(get)", ->
    it "can get values", ->
      rt = COPILOT\eval_once '(get {"a" 1 "b" false} "a")'
      assert.is.true rt\is_const!
      assert.is.equal '<num= 1>', tostring rt.result

    it "checks keys", ->
      err = assert.has.error -> COPILOT\eval_once '(get {"a" 1} "b")'
      assert.matches "has no 'b' key", err

  describe "(getdef)", ->
    it "can get values", ->
      rt = COPILOT\eval_once '(getdef {"a" 1 "b" false} "a" 4)'
      assert.is.true rt\is_const!
      assert.is.equal '<num= 1>', tostring rt.result

    it "falls back", ->
      rt = COPILOT\eval_once '(getdef {"b" false} "a" 4)'
      assert.is.true rt\is_const!
      assert.is.equal '<num= 4>', tostring rt.result

    it "checks types", ->
      err = assert.has.error -> COPILOT\eval_once '(getdef {"a" 1} "a" true)'
      assert.matches "default needs to be of same type as indexed", err

  describe "(insert)", ->
    it "can add members", ->
      rt = COPILOT\eval_once '(insert {"b" true} "a" 1)'
      assert.is.true rt\is_const!
      assert.is.equal ab\mk_const({ a: 1, b: true }), rt.result

    it "doesn't clobber existing members", ->
      err = assert.has.error -> COPILOT\eval_once '(insert {"a" 1} "a" 2)'
      assert.matches "key 'a' already exists in value of type {a: num}", err

  describe "(remove)", ->
    it "can remove members", ->
      rt = COPILOT\eval_once '(remove {"a" 1 "b" false "c" "abc"} "c")'
      assert.is.true rt\is_const!
      assert.is.equal ab\mk_const({ a: 1, b: false }), rt.result

    it "checks keys", ->
      err = assert.has.error -> COPILOT\eval_once '(remove {"a" 1} "b")'
      assert.matches "has no 'b' key", err