lutaml-store 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +11 -175
- data/README.adoc +233 -1124
- data/lib/lutaml/store/adapter/base.rb +4 -0
- data/lib/lutaml/store/adapter/memory.rb +8 -0
- data/lib/lutaml/store/cache_store.rb +9 -6
- data/lib/lutaml/store/format.rb +19 -0
- data/lib/lutaml/store/http_cache.rb +3 -13
- data/lib/lutaml/store/model_registration.rb +5 -2
- data/lib/lutaml/store/model_registry.rb +22 -20
- data/lib/lutaml/store/package_store.rb +2 -18
- data/lib/lutaml/store/package_transport/base.rb +48 -0
- data/lib/lutaml/store/package_transport/directory_transport.rb +196 -0
- data/lib/lutaml/store/package_transport/zip_transport.rb +178 -0
- data/lib/lutaml/store/package_transport.rb +11 -438
- data/lib/lutaml/store/version.rb +1 -1
- metadata +12 -77
- data/.github/workflows/main.yml +0 -27
- data/.gitignore +0 -12
- data/CORRECTED_HTTP_CACHE_IMPLEMENTATION.md +0 -209
- data/CORRECTED_HTTP_CACHE_PLAN.md +0 -164
- data/Gemfile +0 -15
- data/Gemfile.lock +0 -227
- data/TODO.impl/0-lutaml-store-self-quality.md +0 -112
- data/TODO.impl/1-lutaml-hal-migration.md +0 -96
- data/TODO.impl/2-glossarist-migration.md +0 -359
- data/TODO.impl/3-lutaml-jsonschema-migration.md +0 -273
- data/bin/console +0 -11
- data/bin/setup +0 -8
- data/demo/Gemfile +0 -15
- data/demo/Gemfile.lock +0 -61
- data/demo/README.adoc +0 -301
- data/demo/data/vcards/co/contact_10_thompson.data +0 -1
- data/demo/data/vcards/co/contact_10_thompson.meta +0 -1
- data/demo/data/vcards/co/contact_1_doe.data +0 -1
- data/demo/data/vcards/co/contact_1_doe.meta +0 -1
- data/demo/data/vcards/co/contact_2_smith.data +0 -1
- data/demo/data/vcards/co/contact_2_smith.meta +0 -1
- data/demo/data/vcards/co/contact_3_johnson.data +0 -1
- data/demo/data/vcards/co/contact_3_johnson.meta +0 -1
- data/demo/data/vcards/co/contact_4_garcia.data +0 -1
- data/demo/data/vcards/co/contact_4_garcia.meta +0 -1
- data/demo/data/vcards/co/contact_5_wilson.data +0 -1
- data/demo/data/vcards/co/contact_5_wilson.meta +0 -1
- data/demo/data/vcards/co/contact_6_brown.data +0 -1
- data/demo/data/vcards/co/contact_6_brown.meta +0 -1
- data/demo/data/vcards/co/contact_7_davis.data +0 -1
- data/demo/data/vcards/co/contact_7_davis.meta +0 -1
- data/demo/data/vcards/co/contact_8_anderson.data +0 -1
- data/demo/data/vcards/co/contact_8_anderson.meta +0 -1
- data/demo/data/vcards/co/contact_9_taylor.data +0 -1
- data/demo/data/vcards/co/contact_9_taylor.meta +0 -1
- data/demo/data/vcards.db +0 -0
- data/demo/pottery_class_demo.rb +0 -164
- data/demo/vcard_models.rb +0 -140
- data/demo/vcard_store_demo.rb +0 -526
- data/lutaml-store.gemspec +0 -36
- data/plan.adoc +0 -606
- data/spec/lutaml/store/adapter_interface_spec.rb +0 -89
- data/spec/lutaml/store/anti_pattern_guard_spec.rb +0 -35
- data/spec/lutaml/store/anti_pattern_spec.rb +0 -78
- data/spec/lutaml/store/autoload_spec.rb +0 -34
- data/spec/lutaml/store/cache_store_spec.rb +0 -271
- data/spec/lutaml/store/compression_spec.rb +0 -78
- data/spec/lutaml/store/config_enhanced_spec.rb +0 -158
- data/spec/lutaml/store/corrected_http_cache_integration_spec.rb +0 -336
- data/spec/lutaml/store/custom_serializer_spec.rb +0 -108
- data/spec/lutaml/store/database_store_spec.rb +0 -279
- data/spec/lutaml/store/file_io_spec.rb +0 -220
- data/spec/lutaml/store/format/yamls_spec.rb +0 -80
- data/spec/lutaml/store/format_round_trip_spec.rb +0 -110
- data/spec/lutaml/store/format_spec.rb +0 -70
- data/spec/lutaml/store/http_cache_entry_spec.rb +0 -203
- data/spec/lutaml/store/http_cache_hal_integration_spec.rb +0 -404
- data/spec/lutaml/store/http_cache_spec.rb +0 -422
- data/spec/lutaml/store/http_header_processor_spec.rb +0 -290
- data/spec/lutaml/store/import_spec.rb +0 -90
- data/spec/lutaml/store/integrity_spec.rb +0 -157
- data/spec/lutaml/store/key_collision_serializer_spec.rb +0 -98
- data/spec/lutaml/store/load_save_spec.rb +0 -107
- data/spec/lutaml/store/lutaml_model_integration_spec.rb +0 -291
- data/spec/lutaml/store/model_serializer_spec.rb +0 -140
- data/spec/lutaml/store/package_definition_spec.rb +0 -89
- data/spec/lutaml/store/package_store_spec.rb +0 -153
- data/spec/lutaml/store/package_transport/directory_transport_spec.rb +0 -139
- data/spec/lutaml/store/package_transport/zip_transport_spec.rb +0 -85
- data/spec/lutaml/store/store_spec.rb +0 -182
- data/spec/lutaml/store_spec.rb +0 -21
- data/spec/spec_helper.rb +0 -16
- data/spec/support/simple_test_model.rb +0 -15
- 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
|
data/spec/lutaml/store_spec.rb
DELETED
|
@@ -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
|