From 45e707125c38efc6a861fc2d938e4cc10e0b115e Mon Sep 17 00:00:00 2001 From: Nicholas Wiersma Date: Wed, 25 Sep 2024 17:51:57 +0200 Subject: [PATCH] feat: allow empty namespaces (#459) --- protocol.go | 2 +- protocol_test.go | 10 +++++----- schema_parse.go | 13 +++++-------- schema_test.go | 40 ++++++++++++++++++++-------------------- 4 files changed, 31 insertions(+), 34 deletions(-) diff --git a/protocol.go b/protocol.go index 28608eb8..3a62baaa 100644 --- a/protocol.go +++ b/protocol.go @@ -252,7 +252,7 @@ func parseProtocol(m map[string]any, seen seenCache, cache *SchemaCache) (*Proto return nil, fmt.Errorf("avro: error decoding protocol: %w", err) } - if err := checkParsedName(p.Protocol, p.Namespace, hasKey(meta.Keys, "namespace")); err != nil { + if err := checkParsedName(p.Protocol); err != nil { return nil, err } diff --git a/protocol_test.go b/protocol_test.go index 4eb2b970..3e96532b 100644 --- a/protocol_test.go +++ b/protocol_test.go @@ -53,6 +53,11 @@ func TestParseProtocol(t *testing.T) { schema: `{"protocol":"test", "namespace": "org.hamba.avro", "doc": "docs"}`, wantErr: assert.NoError, }, + { + name: "Empty Namespace", + schema: `{"protocol":"test", "namespace": ""}`, + wantErr: assert.NoError, + }, { name: "Invalid Json", schema: `{`, @@ -83,11 +88,6 @@ func TestParseProtocol(t *testing.T) { schema: `{"protocol":"test", "namespace": "org.hamba.avro+"}`, wantErr: assert.Error, }, - { - name: "Empty Namespace", - schema: `{"protocol":"test", "namespace": ""}`, - wantErr: assert.Error, - }, { name: "Invalid Type Schema", schema: `{"protocol":"test", "namespace": "org.hamba.avro", "types":["test"]}`, diff --git a/schema_parse.go b/schema_parse.go index 30221162..889ada0b 100644 --- a/schema_parse.go +++ b/schema_parse.go @@ -224,7 +224,7 @@ func parseRecord(typ Type, namespace string, m map[string]any, seen seenCache, c return nil, fmt.Errorf("avro: error decoding record: %w", err) } - if err := checkParsedName(r.Name, r.Namespace, hasKey(meta.Keys, "namespace")); err != nil { + if err := checkParsedName(r.Name); err != nil { return nil, err } if r.Namespace == "" { @@ -294,7 +294,7 @@ func parseField(namespace string, m map[string]any, seen seenCache, cache *Schem return nil, fmt.Errorf("avro: error decoding field: %w", err) } - if err := checkParsedName(f.Name, "", false); err != nil { + if err := checkParsedName(f.Name); err != nil { return nil, err } @@ -340,7 +340,7 @@ func parseEnum(namespace string, m map[string]any, seen seenCache, cache *Schema return nil, fmt.Errorf("avro: error decoding enum: %w", err) } - if err := checkParsedName(e.Name, e.Namespace, hasKey(meta.Keys, "namespace")); err != nil { + if err := checkParsedName(e.Name); err != nil { return nil, err } if e.Namespace == "" { @@ -451,7 +451,7 @@ func parseFixed(namespace string, m map[string]any, seen seenCache, cache *Schem return nil, fmt.Errorf("avro: error decoding fixed: %w", err) } - if err := checkParsedName(f.Name, f.Namespace, hasKey(meta.Keys, "namespace")); err != nil { + if err := checkParsedName(f.Name); err != nil { return nil, err } if f.Namespace == "" { @@ -529,13 +529,10 @@ func fullName(namespace, name string) string { return namespace + "." + name } -func checkParsedName(name, ns string, hasNS bool) error { +func checkParsedName(name string) error { if name == "" { return errors.New("avro: non-empty name key required") } - if hasNS && ns == "" { - return errors.New("avro: namespace key must be non-empty or omitted") - } return nil } diff --git a/schema_test.go b/schema_test.go index 6e0cb651..469a0e0d 100644 --- a/schema_test.go +++ b/schema_test.go @@ -191,6 +191,11 @@ func TestRecordSchema(t *testing.T) { schema: `{"type":"record", "name":"test", "namespace": "org.hamba.avro", "doc": "docs", "fields":[{"name": "field", "type": "int"}]}`, wantErr: require.NoError, }, + { + name: "Empty Namespace", + schema: `{"type":"record", "name":"test", "namespace": "", "fields":[{"name": "intField", "type": "int"}]}`, + wantErr: require.NoError, + }, { name: "Invalid Name First Char", schema: `{"type":"record", "name":"0test", "namespace": "org.hamba.avro", "fields":[{"name": "field", "type": "int"}]}`, @@ -216,11 +221,6 @@ func TestRecordSchema(t *testing.T) { schema: `{"type":"record", "name":"test", "namespace": "org.hamba.avro+", "fields":[{"name": "field", "type": "int"}]}`, wantErr: require.Error, }, - { - name: "Empty Namespace", - schema: `{"type":"record", "name":"test", "namespace": "", "fields":[{"name": "intField", "type": "int"}]}`, - wantErr: require.Error, - }, { name: "No Fields", schema: `{"type":"record", "name":"test", "namespace": "org.hamba.avro"}`, @@ -286,6 +286,11 @@ func TestErrorRecordSchema(t *testing.T) { wantSchema: true, wantErr: require.NoError, }, + { + name: "Empty Namespace", + schema: `{"type":"error", "name":"test", "namespace": "", "fields":[{"name": "intField", "type": "int"}]}`, + wantErr: require.NoError, + }, { name: "Invalid Name First Char", schema: `{"type":"error", "name":"0test", "namespace": "org.hamba.avro", "fields":[{"name": "field", "type": "int"}]}`, @@ -311,11 +316,6 @@ func TestErrorRecordSchema(t *testing.T) { schema: `{"type":"error", "name":"test", "namespace": "org.hamba.avro+", "fields":[{"name": "field", "type": "int"}]}`, wantErr: require.Error, }, - { - name: "Empty Namespace", - schema: `{"type":"error", "name":"test", "namespace": "", "fields":[{"name": "intField", "type": "int"}]}`, - wantErr: require.Error, - }, } for _, test := range tests { @@ -640,6 +640,11 @@ func TestEnumSchema(t *testing.T) { wantDefault: "TEST", wantErr: require.NoError, }, + { + name: "Empty Namespace", + schema: `{"type":"enum", "name":"test", "namespace": "", "symbols":["TEST"]}`, + wantErr: require.NoError, + }, { name: "Invalid Name", schema: `{"type":"enum", "name":"test+", "namespace": "org.hamba.avro", "symbols":["TEST"]}`, @@ -660,11 +665,6 @@ func TestEnumSchema(t *testing.T) { schema: `{"type":"enum", "name":"test", "namespace": "org.hamba.avro+", "symbols":["TEST"]}`, wantErr: require.Error, }, - { - name: "Empty Namespace", - schema: `{"type":"enum", "name":"test", "namespace": "", "symbols":["TEST"]}`, - wantErr: require.Error, - }, { name: "No Symbols", schema: `{"type":"enum", "name":"test", "namespace": "org.hamba.avro"}`, @@ -931,6 +931,11 @@ func TestFixedSchema(t *testing.T) { wantFingerprint: [32]uint8{0x8c, 0x9e, 0xcb, 0x4, 0x83, 0x2f, 0x3b, 0xa7, 0x58, 0x85, 0x9, 0x99, 0x41, 0xe, 0xbf, 0xd4, 0x7, 0xc7, 0x87, 0x4f, 0x8a, 0x12, 0xf4, 0xd0, 0x7f, 0x45, 0xdd, 0xaa, 0x10, 0x6b, 0x2f, 0xb3}, wantErr: require.NoError, }, + { + name: "Empty Namespace", + schema: `{"type":"fixed", "name":"test", "namespace": "", "size": 12}`, + wantErr: require.NoError, + }, { name: "Invalid Name", schema: `{"type":"fixed", "name":"test+", "namespace": "org.hamba.avro", "size": 12}`, @@ -951,11 +956,6 @@ func TestFixedSchema(t *testing.T) { schema: `{"type":"fixed", "name":"test", "namespace": "org.hamba.avro+", "size": 12}`, wantErr: require.Error, }, - { - name: "Empty Namespace", - schema: `{"type":"fixed", "name":"test", "namespace": "", "size": 12}`, - wantErr: require.Error, - }, { name: "No Size", schema: `{"type":"fixed", "name":"test", "namespace": "org.hamba.avro"}`,