Skip to content

Commit

Permalink
[GHI-99] - Do not allow duplicate field in object in list list compre…
Browse files Browse the repository at this point in the history
…hension
  • Loading branch information
edgar-db committed Nov 9, 2020
1 parent 2c909ba commit 5259355
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 26 deletions.
14 changes: 14 additions & 0 deletions sjsonnet/src/sjsonnet/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,20 @@ object Parser{
exprs(preLocals.length)
val postLocals = exprs.drop(preLocals.length+1).takeWhile(_.isInstanceOf[Expr.Member.BindStmt])
.map(_.asInstanceOf[Expr.Member.BindStmt])

/*
* Prevent duplicate fields in list comprehension. See: https://github.com/databricks/sjsonnet/issues/99
*
* If comps._1 is a forspec with value greater than one lhs cannot be a Expr.Str
* Otherwise the field value will be overriden by the multiple iterations of forspec
*/
if (lhs.isInstanceOf[Expr.Str] &&
comps._1.isInstanceOf[Expr.ForSpec] &&
comps._1.asInstanceOf[Expr.ForSpec].cond.isInstanceOf[Expr.Arr] &&
comps._1.asInstanceOf[Expr.ForSpec].cond.asInstanceOf[Expr.Arr].value.length > 1
) {
Fail.opaque(s"""no duplicate field: "${lhs.asInstanceOf[Expr.Str].value}" """)
}
Expr.ObjBody.ObjComp(preLocals, lhs, rhs, postLocals, comps._1, comps._2)
}

Expand Down
6 changes: 6 additions & 0 deletions sjsonnet/test/src/sjsonnet/EvaluatorTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -328,5 +328,11 @@ object EvaluatorTests extends TestSuite{
eval("{ ['foo']+: x for x in []}", false) ==> ujson.Obj()
eval("{ ['foo']+: x for x in [1]}", false) ==> ujson.Obj("foo" -> 1)
}
test("givenNoDuplicateFieldsInListComprehension1_expectSuccess") {
eval("""{ ["bar"]: x for x in [-876.89]}""") ==> ujson.Obj("bar" -> -876.89)
}
test("givenNoDuplicateFieldsInListComprehension2_expectSuccess") {
eval("""{ ["bar_" + x]: x for x in [5,12]}""") ==> ujson.Obj("bar_5" -> 5, "bar_12" -> 12)
}
}
}
29 changes: 3 additions & 26 deletions sjsonnet/test/src/sjsonnet/ParserTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,12 @@ object ParserTests extends TestSuite{

parse("1 + 2 * 3") ==>
BinaryOp(2, Num(0, 1), BinaryOp.`+`, BinaryOp(6, Num(4, 2), BinaryOp.`*`, Num(8, 3)))
//
// parse("2 | 3 * 2 + 3 | 4") ==>
// BinaryOp(
// BinaryOp(
// Num(2),
// "|",
// BinaryOp(
// BinaryOp(
// Num(3),
// "*",
// Num(2)
// ),
// "+",
// Num(3)
// )
// ),
// "|",
// Num(4)
// )
// }
//
// 'array - {
// parse("[]") ==> Arr(Nil)
// parse("[true]") ==> Arr(Seq(True))
// parse("[1, 2]") ==> Arr(Seq(Num(1), Num(2)))
// parse("[1, [2, 3], 4]") ==> Arr(Seq(Num(1), Arr(Seq(Num(2), Num(3))), Num(4)))
}
test("duplicateFields") {
parseErr("{ a: 1, a: 2 }") ==> """Expected no duplicate field: a:1:14, found "}""""
}
test("givenDuplicateFieldsInListComprehension_expectError") {
parseErr("""{ ["bar"]: x for x in [1, 2]}""") ==> """Expected no duplicate field: "bar" :1:29, found "}""""
}
}
}

0 comments on commit 5259355

Please sign in to comment.