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  }