deimos-ruby 1.11.1 → 1.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -2
  3. data/Gemfile.lock +8 -8
  4. data/README.md +103 -0
  5. data/deimos-ruby.gemspec +1 -1
  6. data/docs/CONFIGURATION.md +4 -0
  7. data/lib/deimos/active_record_consume/batch_consumption.rb +7 -5
  8. data/lib/deimos/active_record_consume/message_consumption.rb +4 -3
  9. data/lib/deimos/active_record_consumer.rb +2 -2
  10. data/lib/deimos/active_record_producer.rb +3 -0
  11. data/lib/deimos/config/configuration.rb +29 -0
  12. data/lib/deimos/consume/batch_consumption.rb +2 -2
  13. data/lib/deimos/consume/message_consumption.rb +2 -2
  14. data/lib/deimos/consumer.rb +10 -0
  15. data/lib/deimos/producer.rb +4 -3
  16. data/lib/deimos/schema_backends/avro_base.rb +64 -1
  17. data/lib/deimos/schema_backends/avro_schema_registry.rb +1 -1
  18. data/lib/deimos/schema_backends/base.rb +18 -2
  19. data/lib/deimos/schema_class/base.rb +62 -0
  20. data/lib/deimos/schema_class/enum.rb +24 -0
  21. data/lib/deimos/schema_class/record.rb +66 -0
  22. data/lib/deimos/shared_config.rb +5 -0
  23. data/lib/deimos/test_helpers.rb +43 -7
  24. data/lib/deimos/utils/schema_class.rb +29 -0
  25. data/lib/deimos/version.rb +1 -1
  26. data/lib/deimos.rb +23 -0
  27. data/lib/generators/deimos/schema_class/templates/schema_class.rb.tt +15 -0
  28. data/lib/generators/deimos/schema_class/templates/schema_enum.rb.tt +21 -0
  29. data/lib/generators/deimos/schema_class/templates/schema_record.rb.tt +65 -0
  30. data/lib/generators/deimos/schema_class_generator.rb +247 -0
  31. data/lib/tasks/deimos.rake +8 -0
  32. data/spec/active_record_batch_consumer_spec.rb +120 -110
  33. data/spec/active_record_consumer_spec.rb +97 -88
  34. data/spec/active_record_producer_spec.rb +38 -27
  35. data/spec/batch_consumer_spec.rb +37 -28
  36. data/spec/config/configuration_spec.rb +10 -3
  37. data/spec/consumer_spec.rb +95 -84
  38. data/spec/generators/active_record_generator_spec.rb +1 -0
  39. data/spec/generators/schema_class/my_schema_with_complex_types_spec.rb +206 -0
  40. data/spec/generators/schema_class_generator_spec.rb +186 -0
  41. data/spec/producer_spec.rb +110 -0
  42. data/spec/schema_classes/generated.rb +156 -0
  43. data/spec/schema_classes/my_nested_schema.rb +114 -0
  44. data/spec/schema_classes/my_schema.rb +53 -0
  45. data/spec/schema_classes/my_schema_key.rb +35 -0
  46. data/spec/schema_classes/my_schema_with_complex_types.rb +172 -0
  47. data/spec/schemas/com/my-namespace/Generated.avsc +6 -0
  48. data/spec/schemas/com/my-namespace/MySchemaWithComplexTypes.avsc +95 -0
  49. data/spec/spec_helper.rb +6 -1
  50. metadata +28 -4
@@ -390,6 +390,116 @@ module ProducerTest
390
390
  }, '456', '4561')
391
391
  end
392
392
 
393
+ context 'with Schema Class payloads' do
394
+ it 'should fail on invalid message with error handler' do
395
+ subscriber = Deimos.subscribe('produce') do |event|
396
+ expect(event.payload[:payloads]).to eq([{ 'invalid' => 'key' }])
397
+ end
398
+ expect(MyProducer.encoder).to receive(:validate).and_raise('OH NOES')
399
+ expect {
400
+ MyProducer.publish(Schemas::MySchema.new(test_id: 'foo', some_int: 'invalid'))
401
+ }.to raise_error('OH NOES')
402
+ Deimos.unsubscribe(subscriber)
403
+ end
404
+
405
+ it 'should produce a message' do
406
+ expect(described_class).to receive(:produce_batch).once.with(
407
+ Deimos::Backends::Test,
408
+ [
409
+ Deimos::Message.new({ 'test_id' => 'foo', 'some_int' => 123 },
410
+ MyProducer,
411
+ topic: 'my-topic',
412
+ partition_key: 'foo',
413
+ key: 'foo'),
414
+ Deimos::Message.new({ 'test_id' => 'bar', 'some_int' => 124 },
415
+ MyProducer,
416
+ topic: 'my-topic',
417
+ partition_key: 'bar',
418
+ key: 'bar')
419
+ ]
420
+ ).and_call_original
421
+
422
+ MyProducer.publish_list(
423
+ [Schemas::MySchema.new(test_id: 'foo', some_int: 123),
424
+ Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
425
+ )
426
+ expect('my-topic').to have_sent('test_id' => 'foo', 'some_int' => 123)
427
+ expect('your-topic').not_to have_sent('test_id' => 'foo', 'some_int' => 123)
428
+ expect('my-topic').not_to have_sent('test_id' => 'foo2', 'some_int' => 123)
429
+ end
430
+
431
+ it 'should not publish if publish disabled' do
432
+ expect(described_class).not_to receive(:produce_batch)
433
+ Deimos.configure { |c| c.producers.disabled = true }
434
+ MyProducer.publish_list(
435
+ [Schemas::MySchema.new(test_id: 'foo', some_int: 123),
436
+ Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
437
+ )
438
+ expect(MyProducer.topic).not_to have_sent(anything)
439
+ end
440
+
441
+ it 'should encode the key' do
442
+ Deimos.configure { |c| c.producers.topic_prefix = nil }
443
+ expect(MyProducer.encoder).to receive(:encode_key).with('test_id', 'foo', topic: 'my-topic-key')
444
+ expect(MyProducer.encoder).to receive(:encode_key).with('test_id', 'bar', topic: 'my-topic-key')
445
+ expect(MyProducer.encoder).to receive(:encode).with({
446
+ 'test_id' => 'foo',
447
+ 'some_int' => 123
448
+ }, { topic: 'my-topic-value' })
449
+ expect(MyProducer.encoder).to receive(:encode).with({
450
+ 'test_id' => 'bar',
451
+ 'some_int' => 124
452
+ }, { topic: 'my-topic-value' })
453
+
454
+ MyProducer.publish_list(
455
+ [Schemas::MySchema.new(test_id: 'foo', some_int: 123),
456
+ Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
457
+ )
458
+ end
459
+
460
+ it 'should encode with a schema' do
461
+ expect(MySchemaProducer.key_encoder).to receive(:encode).with({ 'test_id' => 'foo_key' },
462
+ { topic: 'my-topic2-key' })
463
+ expect(MySchemaProducer.key_encoder).to receive(:encode).with({ 'test_id' => 'bar_key' },
464
+ { topic: 'my-topic2-key' })
465
+
466
+ MySchemaProducer.publish_list(
467
+ [Schemas::MySchema.new(test_id: 'foo', some_int: 123, payload_key: { 'test_id' => 'foo_key' }),
468
+ Schemas::MySchema.new(test_id: 'bar', some_int: 124, payload_key: { 'test_id' => 'bar_key' })]
469
+ )
470
+ end
471
+
472
+ it 'should properly encode and coerce values with a nested record' do
473
+ expect(MyNestedSchemaProducer.encoder).to receive(:encode_key).with('test_id', 'foo', topic: 'my-topic-key')
474
+ MyNestedSchemaProducer.publish(
475
+ Schemas::MyNestedSchema.new(
476
+ test_id: 'foo',
477
+ test_float: BigDecimal('123.456'),
478
+ test_array: ['1'],
479
+ some_nested_record: Schemas::MyNestedRecord.new(
480
+ some_int: 123,
481
+ some_float: BigDecimal('456.789'),
482
+ some_string: '123',
483
+ some_optional_int: nil
484
+ ),
485
+ some_optional_record: nil
486
+ )
487
+ )
488
+ expect(MyNestedSchemaProducer.topic).to have_sent(
489
+ 'test_id' => 'foo',
490
+ 'test_float' => 123.456,
491
+ 'test_array' => ['1'],
492
+ 'some_nested_record' => {
493
+ 'some_int' => 123,
494
+ 'some_float' => 456.789,
495
+ 'some_string' => '123',
496
+ 'some_optional_int' => nil
497
+ },
498
+ 'some_optional_record' => nil
499
+ )
500
+ end
501
+ end
502
+
393
503
  describe 'disabling' do
394
504
  it 'should disable globally' do
395
505
  Deimos.disable_producers do
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Secondary Schema Classes ###
6
+ # Autogenerated Schema for Enum at com.my-namespace.AnEnum
7
+ class AnEnum < Deimos::SchemaClass::Enum
8
+ # @return ['sym1', 'sym2']
9
+ attr_accessor :an_enum
10
+
11
+ # :nodoc:
12
+ def initialize(an_enum)
13
+ super
14
+ self.an_enum = an_enum
15
+ end
16
+
17
+ # @override
18
+ def symbols
19
+ %w(sym1 sym2)
20
+ end
21
+
22
+ # @override
23
+ def to_h
24
+ @an_enum
25
+ end
26
+ end
27
+
28
+ # Autogenerated Schema for Record at com.my-namespace.ARecord
29
+ class ARecord < Deimos::SchemaClass::Record
30
+ ### Attribute Accessors ###
31
+ # @param value [String]
32
+ attr_accessor :a_record_field
33
+
34
+ # @override
35
+ def initialize(a_record_field: nil)
36
+ super
37
+ self.a_record_field = a_record_field
38
+ end
39
+
40
+ # @override
41
+ def schema
42
+ 'ARecord'
43
+ end
44
+
45
+ # @override
46
+ def namespace
47
+ 'com.my-namespace'
48
+ end
49
+
50
+ # @override
51
+ def to_h
52
+ {
53
+ 'a_record_field' => @a_record_field
54
+ }
55
+ end
56
+ end
57
+
58
+ ### Primary Schema Class ###
59
+ # Autogenerated Schema for Record at com.my-namespace.Generated
60
+ class Generated < Deimos::SchemaClass::Record
61
+ ### Attribute Readers ###
62
+ # @return [AnEnum]
63
+ attr_reader :an_enum
64
+ # @return [ARecord]
65
+ attr_reader :a_record
66
+
67
+ ### Attribute Accessors ###
68
+ # @param value [String]
69
+ attr_accessor :a_string
70
+ # @param value [Integer]
71
+ attr_accessor :a_int
72
+ # @param value [Integer]
73
+ attr_accessor :a_long
74
+ # @param value [Float]
75
+ attr_accessor :a_float
76
+ # @param value [Float]
77
+ attr_accessor :a_double
78
+ # @param value [nil, Integer]
79
+ attr_accessor :an_optional_int
80
+ # @param values [Array<Integer>]
81
+ attr_accessor :an_array
82
+ # @param values [Hash<String, String>]
83
+ attr_accessor :a_map
84
+ # @param value [String]
85
+ attr_accessor :timestamp
86
+ # @param value [String]
87
+ attr_accessor :message_id
88
+
89
+ ### Attribute Writers ###
90
+ # @param value [AnEnum]
91
+ def an_enum=(value)
92
+ @an_enum = AnEnum.initialize_from_value(value)
93
+ end
94
+
95
+ # @param value [ARecord]
96
+ def a_record=(value)
97
+ @a_record = ARecord.initialize_from_value(value)
98
+ end
99
+
100
+ # @override
101
+ def initialize(a_string: nil,
102
+ a_int: nil,
103
+ a_long: nil,
104
+ a_float: nil,
105
+ a_double: nil,
106
+ an_optional_int: nil,
107
+ an_enum: nil,
108
+ an_array: nil,
109
+ a_map: nil,
110
+ timestamp: nil,
111
+ message_id: nil,
112
+ a_record: nil)
113
+ super
114
+ self.a_string = a_string
115
+ self.a_int = a_int
116
+ self.a_long = a_long
117
+ self.a_float = a_float
118
+ self.a_double = a_double
119
+ self.an_optional_int = an_optional_int
120
+ self.an_enum = an_enum
121
+ self.an_array = an_array
122
+ self.a_map = a_map
123
+ self.timestamp = timestamp
124
+ self.message_id = message_id
125
+ self.a_record = a_record
126
+ end
127
+
128
+ # @override
129
+ def schema
130
+ 'Generated'
131
+ end
132
+
133
+ # @override
134
+ def namespace
135
+ 'com.my-namespace'
136
+ end
137
+
138
+ # @override
139
+ def to_h
140
+ {
141
+ 'a_string' => @a_string,
142
+ 'a_int' => @a_int,
143
+ 'a_long' => @a_long,
144
+ 'a_float' => @a_float,
145
+ 'a_double' => @a_double,
146
+ 'an_optional_int' => @an_optional_int,
147
+ 'an_enum' => @an_enum&.to_h,
148
+ 'an_array' => @an_array,
149
+ 'a_map' => @a_map,
150
+ 'timestamp' => @timestamp,
151
+ 'message_id' => @message_id,
152
+ 'a_record' => @a_record&.to_h
153
+ }
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Secondary Schema Classes ###
6
+ # Autogenerated Schema for Record at com.my-namespace.MyNestedRecord
7
+ class MyNestedRecord < Deimos::SchemaClass::Record
8
+ ### Attribute Accessors ###
9
+ # @param value [Integer]
10
+ attr_accessor :some_int
11
+ # @param value [Float]
12
+ attr_accessor :some_float
13
+ # @param value [String]
14
+ attr_accessor :some_string
15
+ # @param value [nil, Integer]
16
+ attr_accessor :some_optional_int
17
+
18
+ # @override
19
+ def initialize(some_int: nil,
20
+ some_float: nil,
21
+ some_string: nil,
22
+ some_optional_int: nil)
23
+ super
24
+ self.some_int = some_int
25
+ self.some_float = some_float
26
+ self.some_string = some_string
27
+ self.some_optional_int = some_optional_int
28
+ end
29
+
30
+ # @override
31
+ def schema
32
+ 'MyNestedRecord'
33
+ end
34
+
35
+ # @override
36
+ def namespace
37
+ 'com.my-namespace'
38
+ end
39
+
40
+ # @override
41
+ def to_h
42
+ {
43
+ 'some_int' => @some_int,
44
+ 'some_float' => @some_float,
45
+ 'some_string' => @some_string,
46
+ 'some_optional_int' => @some_optional_int
47
+ }
48
+ end
49
+ end
50
+
51
+ ### Primary Schema Class ###
52
+ # Autogenerated Schema for Record at com.my-namespace.MyNestedSchema
53
+ class MyNestedSchema < Deimos::SchemaClass::Record
54
+ ### Attribute Readers ###
55
+ # @return [MyNestedRecord]
56
+ attr_reader :some_nested_record
57
+ # @return [nil, MyNestedRecord]
58
+ attr_reader :some_optional_record
59
+
60
+ ### Attribute Accessors ###
61
+ # @param value [String]
62
+ attr_accessor :test_id
63
+ # @param value [Float]
64
+ attr_accessor :test_float
65
+ # @param values [Array<String>]
66
+ attr_accessor :test_array
67
+
68
+ ### Attribute Writers ###
69
+ # @param value [MyNestedRecord]
70
+ def some_nested_record=(value)
71
+ @some_nested_record = MyNestedRecord.initialize_from_value(value)
72
+ end
73
+
74
+ # @param value [nil, MyNestedRecord]
75
+ def some_optional_record=(value)
76
+ @some_optional_record = MyNestedRecord.initialize_from_value(value)
77
+ end
78
+
79
+ # @override
80
+ def initialize(test_id: nil,
81
+ test_float: nil,
82
+ test_array: nil,
83
+ some_nested_record: nil,
84
+ some_optional_record: nil)
85
+ super
86
+ self.test_id = test_id
87
+ self.test_float = test_float
88
+ self.test_array = test_array
89
+ self.some_nested_record = some_nested_record
90
+ self.some_optional_record = some_optional_record
91
+ end
92
+
93
+ # @override
94
+ def schema
95
+ 'MyNestedSchema'
96
+ end
97
+
98
+ # @override
99
+ def namespace
100
+ 'com.my-namespace'
101
+ end
102
+
103
+ # @override
104
+ def to_h
105
+ {
106
+ 'test_id' => @test_id,
107
+ 'test_float' => @test_float,
108
+ 'test_array' => @test_array,
109
+ 'some_nested_record' => @some_nested_record&.to_h,
110
+ 'some_optional_record' => @some_optional_record&.to_h
111
+ }
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Primary Schema Class ###
6
+ # Autogenerated Schema for Record at com.my-namespace.MySchema
7
+ class MySchema < Deimos::SchemaClass::Record
8
+ ### Attribute Readers ###
9
+ # @return [MySchemaKey]
10
+ attr_reader :payload_key
11
+
12
+ ### Attribute Accessors ###
13
+ # @param value [String]
14
+ attr_accessor :test_id
15
+ # @param value [Integer]
16
+ attr_accessor :some_int
17
+
18
+ ### Attribute Writers ###
19
+ # @param value [MySchemaKey]
20
+ def payload_key=(value)
21
+ @payload_key = MySchemaKey.initialize_from_value(value)
22
+ end
23
+
24
+ # @override
25
+ def initialize(test_id: nil,
26
+ some_int: nil,
27
+ payload_key: nil)
28
+ super
29
+ self.test_id = test_id
30
+ self.some_int = some_int
31
+ self.payload_key = payload_key
32
+ end
33
+
34
+ # @override
35
+ def schema
36
+ 'MySchema'
37
+ end
38
+
39
+ # @override
40
+ def namespace
41
+ 'com.my-namespace'
42
+ end
43
+
44
+ # @override
45
+ def to_h
46
+ {
47
+ 'test_id' => @test_id,
48
+ 'some_int' => @some_int,
49
+ 'payload_key' => @payload_key&.to_h
50
+ }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Primary Schema Class ###
6
+ # Autogenerated Schema for Record at com.my-namespace.MySchema-key
7
+ class MySchemaKey < Deimos::SchemaClass::Record
8
+ ### Attribute Accessors ###
9
+ # @param value [String]
10
+ attr_accessor :test_id
11
+
12
+ # @override
13
+ def initialize(test_id: nil)
14
+ super
15
+ self.test_id = test_id
16
+ end
17
+
18
+ # @override
19
+ def schema
20
+ 'MySchema-key'
21
+ end
22
+
23
+ # @override
24
+ def namespace
25
+ 'com.my-namespace'
26
+ end
27
+
28
+ # @override
29
+ def to_h
30
+ {
31
+ 'test_id' => @test_id
32
+ }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Secondary Schema Classes ###
6
+ # Autogenerated Schema for Record at com.my-namespace.ARecord
7
+ class ARecord < Deimos::SchemaClass::Record
8
+ ### Attribute Accessors ###
9
+ # @param value [String]
10
+ attr_accessor :a_record_field
11
+
12
+ # @override
13
+ def initialize(a_record_field: nil)
14
+ super
15
+ self.a_record_field = a_record_field
16
+ end
17
+
18
+ # @override
19
+ def schema
20
+ 'ARecord'
21
+ end
22
+
23
+ # @override
24
+ def namespace
25
+ 'com.my-namespace'
26
+ end
27
+
28
+ # @override
29
+ def to_h
30
+ {
31
+ 'a_record_field' => @a_record_field
32
+ }
33
+ end
34
+ end
35
+
36
+ # Autogenerated Schema for Enum at com.my-namespace.AnEnum
37
+ class AnEnum < Deimos::SchemaClass::Enum
38
+ # @return ['sym1', 'sym2']
39
+ attr_accessor :an_enum
40
+
41
+ # :nodoc:
42
+ def initialize(an_enum)
43
+ super
44
+ self.an_enum = an_enum
45
+ end
46
+
47
+ # @override
48
+ def symbols
49
+ %w(sym1 sym2)
50
+ end
51
+
52
+ # @override
53
+ def to_h
54
+ @an_enum
55
+ end
56
+ end
57
+
58
+ ### Primary Schema Class ###
59
+ # Autogenerated Schema for Record at com.my-namespace.MySchemaWithComplexTypes
60
+ class MySchemaWithComplexTypes < Deimos::SchemaClass::Record
61
+ ### Attribute Readers ###
62
+ # @return [ARecord]
63
+ attr_reader :some_record
64
+ # @return [nil, ARecord]
65
+ attr_reader :some_optional_record
66
+ # @return [Array<ARecord>]
67
+ attr_reader :some_record_array
68
+ # @return [Hash<String, ARecord>]
69
+ attr_reader :some_record_map
70
+ # @return [Array<AnEnum>]
71
+ attr_reader :some_enum_array
72
+
73
+ ### Attribute Accessors ###
74
+ # @param value [String]
75
+ attr_accessor :test_id
76
+ # @param value [Float]
77
+ attr_accessor :test_float
78
+ # @param values [Array<String>]
79
+ attr_accessor :test_string_array
80
+ # @param values [Array<Integer>]
81
+ attr_accessor :test_int_array
82
+ # @param value [Integer, nil]
83
+ attr_accessor :test_optional_int
84
+ # @param values [Hash<String, Integer>]
85
+ attr_accessor :some_integer_map
86
+
87
+ ### Attribute Writers ###
88
+ # @param value [ARecord]
89
+ def some_record=(value)
90
+ @some_record = ARecord.initialize_from_value(value)
91
+ end
92
+
93
+ # @param value [nil, ARecord]
94
+ def some_optional_record=(value)
95
+ @some_optional_record = ARecord.initialize_from_value(value)
96
+ end
97
+
98
+ # @param values [Array<ARecord>]
99
+ def some_record_array=(values)
100
+ @some_record_array = values.map do |value|
101
+ ARecord.initialize_from_value(value)
102
+ end
103
+ end
104
+
105
+ # @param values [Hash<String, ARecord>]
106
+ def some_record_map=(values)
107
+ @some_record_map = values.transform_values do |value|
108
+ ARecord.initialize_from_value(value)
109
+ end
110
+ end
111
+
112
+ # @param values [Array<AnEnum>]
113
+ def some_enum_array=(values)
114
+ @some_enum_array = values.map do |value|
115
+ AnEnum.initialize_from_value(value)
116
+ end
117
+ end
118
+
119
+ # @override
120
+ def initialize(test_id: nil,
121
+ test_float: nil,
122
+ test_string_array: ["test"],
123
+ test_int_array: [123],
124
+ test_optional_int: 123,
125
+ some_integer_map: {"abc"=>123},
126
+ some_record: {"a_record_field"=>"Test String"},
127
+ some_optional_record: nil,
128
+ some_record_array: nil,
129
+ some_record_map: nil,
130
+ some_enum_array: nil)
131
+ super
132
+ self.test_id = test_id
133
+ self.test_float = test_float
134
+ self.test_string_array = test_string_array
135
+ self.test_int_array = test_int_array
136
+ self.test_optional_int = test_optional_int
137
+ self.some_integer_map = some_integer_map
138
+ self.some_record = some_record
139
+ self.some_optional_record = some_optional_record
140
+ self.some_record_array = some_record_array
141
+ self.some_record_map = some_record_map
142
+ self.some_enum_array = some_enum_array
143
+ end
144
+
145
+ # @override
146
+ def schema
147
+ 'MySchemaWithComplexTypes'
148
+ end
149
+
150
+ # @override
151
+ def namespace
152
+ 'com.my-namespace'
153
+ end
154
+
155
+ # @override
156
+ def to_h
157
+ {
158
+ 'test_id' => @test_id,
159
+ 'test_float' => @test_float,
160
+ 'test_string_array' => @test_string_array,
161
+ 'test_int_array' => @test_int_array,
162
+ 'test_optional_int' => @test_optional_int,
163
+ 'some_integer_map' => @some_integer_map,
164
+ 'some_record' => @some_record&.to_h,
165
+ 'some_optional_record' => @some_optional_record&.to_h,
166
+ 'some_record_array' => @some_record_array.map { |v| v&.to_h },
167
+ 'some_record_map' => @some_record_map.transform_values { |v| v&.to_h },
168
+ 'some_enum_array' => @some_enum_array.map { |v| v&.to_h }
169
+ }
170
+ end
171
+ end
172
+ end
@@ -24,6 +24,12 @@
24
24
  "name": "a_double",
25
25
  "type": "double"
26
26
  },
27
+ {
28
+ "name": "an_optional_int",
29
+ "type": [ "null", "int" ],
30
+ "doc": "an optional int",
31
+ "default": null
32
+ },
27
33
  {
28
34
  "name": "an_enum",
29
35
  "type": {