func translateNumeric(schema Numeric) (*relapse.Pattern, error) { v := Number() list := []funcs.Bool{} notNum := funcs.Not(funcs.TypeDouble(Number())) if schema.MultipleOf != nil { mult := MultipleOf(v, funcs.DoubleConst(*schema.MultipleOf)) list = append(list, funcs.Or(mult, notNum)) } if schema.Maximum != nil { lt := funcs.DoubleLE(v, funcs.DoubleConst(*schema.Maximum)) if schema.ExclusiveMaximum { lt = funcs.DoubleLt(v, funcs.DoubleConst(*schema.Maximum)) } list = append(list, funcs.Or(lt, notNum)) } if schema.Minimum != nil { lt := funcs.DoubleGE(v, funcs.DoubleConst(*schema.Minimum)) if schema.ExclusiveMinimum { lt = funcs.DoubleGt(v, funcs.DoubleConst(*schema.Minimum)) } list = append(list, funcs.Or(lt, notNum)) } if len(list) == 0 { return combinator.Value(funcs.TypeDouble(v)), nil } return combinator.Value(and(list)), nil }
func translateType(typ SimpleType) (*relapse.Pattern, error) { switch typ { case TypeArray, TypeObject: //This does not distinguish between arrays and objects return combinator.Many(combinator.InAny(combinator.Any())), nil case TypeBoolean: return combinator.Value(funcs.TypeBool(funcs.BoolVar())), nil case TypeInteger: return combinator.Value(funcs.TypeDouble(Integer())), nil case TypeNull: //TODO null is not being returned by json parser, but is also not empty return combinator.Value(funcs.Not( funcs.Or( funcs.TypeDouble(Number()), funcs.Or( funcs.TypeBool(funcs.BoolVar()), funcs.TypeString(funcs.StringVar()), ), ), )), nil case TypeNumber: return combinator.Value(funcs.TypeDouble(Number())), nil case TypeString: return combinator.Value(funcs.TypeString(funcs.StringVar())), nil } panic(fmt.Sprintf("unknown simpletype: %s", typ)) }
func TestSimplifyRecordLeaf1(t *testing.T) { input := ast.NewAnd( ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), combinator.Value(funcs.Contains(funcs.StringVar(), funcs.StringConst("a"))))), ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), combinator.Value(funcs.Contains(funcs.StringVar(), funcs.StringConst("b"))))), ) t.Logf("input: %v", input) expected := ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), combinator.Value(funcs.And( funcs.Contains(funcs.StringVar(), funcs.StringConst("a")), funcs.Contains(funcs.StringVar(), funcs.StringConst("b")), )))) output := NewSimplifier(input.Grammar()).OptimizeForRecord().Simplify(input) expected.Format() output.Format() t.Logf("%v", output) if !expected.Equal(output) { t.Fatalf("expected %v, but got %v", expected, output) } }
func TestSimplifyFalseLeaf(t *testing.T) { input := combinator.Value(funcs.And(funcs.StringEq(funcs.StringVar(), funcs.StringConst("a")), funcs.StringEq(funcs.StringVar(), funcs.StringConst("b")))) expected := ast.NewNot(ast.NewZAny()) output := NewSimplifier(input.Grammar()).Simplify(input) t.Logf("%v", output) if !expected.Equal(output) { t.Fatalf("expected %v, but got %v", expected, output) } }
func newList(nameOrPattern *NameOrPattern) *ast.Pattern { regexStr, nullable, err := listToRegex(nameOrPattern) if err != nil { return ast.NewNot(ast.NewZAny()) } val := combinator.Value(&list{nil, funcs.StringVar(), funcs.StringConst("^" + regexStr + "$")}) if !nullable { return val } return ast.NewOr(val, ast.NewEmpty()) }
func translateString(schema String) (*relapse.Pattern, error) { v := funcs.StringVar() list := []funcs.Bool{} notStr := funcs.Not(funcs.TypeString(funcs.StringVar())) if schema.MaxLength != nil { ml := MaxLength(v, int64(*schema.MaxLength)) list = append(list, funcs.Or(ml, notStr)) } if schema.MinLength > 0 { ml := MinLength(v, int64(schema.MinLength)) list = append(list, funcs.Or(ml, notStr)) } if schema.Pattern != nil { p := funcs.Regex(funcs.StringConst(*schema.Pattern), v) list = append(list, funcs.Or(p, notStr)) } if len(list) == 0 { return combinator.Value(funcs.TypeString(v)), nil } return combinator.Value(and(list)), nil }
func newTokenValue(t string) *ast.Pattern { return combinator.Value(&token{funcs.StringVar(), funcs.StringConst(t), ""}) }
func newTextValue(value string) *ast.Pattern { return combinator.Value(&text{funcs.StringVar(), funcs.StringConst(value), ""}) }
func newAnyValue() *ast.Pattern { return combinator.Value(&anytext{funcs.StringVar()}) }
func newEmptyValue() *ast.Pattern { return combinator.Value(&whitespace{funcs.StringVar()}) }
) func TestSimplify1(t *testing.T) { c := ast.NewConcat(ast.NewNot(ast.NewZAny()), ast.NewZAny()) s := NewSimplifier(c.Grammar()).Simplify(c) if !s.Equal(ast.NewNot(ast.NewZAny())) { t.Fatalf("Expected EmptySet, but got %s", s) } } var andNameTelephonePerson = combinator.G{ "main": combinator.InOrder( combinator.AllOf( combinator.InOrder( combinator.Any(), combinator.In("Name", combinator.Value( funcs.StringEq(funcs.StringVar(), funcs.StringConst("David"))), ), combinator.Any(), ), combinator.InOrder( combinator.Any(), combinator.In("Telephone", combinator.Value( funcs.StringEq(funcs.StringVar(), funcs.StringConst("0123456789"))), ), combinator.Any(), ), ), ), } func TestSimplify2(t *testing.T) {