Skip to content

Commit

Permalink
Merge pull request #115 from softwaremill/cache-obj
Browse files Browse the repository at this point in the history
Avoid repeatedly evaluating the source if it's a complex expression
  • Loading branch information
adamw authored Sep 11, 2022
2 parents 213a8e8 + 93af704 commit 032b503
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import scala.reflect.ClassTag

package object quicklens {

extension [S, A](inline obj: S)
// #114: obj shouldn't be inline since we want to reference the parameter by-name, rather then embedding the whole
// expression whenever obj is used; this is especially important for chained .modify invocations
extension [S, A](obj: S)
/** Create an object allowing modifying the given (deeply nested) field accessible in a `case class` hierarchy via
* `path` on the given `obj`.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.softwaremill.quicklens.test

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class CompileTimeTest extends AnyFlatSpec with Matchers {
// #114
it should "not compile for too long in case of chained modify invocations" in {
val start = System.currentTimeMillis()
assertDoesNotCompile("""
case class B(a1: Double, a2: Double, a3: Double, a4: Double, a5: Double)
case class C(b: B)
import com.softwaremill.quicklens.*
val c = C(B(1, 1, 1, 1, 1))
c
.modify(_.b.a1).setTo("")
.modify(_.b.a2).setTo("")
.modify(_.b.a3).setTo("")
.modify(_.b.a4).setTo("")
.modify(_.b.a5).setTo("")
""")
val end = System.currentTimeMillis()
(end - start) shouldBe <=(5000L) // that's a lot anyway
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.softwaremill.quicklens

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class RepeatedModifyTest extends AnyFlatSpec with Matchers {
import RepeatedModifyTest._

it should "properly handle repeated modify invocations for different fields" in {
val c = C(B(1, 1, 1, 1, 1))
c
.modify(_.b.a1)
.setTo(0.0d)
.modify(_.b.a2)
.setTo(0.0d)
.modify(_.b.a3)
.setTo(0.0d)
.modify(_.b.a4)
.setTo(0.0d)
.modify(_.b.a5)
.setTo(0.0d) shouldBe C(B(0, 0, 0, 0, 0))
}

it should "properly handle repeated modify invocations for the same field" in {
val c = C(B(1, 1, 1, 1, 1))
c
.modify(_.b.a1)
.setTo(0.0d)
.modify(_.b.a1)
.setTo(1.0d)
.modify(_.b.a1)
.setTo(2.0d)
.modify(_.b.a1)
.setTo(3.0d)
.modify(_.b.a1)
.setTo(4.0d) shouldBe C(B(4, 1, 1, 1, 1))
}
}

object RepeatedModifyTest {
case class B(a1: Double, a2: Double, a3: Double, a4: Double, a5: Double)
case class C(b: B)
}

0 comments on commit 032b503

Please sign in to comment.