Skip to content

Commit

Permalink
Disallow function values in std.format (#145)
Browse files Browse the repository at this point in the history
For compatibility with jsonnet. Fixes #144.
  • Loading branch information
szeiger authored Feb 25, 2022
1 parent 0b8ce80 commit 256c037
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 22 deletions.
12 changes: 8 additions & 4 deletions sjsonnet/src/sjsonnet/Format.scala
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,18 @@ object Format{
case '%' => widenRaw(formatted, "%")
case _ =>

val value = formatted.label match{
case None => Materializer(values.cast[Val.Arr].force(i))
val raw = formatted.label match{
case None => values.cast[Val.Arr].force(i)
case Some(key) =>
values match{
case v: Val.Arr => Materializer(v.force(i))
case v: Val.Obj => Materializer(v.value(key, pos))
case v: Val.Arr => v.force(i)
case v: Val.Obj => v.value(key, pos)
}
}
val value = raw match {
case f: Val.Func => Error.fail("Cannot format function value", f)
case raw => Materializer(raw)
}
i += 1
value match{
case ujson.Str(s) => widenRaw(formatted, s)
Expand Down
2 changes: 2 additions & 0 deletions sjsonnet/src/sjsonnet/Val.scala
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ object Val{

def prettyName = "function"

override def exprErrorString: String = "Function"

override def asFunc: Func = this

def apply(argsL: Array[_ <: Lazy], namedNames: Array[String], outerPos: Position)(implicit ev: EvalScope): Val = {
Expand Down
1 change: 1 addition & 0 deletions sjsonnet/test/resources/db/error.format_func.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"%1s" % function() "foo"
41 changes: 23 additions & 18 deletions sjsonnet/test/src-jvm-native/sjsonnet/ErrorTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package sjsonnet
import utest._

object ErrorTests extends TestSuite{
val testSuiteRoot = os.pwd / "sjsonnet" / "test" / "resources" / "test_suite"
val testSuiteRoot = os.pwd / "sjsonnet" / "test" / "resources"
def eval(p: os.Path, noStaticErrors: Boolean) = {
val out = new StringBuffer()
val interp = new Interpreter(
Expand All @@ -17,19 +17,12 @@ object ErrorTests extends TestSuite{
)
interp.interpret(os.read(p), OsPath(p)).left.map(s => out.toString + s)
}
def check(expected: String, noStaticErrors: Boolean = false)(implicit tp: utest.framework.TestPath) = {
val res = eval(testSuiteRoot / s"error.${tp.value.mkString(".")}.jsonnet", noStaticErrors)
def check(expected: String, noStaticErrors: Boolean = false, suite: String = "test_suite")(implicit tp: utest.framework.TestPath) = {
val res = eval(testSuiteRoot / suite / s"error.${tp.value.mkString(".")}.jsonnet", noStaticErrors)

assert(res == Left(expected))
}

def checkImports(expected: String)(implicit tp: utest.framework.TestPath) = {
val res = eval(os.pwd / "sjsonnet" / "test" / "resources" / "imports" / s"error.${tp.value.mkString(".")}.jsonnet", false)

assert(res == Left(expected))
}


val tests = Tests{
test("01") - check(
"""sjsonnet.Error: foo
Expand Down Expand Up @@ -289,28 +282,40 @@ object ErrorTests extends TestSuite{
)
}

test("import_wrong_nr_args") - checkImports(
test("import_wrong_nr_args") - check(
"""|sjsonnet.Error: Function parameter y not bound in call
| at [Apply1].(sjsonnet/test/resources/imports/error.import_wrong_nr_args.jsonnet:3:6)
|""".stripMargin
|""".stripMargin,
suite = "imports"
)

test("wrong_named_arg") - checkImports(
test("wrong_named_arg") - check(
"""|sjsonnet.Error: Function has no parameter z
| at [Apply].(sjsonnet/test/resources/imports/error.wrong_named_arg.jsonnet:3:6)
|""".stripMargin
|""".stripMargin,
suite = "imports"
)

test("too_many_arg") - checkImports(
test("too_many_arg") - check(
"""|sjsonnet.Error: Too many args, function has 2 parameter(s)
| at [Apply].(sjsonnet/test/resources/imports/error.too_many_arg.jsonnet:3:6)
|""".stripMargin
|""".stripMargin,
suite = "imports"
)

test("too_many_arg_with_named_arg") - checkImports(
test("too_many_arg_with_named_arg") - check(
"""|sjsonnet.Error: binding parameter a second time: x
| at [Apply].(sjsonnet/test/resources/imports/error.too_many_arg_with_named_arg.jsonnet:2:2)
|""".stripMargin
|""".stripMargin,
suite = "imports"
)

test("format_func") - check(
"""|sjsonnet.Error: Cannot format function value
| at [Function].(sjsonnet/test/resources/db/error.format_func.jsonnet:1:9)
| at [ApplyBuiltin1].(sjsonnet/test/resources/db/error.format_func.jsonnet:1:7)
|""".stripMargin,
suite = "db"
)
}
}

0 comments on commit 256c037

Please sign in to comment.