package orm import "testing" func TestParseDomainStringSimple(t *testing.T) { domain, err := ParseDomainString("[('name', '=', 'test')]", nil) if err != nil { t.Fatal(err) } if len(domain) != 1 { t.Fatalf("expected 1 node, got %d", len(domain)) } cond, ok := domain[0].(Condition) if !ok { t.Fatal("expected Condition") } if cond.Field != "name" { t.Errorf("field: %s", cond.Field) } if cond.Operator != "=" { t.Errorf("op: %s", cond.Operator) } if cond.Value != "test" { t.Errorf("value: %v", cond.Value) } } func TestParseDomainStringNumeric(t *testing.T) { domain, err := ParseDomainString("[('age', '>', 18)]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) if cond.Value != int64(18) { t.Errorf("expected int64(18), got %T %v", cond.Value, cond.Value) } } func TestParseDomainStringFloat(t *testing.T) { domain, err := ParseDomainString("[('amount', '>', 99.5)]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) if cond.Value != float64(99.5) { t.Errorf("expected float64(99.5), got %T %v", cond.Value, cond.Value) } } func TestParseDomainStringNegativeNumber(t *testing.T) { domain, err := ParseDomainString("[('balance', '<', -100)]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) if cond.Value != int64(-100) { t.Errorf("expected int64(-100), got %T %v", cond.Value, cond.Value) } } func TestParseDomainStringBoolean(t *testing.T) { domain, err := ParseDomainString("[('active', '=', True)]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) if cond.Value != true { t.Errorf("expected true, got %v", cond.Value) } } func TestParseDomainStringBooleanFalse(t *testing.T) { domain, err := ParseDomainString("[('active', '=', False)]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) if cond.Value != false { t.Errorf("expected false, got %v", cond.Value) } } func TestParseDomainStringList(t *testing.T) { domain, err := ParseDomainString("[('id', 'in', [1, 2, 3])]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) vals, ok := cond.Value.([]int64) if !ok { t.Fatalf("expected []int64, got %T", cond.Value) } if len(vals) != 3 { t.Errorf("expected 3, got %d", len(vals)) } if vals[0] != 1 || vals[1] != 2 || vals[2] != 3 { t.Errorf("values: %v", vals) } } func TestParseDomainStringStringList(t *testing.T) { domain, err := ParseDomainString("[('state', 'in', ['draft', 'sent'])]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) vals, ok := cond.Value.([]string) if !ok { t.Fatalf("expected []string, got %T", cond.Value) } if len(vals) != 2 { t.Errorf("expected 2, got %d", len(vals)) } } func TestParseDomainStringEmptyList(t *testing.T) { domain, err := ParseDomainString("[('id', 'in', [])]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) vals, ok := cond.Value.([]int64) if !ok { t.Fatalf("expected []int64, got %T", cond.Value) } if len(vals) != 0 { t.Errorf("expected 0, got %d", len(vals)) } } func TestParseDomainStringOperators(t *testing.T) { domain, err := ParseDomainString("['&', ('a', '=', 1), ('b', '=', 2)]", nil) if err != nil { t.Fatal(err) } if len(domain) != 3 { t.Fatalf("expected 3 nodes, got %d", len(domain)) } if domain[0] != OpAnd { t.Error("expected & operator") } } func TestParseDomainStringOrOperator(t *testing.T) { domain, err := ParseDomainString("['|', ('a', '=', 1), ('b', '=', 2)]", nil) if err != nil { t.Fatal(err) } if len(domain) != 3 { t.Fatalf("expected 3 nodes, got %d", len(domain)) } if domain[0] != OpOr { t.Error("expected | operator") } } func TestParseDomainStringNotOperator(t *testing.T) { domain, err := ParseDomainString("['!', ('active', '=', True)]", nil) if err != nil { t.Fatal(err) } if len(domain) != 2 { t.Fatalf("expected 2 nodes, got %d", len(domain)) } if domain[0] != OpNot { t.Error("expected ! operator") } } func TestParseDomainStringEmpty(t *testing.T) { domain, err := ParseDomainString("[]", nil) if err != nil { t.Fatal(err) } if len(domain) != 0 { t.Errorf("expected 0 nodes, got %d", len(domain)) } } func TestParseDomainStringEmptyString(t *testing.T) { domain, err := ParseDomainString("", nil) if err != nil { t.Fatal(err) } if len(domain) != 0 { t.Errorf("expected 0 nodes, got %d", len(domain)) } } func TestParseDomainStringNone(t *testing.T) { domain, err := ParseDomainString("[('field', '=', None)]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) if cond.Value != nil { t.Errorf("expected nil, got %v", cond.Value) } } func TestParseDomainStringImplicitAnd(t *testing.T) { // Multiple leaves without explicit operator should be implicitly ANDed domain, err := ParseDomainString("[('a', '=', 1), ('b', '=', 2)]", nil) if err != nil { t.Fatal(err) } // normalizeDomainNodes wraps with And() → [&, leaf, leaf] = 3 nodes if len(domain) != 3 { t.Fatalf("expected 3 nodes (implicit AND), got %d", len(domain)) } if domain[0] != OpAnd { t.Error("expected implicit & operator") } } func TestParseDomainStringDoubleQuotes(t *testing.T) { domain, err := ParseDomainString(`[("name", "=", "test")]`, nil) if err != nil { t.Fatal(err) } if len(domain) != 1 { t.Fatalf("expected 1 node, got %d", len(domain)) } cond := domain[0].(Condition) if cond.Field != "name" { t.Errorf("field: %s", cond.Field) } if cond.Value != "test" { t.Errorf("value: %v", cond.Value) } } func TestParseDomainStringContextVar(t *testing.T) { // Without env, context vars should resolve to int64(0) domain, err := ParseDomainString("[('user_id', '=', user.id)]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) if cond.Value != int64(0) { t.Errorf("expected int64(0), got %T %v", cond.Value, cond.Value) } } func TestParseDomainStringInvalidSyntax(t *testing.T) { _, err := ParseDomainString("not a domain", nil) if err == nil { t.Error("expected error for invalid syntax") } } func TestParseDomainStringTupleAsList(t *testing.T) { // Some domain_force uses tuple syntax for list values domain, err := ParseDomainString("[('id', 'in', (1, 2, 3))]", nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) vals, ok := cond.Value.([]int64) if !ok { t.Fatalf("expected []int64, got %T", cond.Value) } if len(vals) != 3 { t.Errorf("expected 3, got %d", len(vals)) } } func TestParseDomainStringEscapedQuote(t *testing.T) { domain, err := ParseDomainString(`[('name', '=', 'it\'s')]`, nil) if err != nil { t.Fatal(err) } cond := domain[0].(Condition) if cond.Value != "it's" { t.Errorf("expected it's, got %v", cond.Value) } }