Skip to content

Commit

Permalink
truth table test for all bool expressions
Browse files Browse the repository at this point in the history
Just to put them all in one place, generate a table of all possible 2
and 3 part boolean expressions.
  • Loading branch information
jbardin committed Dec 2, 2024
1 parent 7947f74 commit dc88dcc
Showing 1 changed file with 164 additions and 0 deletions.
164 changes: 164 additions & 0 deletions hclsyntax/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2914,3 +2914,167 @@ func TestParseExpression_incompleteFunctionCall(t *testing.T) {
})
}
}

func TestAllBoolExpressions(t *testing.T) {
inputs := map[string]cty.Value{
// truth table for all boolean expressions
"true && true": cty.True,
"true || true": cty.True,
"true && false": cty.False,
"true || false": cty.True,
"true && unknown": cty.DynamicVal,
"true || unknown": cty.True,
"false && true": cty.False,
"false || true": cty.True,
"false && false": cty.False,
"false || false": cty.False,
"false && unknown": cty.False,
"false || unknown": cty.DynamicVal,
"unknown && true": cty.DynamicVal,
"unknown || true": cty.True,
"unknown && false": cty.False,
"unknown || false": cty.DynamicVal,
"unknown && unknown": cty.DynamicVal,
"unknown || unknown": cty.DynamicVal,

// truth table for all possible combinations 3 part boolean expressions
"true && true && true": cty.True,
"true || true && true": cty.True,
"true || true || true": cty.True,
"true && true || true": cty.True,
"true && true && false": cty.False,
"true || true && false": cty.True,
"true || true || false": cty.True,
"true && true || false": cty.True,
"true && true && unknown": cty.DynamicVal,
"true || true && unknown": cty.True,
"true || true || unknown": cty.True,
"true && true || unknown": cty.True,
"true && false && true": cty.False,
"true || false && true": cty.True,
"true || false || true": cty.True,
"true && false || true": cty.True,
"true && false && false": cty.False,
"true || false && false": cty.True,
"true || false || false": cty.True,
"true && false || false": cty.False,
"true && false && unknown": cty.False,
"true || false && unknown": cty.True,
"true || false || unknown": cty.True,
"true && false || unknown": cty.DynamicVal,
"true && unknown && true": cty.DynamicVal,
"true || unknown && true": cty.True,
"true || unknown || true": cty.True,
"true && unknown || true": cty.True,
"true && unknown && false": cty.False,
"true || unknown && false": cty.True,
"true || unknown || false": cty.True,
"true && unknown || false": cty.DynamicVal,
"true && unknown && unknown": cty.DynamicVal,
"true || unknown && unknown": cty.True,
"true || unknown || unknown": cty.True,
"true && unknown || unknown": cty.DynamicVal,
"false && true && true": cty.False,
"false || true && true": cty.True,
"false || true || true": cty.True,
"false && true || true": cty.True,
"false && true && false": cty.False,
"false || true && false": cty.False,
"false || true || false": cty.True,
"false && true || false": cty.False,
"false && true && unknown": cty.False,
"false || true && unknown": cty.DynamicVal,
"false || true || unknown": cty.True,
"false && true || unknown": cty.DynamicVal,
"false && false && true": cty.False,
"false || false && true": cty.False,
"false || false || true": cty.True,
"false && false || true": cty.True,
"false && false && false": cty.False,
"false || false && false": cty.False,
"false || false || false": cty.False,
"false && false || false": cty.False,
"false && false && unknown": cty.False,
"false || false && unknown": cty.False,
"false || false || unknown": cty.DynamicVal,
"false && false || unknown": cty.DynamicVal,
"false && unknown && true": cty.False,
"false || unknown && true": cty.DynamicVal,
"false || unknown || true": cty.True,
"false && unknown || true": cty.True,
"false && unknown && false": cty.False,
"false || unknown && false": cty.False,
"false || unknown || false": cty.DynamicVal,
"false && unknown || false": cty.False,
"false && unknown && unknown": cty.False,
"false || unknown && unknown": cty.DynamicVal,
"false || unknown || unknown": cty.DynamicVal,
"false && unknown || unknown": cty.DynamicVal,
"unknown && true && true": cty.DynamicVal,
"unknown || true && true": cty.True,
"unknown || true || true": cty.True,
"unknown && true || true": cty.True,
"unknown && true && false": cty.False,
"unknown || true && false": cty.DynamicVal,
"unknown || true || false": cty.True,
"unknown && true || false": cty.DynamicVal,
"unknown && true && unknown": cty.DynamicVal,
"unknown || true && unknown": cty.DynamicVal,
"unknown || true || unknown": cty.True,
"unknown && true || unknown": cty.DynamicVal,
"unknown && false && true": cty.False,
"unknown || false && true": cty.DynamicVal,
"unknown || false || true": cty.True,
"unknown && false || true": cty.True,
"unknown && false && false": cty.False,
"unknown || false && false": cty.DynamicVal,
"unknown || false || false": cty.DynamicVal,
"unknown && false || false": cty.False,
"unknown && false && unknown": cty.False,
"unknown || false && unknown": cty.DynamicVal,
"unknown || false || unknown": cty.DynamicVal,
"unknown && false || unknown": cty.DynamicVal,
"unknown && unknown && true": cty.DynamicVal,
"unknown || unknown && true": cty.DynamicVal,
"unknown || unknown || true": cty.True,
"unknown && unknown || true": cty.True,
"unknown && unknown && false": cty.False,
"unknown || unknown && false": cty.DynamicVal,
"unknown || unknown || false": cty.DynamicVal,
"unknown && unknown || false": cty.DynamicVal,
"unknown && unknown && unknown": cty.DynamicVal,
"unknown || unknown && unknown": cty.DynamicVal,
"unknown || unknown || unknown": cty.DynamicVal,
"unknown && unknown || unknown": cty.DynamicVal,
}

for input, want := range inputs {
t.Run(input, func(t *testing.T) {
ctx := &hcl.EvalContext{
Variables: map[string]cty.Value{
"unknown": cty.UnknownVal(cty.DynamicPseudoType),
},
}
expr, diags := ParseExpression([]byte(input), "", hcl.Pos{Line: 1, Column: 1, Byte: 0})
if diags.HasErrors() {
t.Fatal(diags.Error())
}
got, diags := expr.Value(ctx)
if diags.HasErrors() {
t.Fatal(diags.Error())
}

if got.IsKnown() != want.IsKnown() {
t.Fatalf("%q resulted in %#v, wanted %#v\n", input, got, want)
}
if !got.IsKnown() {
// covered in known comparison
return
}

if got.Equals(want).False() {
t.Fatalf("%q resulted in %#v, wanted %#v\n", input, got, want)
}
})
}
}

0 comments on commit dc88dcc

Please sign in to comment.