lutaml-store 0.2.0 → 0.2.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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +13 -177
  3. data/CLAUDE.md +22 -9
  4. data/README.adoc +326 -1103
  5. data/lib/lutaml/store/adapter/base.rb +4 -0
  6. data/lib/lutaml/store/adapter/memory.rb +8 -0
  7. data/lib/lutaml/store/adapter.rb +17 -0
  8. data/lib/lutaml/store/basic_store.rb +1 -10
  9. data/lib/lutaml/store/cache_store.rb +11 -16
  10. data/lib/lutaml/store/database_store.rb +19 -9
  11. data/lib/lutaml/store/format/base.rb +4 -0
  12. data/lib/lutaml/store/format/marshal_format.rb +4 -0
  13. data/lib/lutaml/store/format/xml.rb +37 -0
  14. data/lib/lutaml/store/format/yamls.rb +1 -1
  15. data/lib/lutaml/store/format.rb +22 -1
  16. data/lib/lutaml/store/format_serializer.rb +44 -0
  17. data/lib/lutaml/store/http_cache.rb +3 -13
  18. data/lib/lutaml/store/model_registration.rb +5 -2
  19. data/lib/lutaml/store/model_registry.rb +22 -20
  20. data/lib/lutaml/store/package_store.rb +2 -18
  21. data/lib/lutaml/store/package_transport/base.rb +60 -0
  22. data/lib/lutaml/store/package_transport/directory_transport.rb +196 -0
  23. data/lib/lutaml/store/package_transport/zip_transport.rb +183 -0
  24. data/lib/lutaml/store/package_transport.rb +11 -438
  25. data/lib/lutaml/store/storage_key.rb +1 -1
  26. data/lib/lutaml/store/version.rb +1 -1
  27. data/lib/lutaml/store.rb +1 -0
  28. metadata +14 -77
  29. data/.github/workflows/main.yml +0 -27
  30. data/.gitignore +0 -12
  31. data/CORRECTED_HTTP_CACHE_IMPLEMENTATION.md +0 -209
  32. data/CORRECTED_HTTP_CACHE_PLAN.md +0 -164
  33. data/Gemfile +0 -15
  34. data/Gemfile.lock +0 -227
  35. data/TODO.impl/0-lutaml-store-self-quality.md +0 -112
  36. data/TODO.impl/1-lutaml-hal-migration.md +0 -96
  37. data/TODO.impl/2-glossarist-migration.md +0 -359
  38. data/TODO.impl/3-lutaml-jsonschema-migration.md +0 -273
  39. data/bin/console +0 -11
  40. data/bin/setup +0 -8
  41. data/demo/Gemfile +0 -15
  42. data/demo/Gemfile.lock +0 -61
  43. data/demo/README.adoc +0 -301
  44. data/demo/data/vcards/co/contact_10_thompson.data +0 -1
  45. data/demo/data/vcards/co/contact_10_thompson.meta +0 -1
  46. data/demo/data/vcards/co/contact_1_doe.data +0 -1
  47. data/demo/data/vcards/co/contact_1_doe.meta +0 -1
  48. data/demo/data/vcards/co/contact_2_smith.data +0 -1
  49. data/demo/data/vcards/co/contact_2_smith.meta +0 -1
  50. data/demo/data/vcards/co/contact_3_johnson.data +0 -1
  51. data/demo/data/vcards/co/contact_3_johnson.meta +0 -1
  52. data/demo/data/vcards/co/contact_4_garcia.data +0 -1
  53. data/demo/data/vcards/co/contact_4_garcia.meta +0 -1
  54. data/demo/data/vcards/co/contact_5_wilson.data +0 -1
  55. data/demo/data/vcards/co/contact_5_wilson.meta +0 -1
  56. data/demo/data/vcards/co/contact_6_brown.data +0 -1
  57. data/demo/data/vcards/co/contact_6_brown.meta +0 -1
  58. data/demo/data/vcards/co/contact_7_davis.data +0 -1
  59. data/demo/data/vcards/co/contact_7_davis.meta +0 -1
  60. data/demo/data/vcards/co/contact_8_anderson.data +0 -1
  61. data/demo/data/vcards/co/contact_8_anderson.meta +0 -1
  62. data/demo/data/vcards/co/contact_9_taylor.data +0 -1
  63. data/demo/data/vcards/co/contact_9_taylor.meta +0 -1
  64. data/demo/data/vcards.db +0 -0
  65. data/demo/pottery_class_demo.rb +0 -164
  66. data/demo/vcard_models.rb +0 -140
  67. data/demo/vcard_store_demo.rb +0 -526
  68. data/lutaml-store.gemspec +0 -36
  69. data/plan.adoc +0 -606
  70. data/spec/lutaml/store/adapter_interface_spec.rb +0 -89
  71. data/spec/lutaml/store/anti_pattern_guard_spec.rb +0 -35
  72. data/spec/lutaml/store/anti_pattern_spec.rb +0 -78
  73. data/spec/lutaml/store/autoload_spec.rb +0 -34
  74. data/spec/lutaml/store/cache_store_spec.rb +0 -271
  75. data/spec/lutaml/store/compression_spec.rb +0 -78
  76. data/spec/lutaml/store/config_enhanced_spec.rb +0 -158
  77. data/spec/lutaml/store/corrected_http_cache_integration_spec.rb +0 -336
  78. data/spec/lutaml/store/custom_serializer_spec.rb +0 -108
  79. data/spec/lutaml/store/database_store_spec.rb +0 -279
  80. data/spec/lutaml/store/file_io_spec.rb +0 -220
  81. data/spec/lutaml/store/format/yamls_spec.rb +0 -80
  82. data/spec/lutaml/store/format_round_trip_spec.rb +0 -110
  83. data/spec/lutaml/store/format_spec.rb +0 -70
  84. data/spec/lutaml/store/http_cache_entry_spec.rb +0 -203
  85. data/spec/lutaml/store/http_cache_hal_integration_spec.rb +0 -404
  86. data/spec/lutaml/store/http_cache_spec.rb +0 -422
  87. data/spec/lutaml/store/http_header_processor_spec.rb +0 -290
  88. data/spec/lutaml/store/import_spec.rb +0 -90
  89. data/spec/lutaml/store/integrity_spec.rb +0 -157
  90. data/spec/lutaml/store/key_collision_serializer_spec.rb +0 -98
  91. data/spec/lutaml/store/load_save_spec.rb +0 -107
  92. data/spec/lutaml/store/lutaml_model_integration_spec.rb +0 -291
  93. data/spec/lutaml/store/model_serializer_spec.rb +0 -140
  94. data/spec/lutaml/store/package_definition_spec.rb +0 -89
  95. data/spec/lutaml/store/package_store_spec.rb +0 -153
  96. data/spec/lutaml/store/package_transport/directory_transport_spec.rb +0 -139
  97. data/spec/lutaml/store/package_transport/zip_transport_spec.rb +0 -85
  98. data/spec/lutaml/store/store_spec.rb +0 -182
  99. data/spec/lutaml/store_spec.rb +0 -21
  100. data/spec/spec_helper.rb +0 -16
  101. data/spec/support/simple_test_model.rb +0 -15
  102. data/spec/support/yamls_test_model.rb +0 -35
@@ -1,139 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "support/simple_test_model"
5
-
6
- RSpec.describe Lutaml::Store::PackageTransport::DirectoryTransport do
7
- let(:transport) { described_class.new }
8
- let(:tmpdir) { Dir.mktmpdir }
9
- after { FileUtils.rm_rf(tmpdir) }
10
-
11
- let(:definition) do
12
- Lutaml::Store::PackageDefinition.new(
13
- name: :test, metadata_model: SimpleTestModel,
14
- metadata_file: "meta.yaml", metadata_key: :id
15
- ) do |pkg|
16
- pkg.model(model: SimpleTestModel, dir: "items",
17
- layout: :separate, key: :id, default_format: :yaml)
18
- pkg.asset("data.bin", type: :file)
19
- pkg.asset("images", type: :directory)
20
- end
21
- end
22
-
23
- describe "round-trip: write then read" do
24
- it "preserves models, metadata, and assets" do
25
- store = Lutaml::Store::PackageStore.new(definition)
26
- store.add_model(SimpleTestModel.new(id: "item-1", name: "First"))
27
- store.add_model(SimpleTestModel.new(id: "item-2", name: "Second"))
28
- store.metadata = SimpleTestModel.new(id: "meta", name: "Test Package")
29
- store.add_asset("data.bin", "BINARY_CONTENT")
30
- store.add_asset("images/logo.png", "PNG_BYTES")
31
-
32
- output_dir = File.join(tmpdir, "output")
33
- store.save(output_dir, transport: :directory)
34
-
35
- # Verify file structure
36
- expect(File.exist?(File.join(output_dir, "meta.yaml"))).to be true
37
- expect(File.exist?(File.join(output_dir, "items", "item-1.yaml"))).to be true
38
- expect(File.exist?(File.join(output_dir, "items", "item-2.yaml"))).to be true
39
- expect(File.exist?(File.join(output_dir, "data.bin"))).to be true
40
- expect(File.exist?(File.join(output_dir, "images", "logo.png"))).to be true
41
-
42
- # Load back
43
- loaded = Lutaml::Store::PackageStore.load(definition, output_dir,
44
- transport: :directory)
45
- expect(loaded.model_count(SimpleTestModel)).to eq(2)
46
- expect(loaded.metadata.name).to eq("Test Package")
47
- expect(loaded.asset("data.bin")).to eq("BINARY_CONTENT")
48
- expect(loaded.asset("images/logo.png")).to eq("PNG_BYTES")
49
- end
50
- end
51
-
52
- describe "missing optional entries" do
53
- it "loads successfully with empty directory" do
54
- empty_dir = File.join(tmpdir, "empty")
55
- FileUtils.mkdir_p(File.join(empty_dir, "items"))
56
- loaded = Lutaml::Store::PackageStore.load(definition, empty_dir,
57
- transport: :directory)
58
- expect(loaded.model_count(SimpleTestModel)).to eq(0)
59
- expect(loaded.metadata).to be_nil
60
- end
61
- end
62
-
63
- describe "format override" do
64
- it "writes models in JSON format when overridden" do
65
- store = Lutaml::Store::PackageStore.new(definition)
66
- store.add_model(SimpleTestModel.new(id: "item-1", name: "First"))
67
-
68
- output_dir = File.join(tmpdir, "json")
69
- store.save(output_dir, transport: :directory,
70
- formats: { SimpleTestModel => :json })
71
-
72
- files = Dir.glob(File.join(output_dir, "items", "*"))
73
- expect(files.length).to eq(1)
74
- expect(File.extname(files.first)).to eq(".json")
75
- end
76
-
77
- it "loads models saved in JSON format" do
78
- store = Lutaml::Store::PackageStore.new(definition)
79
- store.add_model(SimpleTestModel.new(id: "item-1", name: "First"))
80
-
81
- output_dir = File.join(tmpdir, "json")
82
- store.save(output_dir, transport: :directory,
83
- formats: { SimpleTestModel => :json })
84
-
85
- loaded = Lutaml::Store::PackageStore.load(definition, output_dir,
86
- transport: :directory,
87
- format: :json)
88
- expect(loaded.model_count(SimpleTestModel)).to eq(1)
89
- expect(loaded.fetch_model(SimpleTestModel, "item-1").name).to eq("First")
90
- end
91
- end
92
-
93
- describe "corrupt file handling" do
94
- it "warns and continues when a model file is corrupt" do
95
- dir = File.join(tmpdir, "corrupt")
96
- FileUtils.mkdir_p(File.join(dir, "items"))
97
- File.write(File.join(dir, "items", "good.yaml"), "---\nid: good\nname: OK\n")
98
- File.write(File.join(dir, "items", "bad.yaml"), "{{{{not yaml")
99
-
100
- expect do
101
- Lutaml::Store::PackageStore.load(definition, dir, transport: :directory)
102
- end.to output(/failed to load/).to_stderr
103
-
104
- loaded = Lutaml::Store::PackageStore.load(definition, dir,
105
- transport: :directory)
106
- expect(loaded.model_count(SimpleTestModel)).to eq(1)
107
- end
108
- end
109
-
110
- describe "dir: nil (root-level models)" do
111
- let(:root_definition) do
112
- Lutaml::Store::PackageDefinition.new(name: :root_test) do |pkg|
113
- pkg.model(model: SimpleTestModel, dir: nil,
114
- layout: :separate, key: :id, default_format: :yaml)
115
- end
116
- end
117
-
118
- it "writes models to package root" do
119
- store = Lutaml::Store::PackageStore.new(root_definition)
120
- store.add_model(SimpleTestModel.new(id: "root-1", name: "Root"))
121
-
122
- output_dir = File.join(tmpdir, "root")
123
- store.save(output_dir, transport: :directory)
124
-
125
- expect(File.exist?(File.join(output_dir, "root-1.yaml"))).to be true
126
- end
127
-
128
- it "reads models from package root" do
129
- dir = File.join(tmpdir, "root_read")
130
- FileUtils.mkdir_p(dir)
131
- File.write(File.join(dir, "abc.yaml"), "---\nid: abc\nname: Found\n")
132
-
133
- loaded = Lutaml::Store::PackageStore.load(root_definition, dir,
134
- transport: :directory)
135
- expect(loaded.model_count(SimpleTestModel)).to eq(1)
136
- expect(loaded.fetch_model(SimpleTestModel, "abc").name).to eq("Found")
137
- end
138
- end
139
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "support/simple_test_model"
5
- require "zip"
6
-
7
- RSpec.describe Lutaml::Store::PackageTransport::ZipTransport do
8
- let(:tmpdir) { Dir.mktmpdir }
9
- after { FileUtils.rm_rf(tmpdir) }
10
-
11
- let(:definition) do
12
- Lutaml::Store::PackageDefinition.new(
13
- name: :test, metadata_model: SimpleTestModel, metadata_file: "meta.yaml",
14
- metadata_key: :id
15
- ) do |pkg|
16
- pkg.model(model: SimpleTestModel, dir: "items",
17
- layout: :separate, key: :id, default_format: :yaml)
18
- pkg.asset("data.bin", type: :file)
19
- end
20
- end
21
-
22
- describe "round-trip through ZIP" do
23
- it "preserves models, metadata, and assets" do
24
- store = Lutaml::Store::PackageStore.new(definition)
25
- store.add_model(SimpleTestModel.new(id: "item-1", name: "First"))
26
- store.metadata = SimpleTestModel.new(id: "meta", name: "Package")
27
- store.add_asset("data.bin", "BINARY")
28
-
29
- zip_path = File.join(tmpdir, "test.zip")
30
- store.save(zip_path, transport: :zip)
31
-
32
- expect(File.exist?(zip_path)).to be true
33
-
34
- # Verify ZIP contents
35
- Zip::File.open(zip_path) do |zf|
36
- expect(zf.find_entry("meta.yaml")).not_to be_nil
37
- expect(zf.find_entry("items/item-1.yaml")).not_to be_nil
38
- expect(zf.find_entry("data.bin")).not_to be_nil
39
- end
40
-
41
- # Load from ZIP
42
- loaded = Lutaml::Store::PackageStore.load(definition, zip_path,
43
- transport: :zip)
44
- expect(loaded.model_count(SimpleTestModel)).to eq(1)
45
- expect(loaded.metadata.name).to eq("Package")
46
- expect(loaded.asset("data.bin")).to eq("BINARY")
47
- end
48
- end
49
-
50
- describe "directory → ZIP → directory round-trip" do
51
- it "preserves data through format conversion" do
52
- dir = File.join(tmpdir, "source")
53
- dir_store = Lutaml::Store::PackageStore.new(definition)
54
- dir_store.add_model(SimpleTestModel.new(id: "abc", name: "Test"))
55
- dir_store.metadata = SimpleTestModel.new(id: "meta", name: "Dir Package")
56
- dir_store.save(dir, transport: :directory)
57
-
58
- loaded_from_dir = Lutaml::Store::PackageStore.load(definition, dir,
59
- transport: :directory)
60
- zip_path = File.join(tmpdir, "converted.zip")
61
- loaded_from_dir.save(zip_path, transport: :zip)
62
-
63
- loaded_from_zip = Lutaml::Store::PackageStore.load(definition, zip_path,
64
- transport: :zip)
65
- expect(loaded_from_zip.model_count(SimpleTestModel)).to eq(1)
66
- expect(loaded_from_zip.fetch_model(SimpleTestModel, "abc").name).to eq("Test")
67
- expect(loaded_from_zip.metadata.name).to eq("Dir Package")
68
- end
69
- end
70
-
71
- describe "format override in ZIP" do
72
- it "writes models in JSON format" do
73
- store = Lutaml::Store::PackageStore.new(definition)
74
- store.add_model(SimpleTestModel.new(id: "item-1", name: "First"))
75
-
76
- zip_path = File.join(tmpdir, "json.zip")
77
- store.save(zip_path, transport: :zip,
78
- formats: { SimpleTestModel => :json })
79
-
80
- Zip::File.open(zip_path) do |zf|
81
- expect(zf.find_entry("items/item-1.json")).not_to be_nil
82
- end
83
- end
84
- end
85
- end
@@ -1,182 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- RSpec.describe Lutaml::Store::BasicStore do
6
- let(:store) { described_class.new }
7
-
8
- describe "initialization" do
9
- it "creates a store with default memory adapter" do
10
- expect(store.adapter).to be_a(Lutaml::Store::Adapter::Memory)
11
- end
12
-
13
- it "creates a store with configuration hash" do
14
- config = {
15
- "adapter" => { "type" => "memory" },
16
- "cache" => { "enabled" => false }
17
- }
18
- store = described_class.new(config)
19
- expect(store.cache).to be_nil
20
- end
21
-
22
- it "creates a store with direct adapter instance" do
23
- adapter = Lutaml::Store::Adapter::Memory.new
24
- store = described_class.new(adapter)
25
- expect(store.adapter).to eq(adapter)
26
- end
27
- end
28
-
29
- describe "basic operations" do
30
- it "stores and retrieves values" do
31
- store.set("key1", "value1")
32
- expect(store.get("key1")).to eq("value1")
33
- end
34
-
35
- it "returns nil for non-existent keys" do
36
- expect(store.get("nonexistent")).to be_nil
37
- end
38
-
39
- it "deletes values" do
40
- store.set("key1", "value1")
41
- expect(store.delete("key1")).to be true
42
- expect(store.get("key1")).to be_nil
43
- end
44
-
45
- it "checks key existence" do
46
- store.set("key1", "value1")
47
- expect(store.exists?("key1")).to be true
48
- expect(store.exists?("nonexistent")).to be false
49
- end
50
-
51
- it "returns all data" do
52
- store.set("key1", "value1")
53
- store.set("key2", "value2")
54
- expect(store.all).to eq("key1" => "value1", "key2" => "value2")
55
- end
56
-
57
- it "clears all data" do
58
- store.set("key1", "value1")
59
- store.clear
60
- expect(store.size).to eq(0)
61
- end
62
-
63
- it "returns correct size" do
64
- expect(store.size).to eq(0)
65
- store.set("key1", "value1")
66
- expect(store.size).to eq(1)
67
- end
68
- end
69
-
70
- describe "caching" do
71
- let(:config) do
72
- {
73
- "adapter" => { "type" => "memory" },
74
- "cache" => { "enabled" => true, "max_size" => 10 }
75
- }
76
- end
77
- let(:store) { described_class.new(config) }
78
-
79
- it "caches retrieved values" do
80
- store.set("key1", "value1")
81
-
82
- # First get should hit backend
83
- value1 = store.get("key1")
84
- expect(value1).to eq("value1")
85
-
86
- # Second get should hit cache
87
- value2 = store.get("key1")
88
- expect(value2).to eq("value1")
89
-
90
- # Cache should contain the value
91
- expect(store.cache_stats[:size]).to eq(1)
92
- end
93
-
94
- it "invalidates cache on delete" do
95
- store.set("key1", "value1")
96
- store.get("key1") # Cache the value
97
-
98
- store.delete("key1")
99
- expect(store.cache_stats[:size]).to eq(0)
100
- end
101
- end
102
-
103
- describe "events" do
104
- let(:events) { [] }
105
-
106
- before do
107
- store.on(:set) { |data| events << data }
108
- store.on(:get) { |data| events << data }
109
- store.on(:delete) { |data| events << data }
110
- end
111
-
112
- it "emits events for operations" do
113
- store.set("key1", "value1")
114
- store.get("key1")
115
- store.delete("key1")
116
-
117
- expect(events.size).to eq(3)
118
- expect(events[0][:event]).to eq(:set)
119
- expect(events[1][:event]).to eq(:get)
120
- expect(events[2][:event]).to eq(:delete)
121
- end
122
- end
123
-
124
- describe "monitoring" do
125
- let(:config) do
126
- {
127
- "adapter" => { "type" => "memory" },
128
- "monitoring" => { "enabled" => true }
129
- }
130
- end
131
- let(:store) { described_class.new(config) }
132
-
133
- it "tracks operation statistics" do
134
- store.set("key1", "value1")
135
- store.get("key1")
136
-
137
- stats = store.stats
138
- monitor_stats = stats[:monitor_stats]
139
- expect(monitor_stats[:operations][:set]).to eq(1)
140
- expect(monitor_stats[:operations][:get]).to eq(1)
141
- # NOTE: total_operations includes the size call from stats method
142
- expect(monitor_stats[:total_operations]).to be >= 2
143
- end
144
- end
145
-
146
- describe "configuration from file" do
147
- let(:config_file) { "test_config.yml" }
148
- let(:config_content) do
149
- <<~YAML
150
- lutaml_store:
151
- adapter:
152
- type: memory
153
- cache:
154
- enabled: true
155
- max_size: 500
156
- monitoring:
157
- enabled: true
158
- YAML
159
- end
160
-
161
- before do
162
- File.write(config_file, config_content)
163
- end
164
-
165
- after do
166
- File.delete(config_file) if File.exist?(config_file)
167
- end
168
-
169
- it "loads configuration from YAML file" do
170
- store = described_class.from_file(config_file)
171
- expect(store.adapter).to be_a(Lutaml::Store::Adapter::Memory)
172
- expect(store.cache).not_to be_nil
173
- expect(store.monitor).not_to be_nil
174
- end
175
- end
176
-
177
- describe "#close" do
178
- it "closes resources properly" do
179
- expect { store.close }.not_to raise_error
180
- end
181
- end
182
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Lutaml::Store do
4
- it "has a version number" do
5
- expect(Lutaml::Store::VERSION).not_to be nil
6
- end
7
-
8
- it "provides access to Store and DatabaseStore classes" do
9
- expect(Lutaml::Store::BasicStore).to be_a(Class)
10
- expect(Lutaml::Store::DatabaseStore).to be_a(Class)
11
- end
12
-
13
- it "returns a DatabaseStore from .new" do
14
- test_model = Struct.new(:id, :name)
15
- store = Lutaml::Store.new(
16
- adapter: :memory,
17
- models: [{ model: test_model, key: :id }]
18
- )
19
- expect(store).to be_a(Lutaml::Store::DatabaseStore)
20
- end
21
- end
data/spec/spec_helper.rb DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "lutaml/model"
4
- require "lutaml/store"
5
-
6
- RSpec.configure do |config|
7
- # Enable flags like --only-failures and --next-failure
8
- config.example_status_persistence_file_path = ".rspec_status"
9
-
10
- # Disable RSpec exposing methods globally on `Module` and `main`
11
- config.disable_monkey_patching!
12
-
13
- config.expect_with :rspec do |c|
14
- c.syntax = :expect
15
- end
16
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Simple model with key_value DSL for testing package components
4
- # without depending on glossarist or lutaml-jsonschema.
5
- class SimpleTestModel < Lutaml::Model::Serializable
6
- attribute :id, :string
7
- attribute :name, :string
8
- attribute :value, :string
9
-
10
- key_value do
11
- map "id", to: :id
12
- map "name", to: :name
13
- map "value", to: :value
14
- end
15
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Minimal model with yamls DSL for testing Format::Yamls.
4
- # Structure mirrors ConceptDocument: header + collection of parts.
5
- class YamlsTestHeader < Lutaml::Model::Serializable
6
- attribute :id, :string
7
- attribute :name, :string
8
-
9
- yaml do
10
- map "id", to: :id
11
- map "name", to: :name
12
- end
13
- end
14
-
15
- class YamlsTestPart < Lutaml::Model::Serializable
16
- attribute :label, :string
17
- attribute :value, :string
18
-
19
- yaml do
20
- map "label", to: :label
21
- map "value", to: :value
22
- end
23
- end
24
-
25
- class YamlsTestModel < Lutaml::Model::Serializable
26
- attribute :header, YamlsTestHeader
27
- attribute :parts, YamlsTestPart, collection: true
28
-
29
- yamls do
30
- sequence do
31
- map_document 0, to: :header, type: YamlsTestHeader
32
- map_document 1.., to: :parts, type: YamlsTestPart, collection: true
33
- end
34
- end
35
- end