github.com/cloudflare/circl@v1.5.0/abe/cpabe/tkn20/internal/dsl/dsl_test.go (about) 1 package dsl_test 2 3 import ( 4 "errors" 5 "testing" 6 7 "github.com/cloudflare/circl/abe/cpabe/tkn20/internal/dsl" 8 "github.com/cloudflare/circl/abe/cpabe/tkn20/internal/tkn" 9 ) 10 11 var testCases = []struct { 12 input string 13 output *tkn.Policy 14 err error 15 }{ 16 { 17 input: "", 18 err: errors.New("expected parentheses or literal"), 19 }, 20 { 21 input: "&", 22 err: errors.New("unexpected character(s): '&'"), 23 }, 24 { 25 input: "country: north korea", 26 err: errors.New("unexpected token korea, expected logical operator \"and\" or \"or\""), 27 }, 28 { 29 input: "(country: congo", 30 err: errors.New("expected ')' after expression"), 31 }, 32 { 33 input: "(country: china or taiwan)", 34 err: errors.New("expected parentheses or literal"), 35 }, 36 { 37 input: "not (planet: arakis", 38 err: errors.New("expected ')' after expression"), 39 }, 40 { 41 input: "ocean: indian and ship: rms titanic", 42 err: errors.New("unexpected token titanic, expected logical operator \"and\" or \"or\""), 43 }, 44 { 45 input: "not (spice: saffron and region: persia)", 46 output: &tkn.Policy{ 47 Inputs: []tkn.Wire{ 48 {Label: "spice", RawValue: "saffron", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "saffron"), Positive: false}, 49 {Label: "region", RawValue: "persia", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "persia"), Positive: false}, 50 }, 51 F: tkn.Formula{ 52 Gates: []tkn.Gate{ 53 {Class: tkn.Orgate, In0: 0, In1: 1, Out: 2}, 54 }, 55 }, 56 }, 57 }, 58 { 59 input: "not (spice: mace or spice: nutmeg)", 60 output: &tkn.Policy{ 61 Inputs: []tkn.Wire{ 62 {Label: "spice", RawValue: "mace", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "mace"), Positive: false}, 63 {Label: "spice", RawValue: "nutmeg", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "nutmeg"), Positive: false}, 64 }, 65 F: tkn.Formula{ 66 Gates: []tkn.Gate{ 67 {Class: tkn.Andgate, In0: 0, In1: 1, Out: 2}, 68 }, 69 }, 70 }, 71 }, 72 { 73 input: "((region: caribean)) or (not (((fruit: stonefruit and not flower: hibiscus) or spice: mace) and not (family: extracts or family: chilis)))", 74 output: &tkn.Policy{ 75 Inputs: []tkn.Wire{ 76 {Label: "region", RawValue: "caribean", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "caribean"), Positive: true}, 77 {Label: "fruit", RawValue: "stonefruit", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "stonefruit"), Positive: false}, 78 {Label: "flower", RawValue: "hibiscus", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "hibiscus"), Positive: true}, 79 {Label: "spice", RawValue: "mace", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "mace"), Positive: false}, 80 {Label: "family", RawValue: "extracts", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "extracts"), Positive: true}, 81 {Label: "family", RawValue: "chilis", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "chilis"), Positive: true}, 82 }, 83 F: tkn.Formula{ 84 Gates: []tkn.Gate{ 85 {Class: tkn.Orgate, In0: 1, In1: 2, Out: 6}, 86 {Class: tkn.Andgate, In0: 3, In1: 6, Out: 7}, 87 {Class: tkn.Orgate, In0: 4, In1: 5, Out: 8}, 88 {Class: tkn.Orgate, In0: 7, In1: 8, Out: 9}, 89 {Class: tkn.Orgate, In0: 0, In1: 9, Out: 10}, 90 }, 91 }, 92 }, 93 }, 94 { 95 input: "(9country8: france)", 96 output: &tkn.Policy{ 97 Inputs: []tkn.Wire{ 98 {Label: "9country8", RawValue: "france", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "france"), Positive: true}, 99 }, 100 F: tkn.Formula{ 101 Gates: []tkn.Gate{}, 102 }, 103 }, 104 }, 105 { 106 input: "((country : afghanistan) or (country: bactria)) and (not (king: alexander))", 107 output: &tkn.Policy{ 108 Inputs: []tkn.Wire{ 109 {Label: "country", RawValue: "afghanistan", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "afghanistan"), Positive: true}, 110 {Label: "country", RawValue: "bactria", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "bactria"), Positive: true}, 111 {Label: "king", RawValue: "alexander", Value: tkn.HashStringToScalar(dsl.AttrHashKey, "alexander"), Positive: false}, 112 }, 113 F: tkn.Formula{ 114 Gates: []tkn.Gate{ 115 {Class: tkn.Orgate, In0: 0, In1: 1, Out: 3}, 116 {Class: tkn.Andgate, In0: 3, In1: 2, Out: 4}, 117 }, 118 }, 119 }, 120 }, 121 } 122 123 func TestDsl(t *testing.T) { 124 for _, test := range testCases { 125 t.Run("TestDsl:"+test.input, func(t *testing.T) { 126 a, err := dsl.Run(test.input) 127 if test.err == nil { 128 if err != nil { 129 t.Fatal(err) 130 } 131 if !a.Equal(test.output) { 132 t.Fatalf("incorrect attributes: expected %v, received: %v", test.output, a) 133 } 134 } else { 135 if err == nil { 136 t.Fatalf("this should fail") 137 } 138 if test.err.Error() != err.Error() { 139 t.Fatalf("incorrect error: expected: %v, received: %v", test.err, err) 140 } 141 } 142 }) 143 } 144 }