summaryrefslogtreecommitdiff
path: root/main/test/src/util/TestEvaluator.scala
blob: 45bc41d9e24b5e85b021acbabfaa6abae873f4e8 (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
package mill.util

import mill.define.{Input, Target, Task}
import mill.api.Result.OuterStack
import mill.eval.{Evaluator, Result}
import mill.api.Strict.Agg
import utest.assert
import utest.framework.TestPath

import language.experimental.macros
object TestEvaluator{
  val externalOutPath = os.pwd / 'target / 'external


  def static(module: => TestUtil.BaseModule)(implicit fullName: sourcecode.FullName) = {
    new TestEvaluator(module)(fullName, TestPath(Nil))
  }
}

class TestEvaluator(module: => TestUtil.BaseModule, failFast: Boolean = false)
                                            (implicit fullName: sourcecode.FullName,
                                             tp: TestPath){
  val outPath =  TestUtil.getOutPath()

//  val logger = DummyLogger
  val logger = new PrintLogger(
    colored = true, disableTicker=false,
    ammonite.util.Colors.Default, System.out, System.out, System.err, System.in, debugEnabled = false
 )
  val evaluator = new Evaluator(Ctx.defaultHome, outPath, TestEvaluator.externalOutPath, module, logger, failFast = failFast)

  def apply[T](t: Task[T]): Either[Result.Failing[T], (T, Int)] = {
    val evaluated = evaluator.evaluate(Agg(t))

    if (evaluated.failing.keyCount == 0) {
      Right(
        Tuple2(
          evaluated.rawValues.head.asInstanceOf[Result.Success[T]].value,
          evaluated.evaluated.collect {
            case t: Target[_]
              if module.millInternal.targets.contains(t)
              && !t.isInstanceOf[Input[_]]
              && !t.ctx.external => t
            case t: mill.define.Command[_] => t
          }.size
        ))
    } else {
      Left(
        evaluated.failing.lookupKey(evaluated.failing.keys().next).items.next()
          .asInstanceOf[Result.Failing[T]]
      )
    }
  }

  def fail(target: Target[_], expectedFailCount: Int, expectedRawValues: Seq[Result[_]]) = {

    val res = evaluator.evaluate(Agg(target))

    val cleaned = res.rawValues.map{
      case Result.Exception(ex, _) => Result.Exception(ex, new OuterStack(Nil))
      case x => x
    }

    assert(
      cleaned == expectedRawValues,
      res.failing.keyCount == expectedFailCount
    )

  }

  def check(targets: Agg[Task[_]], expected: Agg[Task[_]]) = {
    val evaluated = evaluator.evaluate(targets)
      .evaluated
      .flatMap(_.asTarget)
      .filter(module.millInternal.targets.contains)
      .filter(!_.isInstanceOf[Input[_]])
    assert(evaluated == expected)
  }

}