summaryrefslogblamecommitdiff
path: root/core/src/test/scala/forge/EvaluationTests.scala
blob: b58d5ccc1e3addbace151c2d1ac2fc2011ff01fa (plain) (tree)
1
2
3
4
5
6
7
8
9
10

             
 
                      
              
                               



                                         
                                 
                   
                       
 
                                                                    
                                                                          


                                                                                   
                    

                                  
         


                                                   
 
                                                                                                     


                                                                                                     

                                            

                                                            
           
 






                                                                                                       



                          
                                          
                                             
                                                             


                                                                  
                                                             


                     
                                     
                                                             

                         
                                                         

                       
                                                             


                           
                                           
                                   
                                                                     

                         
                                                                 

                       
                                                                     
 
                                                       
 
                                                                 


                        
                                        
                                                                          

                         
                                                         


                                                                                    
                                                                          

                         
                                                               

                          
                                                                


                            
                                            

                                                              
                                                                          

                         
                                                                      


                                                                                    
                                                                          

                         
                                                                      

                          
                                                                      
       
 




                                                                                    
 

                                                                    
 







                                                                                 
     

 

   
package forge


import forge.util.OSet
import utest._
import utest.framework.TestPath

object EvaluationTests extends TestSuite{

  val tests = Tests{
    val graphs = new TestGraphs()
    import graphs._
    'evaluateSingle - {

      class Checker[T: Discovered](base: T)(implicit tp: TestPath) {
        val workspace = ammonite.ops.pwd / 'target / 'workspace / tp.value
        ammonite.ops.rm(ammonite.ops.Path(workspace, ammonite.ops.pwd))
        // Make sure data is persisted even if we re-create the evaluator each time
        def evaluator = new Evaluator(
          workspace,

          Discovered.mapping(base)
        )
        def apply(target: Target[_], expValue: Any,
                  expEvaled: OSet[Target[_]],
                  extraEvaled: Int = 0) = {

          val Evaluator.Results(returnedValues, returnedEvaluated) = evaluator.evaluate(OSet(target))

          val (matchingReturnedEvaled, extra) = returnedEvaluated.items.partition(expEvaled.contains)

          assert(
            returnedValues == Seq(expValue),
            matchingReturnedEvaled.toSet == expEvaled.toSet,
            extra.length == extraEvaled
          )

          // Second time the value is already cached, so no evaluation needed
          val Evaluator.Results(returnedValues2, returnedEvaluated2) = evaluator.evaluate(OSet(target))
          assert(
            returnedValues2 == returnedValues,
            returnedEvaluated2 == OSet()
          )
        }
      }

      'singleton - {
        import singleton._
        val check = new Checker(singleton)
        // First time the target is evaluated
        check(single, expValue = 0, expEvaled = OSet(single))

        single.counter += 1
        // After incrementing the counter, it forces re-evaluation
        check(single, expValue = 1, expEvaled = OSet(single))
      }
      'pair - {
        import pair._
        val check = new Checker(pair)
        check(down, expValue = 0, expEvaled = OSet(up, down))

        down.counter += 1
        check(down, expValue = 1, expEvaled = OSet(down))

        up.counter += 1
        check(down, expValue = 2, expEvaled = OSet(up, down))
      }
      'anonTriple - {
        import anonTriple._
        val check = new Checker(anonTriple)
        val middle = down.inputs(0)
        check(down, expValue = 0, expEvaled = OSet(up, middle, down))

        down.counter += 1
        check(down, expValue = 1, expEvaled = OSet(middle, down))

        up.counter += 1
        check(down, expValue = 2, expEvaled = OSet(up, middle, down))

        middle.asInstanceOf[TestUtil.Test].counter += 1

        check(down, expValue = 3, expEvaled = OSet(middle, down))
      }
      'diamond - {
        import diamond._
        val check = new Checker(diamond)
        check(down, expValue = 0, expEvaled = OSet(up, left, right, down))

        down.counter += 1
        check(down, expValue = 1, expEvaled = OSet(down))

        up.counter += 1
        // Increment by 2 because up is referenced twice: once by left once by right
        check(down, expValue = 3, expEvaled = OSet(up, left, right, down))

        left.counter += 1
        check(down, expValue = 4, expEvaled = OSet(left, down))

        right.counter += 1
        check(down, expValue = 5, expEvaled = OSet(right, down))
      }
      'anonDiamond - {
        import anonDiamond._
        val check = new Checker(anonDiamond)
        val left = down.inputs(0).asInstanceOf[TestUtil.Test]
        val right = down.inputs(1).asInstanceOf[TestUtil.Test]
        check(down, expValue = 0, expEvaled = OSet(up, left, right, down))

        down.counter += 1
        check(down, expValue = 1, expEvaled = OSet(left, right, down))

        up.counter += 1
        // Increment by 2 because up is referenced twice: once by left once by right
        check(down, expValue = 3, expEvaled = OSet(up, left, right, down))

        left.counter += 1
        check(down, expValue = 4, expEvaled = OSet(left, right, down))

        right.counter += 1
        check(down, expValue = 5, expEvaled = OSet(left, right, down))
      }

      'bigSingleTerminal - {
        import bigSingleTerminal._
        val check = new Checker(bigSingleTerminal)

        check(j, expValue = 0, expEvaled = OSet(a, b, e, f, i, j), extraEvaled = 22)

        j.counter += 1
        check(j, expValue = 1, expEvaled = OSet(j), extraEvaled = 3)

        i.counter += 1
        // increment value by 2 because `i` is used twice on the way to `j`
        check(j, expValue = 3, expEvaled = OSet(j, i), extraEvaled = 8)

        b.counter += 1
        // increment value by 4 because `b` is used four times on the way to `j`
        check(j, expValue = 7, expEvaled = OSet(b, e, f, i, j), extraEvaled = 20)
      }
    }


  }
}