summaryrefslogtreecommitdiff
path: root/main/test/src/mill/define/MacroErrorTests.scala
blob: c8b140fa7c2a68e3f6cfab735cfc23c462cba8b8 (plain) (blame)
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
package mill.define

import utest._
import mill.{T, Module}
import mill.util.TestUtil
object MacroErrorTests extends TestSuite{

  val tests = Tests{

    'errors{
      val expectedMsg =
        "T{} members must be defs defined in a Cacher class/trait/object body"

      val err = compileError("object Foo extends TestUtil.BaseModule{ val x = T{1} }")
      assert(err.msg == expectedMsg)
    }

    'badParameterSets - {
      'command - {
        val e = compileError("""
          object foo extends mill.util.TestUtil.BaseModule{
            def w = T.command{1}
          }
          mill.define.Discover[foo.type]
        """)
        assert(
          e.msg.contains("`T.command` definitions must have 1 parameter list"),
          e.pos.contains("def w = ")
        )
      }
      'target - {
        val e = compileError("""
          object foo extends mill.util.TestUtil.BaseModule{
            def x() = T{1}
          }
          mill.define.Discover[foo.type]
        """)
        assert(
          e.msg.contains("`T{...}` definitions must have 0 parameter lists"),
          e.pos.contains("def x() = ")
        )
      }
      'input - {
        val e = compileError("""
          object foo extends mill.util.TestUtil.BaseModule{
            def y() = T.input{1}
          }
          mill.define.Discover[foo.type]
        """)
        assert(
          e.msg.contains("`T.input` definitions must have 0 parameter lists"),
          e.pos.contains("def y() = ")
        )
      }
      'sources - {
        val e = compileError("""
          object foo extends mill.util.TestUtil.BaseModule{
            def z() = T.sources{ammonite.ops.pwd}
          }
          mill.define.Discover[foo.type]
        """)
        assert(
          e.msg.contains("`T.sources` definitions must have 0 parameter lists"),
          e.pos.contains("def z() = ")
        )
      }
      'persistent - {
        val e = compileError("""
          object foo extends mill.util.TestUtil.BaseModule{
            def a() = T.persistent{1}
          }
          mill.define.Discover[foo.type]
        """)
        assert(
          e.msg.contains("`T.persistent` definitions must have 0 parameter lists"),
          e.pos.contains("def a() = ")
        )
      }
    }
    'badTmacro - {
      // Make sure we can reference values from outside the T{...} block as part
      // of our `Target#apply()` calls, but we cannot reference any values that
      // come from inside the T{...} block
      'pos - {
        val e = compileError("""
          val a = T{ 1 }
          val arr = Array(a)
          val b = {
            val c = 0
            T{
              arr(c)()
            }
          }
        """)
        assert(e.msg.contains(
          "Modules, Targets and Commands can only be defined within a mill Module")
        )
      }
      'neg - {

        val expectedMsg =
          "Target#apply() call cannot use `value n` defined within the T{...} block"
        val err = compileError("""new Module{
          def a = T{ 1 }
          val arr = Array(a)
          def b = {
            T{
              val n = 0
              arr(n)()
            }
          }
        }""")
        assert(err.msg == expectedMsg)
      }
      'neg2 - {

        val expectedMsg =
          "Target#apply() call cannot use `value x` defined within the T{...} block"
        val err = compileError("""new Module{
          def a = T{ 1 }
          val arr = Array(a)
          def b = {
            T{
              arr.map{x => x()}
            }
          }
        }""")
        assert(err.msg == expectedMsg)
      }
      'neg3{
        val borkedCachedDiamond1 = utest.compileError("""
          object borkedCachedDiamond1 {
            def up = T{ TestUtil.test() }
            def left = T{ TestUtil.test(up) }
            def right = T{ TestUtil.test(up) }
            def down = T{ TestUtil.test(left, right) }
          }
        """)
        assert(borkedCachedDiamond1.msg.contains(
          "Modules, Targets and Commands can only be defined within a mill Module")
        )
      }
    }
  }
}