aboutsummaryrefslogtreecommitdiffstats
path: root/spec/lib/array_spec.moon
blob: 130138cc8a8b1a2ae0ed8ac5d18bcfef7b0b92f6 (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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import TestPilot from require 'spec.test_setup'
import T, Array from require 'alv'

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

  svec3 = Array 3, T.str

  it "can contain any type", ->
    COPILOT\eval_once '[1 2 3]'
    COPILOT\eval_once '[true false]'
    COPILOT\eval_once '["a"]'
    COPILOT\eval_once '[[1 2] [3 4]]'

  it "cannot contain mixed types", ->
    err = assert.has.error -> COPILOT\eval_once '[1 false]'
    assert.matches "argument error: couldn't match arguments", err

  describe "(set)", ->
    it "can swap values", ->
      rt = COPILOT\eval_once '(set ["f" "b" "c"] 0 "a")'
      assert.is.true rt\is_const!
      assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result

    it "checks value type", ->
      err = assert.has.error -> COPILOT\eval_once '(set [1] 0 "a")'
      assert.matches "expected value of type num, not str", err

    it "checks index range", ->
      err = assert.has.error -> COPILOT\eval_once '(set [1 2] -1 0)'
      assert.matches "index '%-1' out of range!", err

      COPILOT\eval_once '(set [1 2] 0 0)'

      COPILOT\eval_once '(set [1 2] 1 0)'

      err = assert.has.error -> COPILOT\eval_once '(set [1 2] 2 0)'
      assert.matches "index '2' out of range!", err

  describe "(get)", ->
    it "can get a value", ->
      rt = COPILOT\eval_once '(get [1 2] 0)'
      assert.is.true rt\is_const!
      assert.is.equal '<num= 1>', tostring rt.result

    it "checks index range", ->
      err = assert.has.error -> COPILOT\eval_once '(get [1 2] -1)'
      assert.matches "index '%-1' out of range!", err

      COPILOT\eval_once '(get [1 2] 0)'

      COPILOT\eval_once '(get [1 2] 1)'

      err = assert.has.error -> COPILOT\eval_once '(get [1 2] 2)'
      assert.matches "index '2' out of range!", err

  describe '(head)', ->
    it "can peek a value", ->
      rt = COPILOT\eval_once '(head [1 2])'
      assert.is.true rt\is_const!
      assert.is.equal '<num= 1>', tostring rt.result

  describe '(tail)', ->
    it "gets rest of an array", ->
      rt = COPILOT\eval_once '(tail [1])'
      assert.is.true rt\is_const!
      assert.is.same (Array 0, T.num), rt.result.type
      assert.is.same {}, rt.result!

      rt = COPILOT\eval_once '(tail [1 2])'
      assert.is.true rt\is_const!
      assert.is.same (Array 1, T.num), rt.result.type
      assert.is.same { 2 }, rt.result!

      rt = COPILOT\eval_once '(tail [1 2 3 4])'
      assert.is.true rt\is_const!
      assert.is.same (Array 3, T.num), rt.result.type
      assert.is.same { 2, 3, 4 }, rt.result!

  describe '(prepend)', ->
    it "prepends to array", ->
      rt = COPILOT\eval_once '(prepend [2] 1)'
      assert.is.true rt\is_const!
      assert.is.same (Array 2, T.num), rt.result.type
      assert.is.same { 1, 2 }, rt.result!

      rt = COPILOT\eval_once '(prepend [2 3 4] 1)'
      assert.is.true rt\is_const!
      assert.is.same (Array 4, T.num), rt.result.type
      assert.is.same { 1, 2, 3, 4 }, rt.result!

  describe "(insert)", ->
    it "can insert a value", ->
      rt = COPILOT\eval_once '(insert ["b" "c"] 0 "a")'
      assert.is.true rt\is_const!
      assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result

      rt = COPILOT\eval_once '(insert ["a" "c"] 1 "b")'
      assert.is.true rt\is_const!
      assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result

      rt = COPILOT\eval_once '(insert ["a" "b"] 2 "c")'
      assert.is.true rt\is_const!
      assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result

    it "checks index range", ->
      err = assert.has.error -> COPILOT\eval_once '(insert [1 2] -1 0)'
      assert.matches "index '%-1' out of range!", err

      COPILOT\eval_once '(insert [1 2] 0 0)'

      COPILOT\eval_once '(insert [1 2] 1 0)'

      COPILOT\eval_once '(insert [1 2] 2 0)'

      err = assert.has.error -> COPILOT\eval_once '(insert [1 2] 3 0)'
      assert.matches "index '3' out of range!", err

  describe "(remove)", ->
    it "can remove a value", ->
      rt = COPILOT\eval_once '(remove ["d" "a" "b" "c"] 0)'
      assert.is.true rt\is_const!
      assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result

      rt = COPILOT\eval_once '(remove ["a" "b" "c" "d"] 3)'
      assert.is.true rt\is_const!
      assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result

    it "checks index range", ->
      err = assert.has.error -> COPILOT\eval_once '(remove [1 2 3] -1)'
      assert.matches "index '%-1' out of range!", err

      err = assert.has.error -> COPILOT\eval_once '(remove [1 2 3] 3)'
      assert.matches "index '3' out of range!", err

  it "can be concatenated with (concat)", ->
    rt = COPILOT\eval_once '(concat ["a" "b"] ["c"])'
    assert.is.true rt\is_const!
    assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result

  it "size can be read using (size)", ->
    rt = COPILOT\eval_once '(size [1])'
    assert.is.true rt\is_const!
    assert.is.equal '<num= 1>', tostring rt.result

    rt = COPILOT\eval_once '(size [1 2 3])'
    assert.is.true rt\is_const!
    assert.is.equal '<num= 3>', tostring rt.result