aboutsummaryrefslogtreecommitdiffstats
path: root/spec/lib/builtins/cond_spec.moon
blob: b075f8b54227255ee8069807a822ee88c4bc394b (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
import TestPilot from require 'spec.test_setup'
import T, Struct, Array, Constant from require 'alv'

describe "if", ->
  COPILOT = TestPilot!

  it "checks truthiness", ->
    for truthy in *{'true', '1', '-1', '1234', '[1 2 3]', '"test"', '""'}
      with COPILOT\eval_once "(if #{truthy} 'yes' 'no')"
        assert.is.true \is_const!
        assert.is.equal 'yes', .result!

    for falsy in *{'false', '0'}
      with COPILOT\eval_once "(if #{falsy} 'yes' 'no')"
        assert.is.true \is_const!
        assert.is.equal 'no', .result!

  it "can be used without else clause", ->
    with COPILOT\eval_once '(if true "yes")'
      assert.is.true \is_const!
      assert.is.equal 'yes', .result!

    with COPILOT\eval_once '(if false "yes")'
      assert.is.true \is_const!
      assert.is.equal nil, .result

  it "doesn't evaluate the untaken branch", ->
    with COPILOT\eval_once '(if true "yes" (error/doesnt-exist))'
      assert.is.true \is_const!
      assert.is.equal 'yes', .result!

    with COPILOT\eval_once '(if false (error/doesnt-exist) "no")'
      assert.is.true \is_const!
      assert.is.equal 'no', .result!

  it "errors on non-const choice", ->
    err = assert.has.error ->
      COPILOT\eval_once '(import* time) (if (ramp 1) "yes" "no")'
    assert.matches "'if'%-expression needs to be constant", err

  it "forwards any result", ->
    with COPILOT\eval_once '
        (import* time)
        (if true (every 1 [1 2 3]))'
      assert.is.false \is_const!
      assert.is.equal '<num[3]! nil>', tostring .result

describe "when", ->
  COPILOT = TestPilot!

  it "checks truthiness", ->
    for truthy in *{'true', '1', '-1', '1234', '[1 2 3]', '"test"', '""'}
      with COPILOT\eval_once "(when #{truthy} 'yes')"
        assert.is.true \is_const!
        assert.is.equal 'yes', .result!

    for falsy in *{'false', '0'}
      with COPILOT\eval_once "(when #{falsy} 'yes')"
        assert.is.true \is_const!
        assert.is.nil .result

  it "doesn't evaluate if falsy", ->
    with COPILOT\eval_once '(when false (error/doesnt-exist))'
      assert.is.true \is_const!
      assert.is.nil, .result

    with COPILOT\eval_once '
        (when false
          (error/doesnt-exist)
          (error/doesnt-exist)
          (error/doesnt-exist))'
      assert.is.true \is_const!
      assert.is.nil, .result

  it "errors on non-const choice", ->
    err = assert.has.error ->
      COPILOT\eval_once '(import* time) (when (ramp 1) 1 2 3)'
    assert.matches "'when'%-expression needs to be constant", err

  it "forwards any result", ->
    with COPILOT\eval_once '
        (import* time)
        (when true
          (every 1 [1 2 3])
          1 2 3)'
      assert.is.false \is_const!
      assert.is.equal '<num~ 3>', tostring .result

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


describe "switch", ->
  COPILOT = TestPilot!

  it "switches by num", ->
    for key, val in pairs {[0]: 11, [0.5]: 11, 22, 33, 11}
      with COPILOT\eval_once "(switch #{key} 11 22 33)"
        assert.is.true \is_const!
        assert.is.equal val, .result!

  it "switches arrays by num", ->
    for key, val in pairs {[0]: 11, [0.5]: 11, 22, 33, 11}
      with COPILOT\eval_once "(switch #{key} [11 22 33])"
        assert.is.true \is_const!
        assert.is.equal val, .result!