hexx-storage 0.0.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.
- checksums.yaml +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +9 -0
- data/.metrics +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +12 -0
- data/.yardopts +3 -0
- data/Gemfile +12 -0
- data/Guardfile +14 -0
- data/LICENSE +21 -0
- data/README.md +351 -0
- data/Rakefile +22 -0
- data/config/metrics/STYLEGUIDE +230 -0
- data/config/metrics/cane.yml +5 -0
- data/config/metrics/churn.yml +6 -0
- data/config/metrics/flay.yml +2 -0
- data/config/metrics/metric_fu.yml +13 -0
- data/config/metrics/reek.yml +1 -0
- data/config/metrics/roodi.yml +24 -0
- data/config/metrics/rubocop.yml +73 -0
- data/config/metrics/saikuro.yml +3 -0
- data/config/metrics/simplecov.yml +8 -0
- data/config/metrics/yardstick.yml +37 -0
- data/hexx-storage.gemspec +28 -0
- data/lib/hexx-storage.rb +20 -0
- data/lib/hexx/storage.rb +17 -0
- data/lib/hexx/storage/base.rb +108 -0
- data/lib/hexx/storage/patches.rb +135 -0
- data/lib/hexx/storage/repositories.rb +40 -0
- data/lib/hexx/storage/repositories/base.rb +70 -0
- data/lib/hexx/storage/repositories/memory.rb +33 -0
- data/lib/hexx/storage/repositories/sql.rb +78 -0
- data/lib/hexx/storage/version.rb +13 -0
- data/spec/integration/storage.yml +9 -0
- data/spec/integration/storage_spec.rb +56 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/tests/storage/base_spec.rb +178 -0
- data/spec/tests/storage/patches_spec.rb +202 -0
- data/spec/tests/storage/repositories/base_spec.rb +120 -0
- data/spec/tests/storage/repositories/memory_spec.rb +32 -0
- data/spec/tests/storage/repositories/sql_spec.rb +180 -0
- data/spec/tests/storage/repositories_spec.rb +66 -0
- data/spec/tests/storage_spec.rb +24 -0
- metadata +168 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "rom/memory"
|
4
|
+
require "rom-sql"
|
5
|
+
require "sequel/adapters/postgres"
|
6
|
+
|
7
|
+
describe "Loading a storage" do
|
8
|
+
|
9
|
+
let(:migrate) { File.expand_path "../migrate", __FILE__ }
|
10
|
+
let(:tmp) { File.expand_path "../tmp", __FILE__ }
|
11
|
+
before do
|
12
|
+
`mkdir #{ migrate } -p`
|
13
|
+
`mkdir #{ tmp } -p`
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:storage) { Hexx::Storage.setup }
|
17
|
+
|
18
|
+
before do
|
19
|
+
storage.root = File.expand_path "..", __FILE__
|
20
|
+
storage.load "storage.yml", env: "foo"
|
21
|
+
storage[:baz].migrations = migrate
|
22
|
+
|
23
|
+
ROM.setup storage.settings
|
24
|
+
ROM.finalize
|
25
|
+
|
26
|
+
storage.each do |key, value|
|
27
|
+
next unless value.logger
|
28
|
+
ROM.env.repositories[key].use_logger value.logger
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
subject { ROM.env.repositories }
|
33
|
+
|
34
|
+
it "sets repositories" do
|
35
|
+
expect(subject.keys).to eq %i(bar baz)
|
36
|
+
expect(subject[:bar]).to be_kind_of ROM::Memory::Repository
|
37
|
+
expect(subject[:baz]).to be_kind_of ROM::SQL::Repository
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sets loggers" do
|
41
|
+
expect(subject[:bar].logger).to be_nil
|
42
|
+
expect(subject[:baz].logger).to be_kind_of Logger
|
43
|
+
end
|
44
|
+
|
45
|
+
it "sets sql migrators" do
|
46
|
+
repo = subject[:baz]
|
47
|
+
expect(repo.migrator).not_to be_nil
|
48
|
+
expect(repo.migrator.path).to eq migrate
|
49
|
+
end
|
50
|
+
|
51
|
+
after do
|
52
|
+
`rm #{ migrate } -r -f`
|
53
|
+
`rm #{ tmp } -r -f`
|
54
|
+
end
|
55
|
+
|
56
|
+
end # specification
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe Hexx::Storage::Base do
|
4
|
+
|
5
|
+
# Stub builder to isolate tests
|
6
|
+
let(:settings) { double :settings }
|
7
|
+
let(:storage) { double :storage, settings: settings }
|
8
|
+
let(:builder) { Hexx::Storage::Repositories }
|
9
|
+
before { allow(builder).to receive(:build) { storage } }
|
10
|
+
|
11
|
+
shared_context "setup" do
|
12
|
+
before do
|
13
|
+
subject.root = File.expand_path "..", __FILE__
|
14
|
+
subject.setup foo: { adapter: :memory }, bar: { adapter: :memory }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#root" do
|
19
|
+
|
20
|
+
it "returns nil by default" do
|
21
|
+
expect(subject.root).to be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
end # describe #root
|
25
|
+
|
26
|
+
describe "#root=" do
|
27
|
+
|
28
|
+
let(:folder) { File.expand_path "..", __FILE__ }
|
29
|
+
let(:wrong) { File.join folder, "wrong" }
|
30
|
+
|
31
|
+
it "sets the #root if a folder exists" do
|
32
|
+
expect { subject.root = folder }.to change { subject.root }.to folder
|
33
|
+
end
|
34
|
+
|
35
|
+
it "doesn't set the #root if a folder is absent" do
|
36
|
+
expect { subject.root = wrong }.not_to change { subject.root }
|
37
|
+
end
|
38
|
+
|
39
|
+
end # describe #root=
|
40
|
+
|
41
|
+
describe "#setup" do
|
42
|
+
|
43
|
+
let(:source) do
|
44
|
+
{ "foo" => { "adapter" => "memory", "uri" => "bar", "log" => "baz" } }
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when #root hasn't been set" do
|
48
|
+
|
49
|
+
it "raises NotImplementedError" do
|
50
|
+
expect { subject.setup(source) }.to raise_error NotImplementedError
|
51
|
+
end
|
52
|
+
|
53
|
+
end # context
|
54
|
+
|
55
|
+
context "when #root has been set" do
|
56
|
+
|
57
|
+
let(:root) { File.expand_path "..", __FILE__ }
|
58
|
+
before { subject.root = root }
|
59
|
+
|
60
|
+
it "builds repo storages" do
|
61
|
+
expect(builder)
|
62
|
+
.to receive(:build)
|
63
|
+
.with(root: root, adapter: "memory", uri: "bar", log: "baz")
|
64
|
+
subject.setup source
|
65
|
+
end
|
66
|
+
|
67
|
+
it "sets storages" do
|
68
|
+
expect { subject.setup source }.to change { subject[:foo] }.to storage
|
69
|
+
end
|
70
|
+
|
71
|
+
end # context
|
72
|
+
|
73
|
+
end # describe #setup
|
74
|
+
|
75
|
+
describe "#load" do
|
76
|
+
|
77
|
+
let(:file) { Tempfile.new %w(foo .yml) }
|
78
|
+
let(:path) { file.path }
|
79
|
+
let(:name) { File.basename path }
|
80
|
+
|
81
|
+
before do
|
82
|
+
file.write "---\ntest:\n foo:\n adapter: foo\n uri: bar\n"
|
83
|
+
file.read
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when #root hasn't been set" do
|
87
|
+
|
88
|
+
it "raises NotImplementedError" do
|
89
|
+
expect { subject.load(name, env: "test") }
|
90
|
+
.to raise_error NotImplementedError
|
91
|
+
end
|
92
|
+
|
93
|
+
end # context
|
94
|
+
|
95
|
+
context "when #root has been set" do
|
96
|
+
|
97
|
+
let(:root) { File.dirname path }
|
98
|
+
before { subject.root = root }
|
99
|
+
|
100
|
+
it "sets storages from file" do
|
101
|
+
expect(subject)
|
102
|
+
.to receive(:setup)
|
103
|
+
.with("foo" => { "adapter" => "foo", "uri" => "bar" })
|
104
|
+
subject.load name, env: "test"
|
105
|
+
end
|
106
|
+
|
107
|
+
end # context
|
108
|
+
|
109
|
+
end # describe #load
|
110
|
+
|
111
|
+
describe "#settings" do
|
112
|
+
|
113
|
+
context "before the #setup" do
|
114
|
+
|
115
|
+
it "raises NotImplementedError" do
|
116
|
+
expect { subject.settings }.to raise_error NotImplementedError
|
117
|
+
end
|
118
|
+
|
119
|
+
end # context
|
120
|
+
|
121
|
+
context "after the #setup" do
|
122
|
+
|
123
|
+
include_context "setup"
|
124
|
+
|
125
|
+
it "returns hash of repositories' settings" do
|
126
|
+
expect(subject.settings).to eq(foo: settings, bar: settings)
|
127
|
+
end
|
128
|
+
|
129
|
+
end # context
|
130
|
+
|
131
|
+
end # describe #settings
|
132
|
+
|
133
|
+
describe "#[]" do
|
134
|
+
|
135
|
+
context "by default" do
|
136
|
+
|
137
|
+
it "returns nil" do
|
138
|
+
expect(subject[:foo]).to be_nil
|
139
|
+
end
|
140
|
+
|
141
|
+
end # context
|
142
|
+
|
143
|
+
context "after setup" do
|
144
|
+
|
145
|
+
include_context "setup"
|
146
|
+
let(:repo_storage_class) { Hexx::Storage::Repositories::Memory }
|
147
|
+
|
148
|
+
it "returns the repository settings storage" do
|
149
|
+
expect(subject[:foo]).to eq storage
|
150
|
+
end
|
151
|
+
|
152
|
+
end # context
|
153
|
+
|
154
|
+
end # describe #[]
|
155
|
+
|
156
|
+
describe "#keys" do
|
157
|
+
|
158
|
+
context "by default" do
|
159
|
+
|
160
|
+
it "returns []" do
|
161
|
+
expect(subject.keys).to eq []
|
162
|
+
end
|
163
|
+
|
164
|
+
end # context
|
165
|
+
|
166
|
+
context "after setup" do
|
167
|
+
|
168
|
+
include_context "setup"
|
169
|
+
|
170
|
+
it "returns names of repositories" do
|
171
|
+
expect(subject.keys).to match_array %i(foo bar)
|
172
|
+
end
|
173
|
+
|
174
|
+
end # context
|
175
|
+
|
176
|
+
end # describe #keys
|
177
|
+
|
178
|
+
end # describe Hexx::Storage::Base
|
@@ -0,0 +1,202 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "tempfile"
|
4
|
+
|
5
|
+
describe Hexx::Storage::Patches do
|
6
|
+
using described_class
|
7
|
+
|
8
|
+
describe "for Hash" do
|
9
|
+
|
10
|
+
describe "#normalize" do
|
11
|
+
|
12
|
+
let(:source) { { "foo" => "bar", 1 => "qux" } }
|
13
|
+
let(:target) { { foo: "bar", :"1" => "qux" } }
|
14
|
+
|
15
|
+
it "normalizes a hash" do
|
16
|
+
expect(source.normalize).to eq target
|
17
|
+
end
|
18
|
+
|
19
|
+
end # describe #normalize
|
20
|
+
|
21
|
+
describe "#sub" do
|
22
|
+
|
23
|
+
let(:source) { { "foo" => { "bar" => "baz" }, "bar" => "qux" } }
|
24
|
+
|
25
|
+
context "when a value is a hash" do
|
26
|
+
|
27
|
+
subject { source.sub :foo }
|
28
|
+
|
29
|
+
it "returns the value" do
|
30
|
+
expect(subject).to eq("bar" => "baz")
|
31
|
+
end
|
32
|
+
|
33
|
+
end # context
|
34
|
+
|
35
|
+
context "when a value is not a hash" do
|
36
|
+
|
37
|
+
subject { source.sub :bar }
|
38
|
+
|
39
|
+
it "returns the {}" do
|
40
|
+
expect(subject).to eq({})
|
41
|
+
end
|
42
|
+
|
43
|
+
end # context
|
44
|
+
|
45
|
+
context "when a key is absent" do
|
46
|
+
|
47
|
+
subject { source.sub :baz }
|
48
|
+
|
49
|
+
it "returns the {}" do
|
50
|
+
expect(subject).to eq({})
|
51
|
+
end
|
52
|
+
|
53
|
+
end # context
|
54
|
+
|
55
|
+
end # describe #sub
|
56
|
+
|
57
|
+
describe "#wrap" do
|
58
|
+
|
59
|
+
let(:source) { { foo: %w(a b c), bar: %w(c d) } }
|
60
|
+
|
61
|
+
context "with a block" do
|
62
|
+
|
63
|
+
subject { source.wrap(&:count) }
|
64
|
+
let(:target) { { foo: 3, bar: 2 } }
|
65
|
+
|
66
|
+
it "sends values to the block" do
|
67
|
+
expect(subject).to eq target
|
68
|
+
end
|
69
|
+
|
70
|
+
end # context
|
71
|
+
|
72
|
+
context "without a block" do
|
73
|
+
|
74
|
+
subject { source.wrap }
|
75
|
+
|
76
|
+
it "returns a copy of its own" do
|
77
|
+
expect(subject).to eq source
|
78
|
+
expect { subject.freeze }.not_to change { source }
|
79
|
+
end
|
80
|
+
|
81
|
+
end # context
|
82
|
+
|
83
|
+
end # describe #wrap
|
84
|
+
|
85
|
+
end # describe Hash
|
86
|
+
|
87
|
+
describe "for Array" do
|
88
|
+
|
89
|
+
describe "#to_path" do
|
90
|
+
|
91
|
+
let(:source) { ["foo", nil, "/bar/", "baz"] }
|
92
|
+
let(:target) { "foo/bar/baz" }
|
93
|
+
|
94
|
+
it "converts array to filepath" do
|
95
|
+
expect(source.to_path).to eq target
|
96
|
+
end
|
97
|
+
|
98
|
+
it "converts empty array to empty string" do
|
99
|
+
expect([].to_path).to eq ""
|
100
|
+
end
|
101
|
+
|
102
|
+
end # describe #to_path
|
103
|
+
|
104
|
+
end # describe Array
|
105
|
+
|
106
|
+
describe "for String" do
|
107
|
+
|
108
|
+
describe "#from_yaml" do
|
109
|
+
|
110
|
+
context "when the string contains valid yml" do
|
111
|
+
|
112
|
+
let(:source) { "---\nfoo:\n bar: :baz\n" }
|
113
|
+
let(:target) { { "foo" => { "bar" => :baz } } }
|
114
|
+
|
115
|
+
subject { source.from_yaml }
|
116
|
+
|
117
|
+
it "converts it to hash" do
|
118
|
+
expect(subject).to eq target
|
119
|
+
end
|
120
|
+
|
121
|
+
end # context
|
122
|
+
|
123
|
+
context "when the string contains invalid yml" do
|
124
|
+
|
125
|
+
subject { "wrong".from_yaml }
|
126
|
+
|
127
|
+
it "returns the {}" do
|
128
|
+
expect(subject).to eq({})
|
129
|
+
end
|
130
|
+
|
131
|
+
end # context
|
132
|
+
|
133
|
+
context "when the string is empty" do
|
134
|
+
|
135
|
+
subject { "".from_yaml }
|
136
|
+
|
137
|
+
it "returns the {}" do
|
138
|
+
expect(subject).to eq({})
|
139
|
+
end
|
140
|
+
|
141
|
+
end # context
|
142
|
+
|
143
|
+
end # describe #from_yaml
|
144
|
+
|
145
|
+
describe "#from_file" do
|
146
|
+
|
147
|
+
context "when the file exists" do
|
148
|
+
|
149
|
+
let(:file) { Tempfile.create "foo" }
|
150
|
+
let(:source) { file.path }
|
151
|
+
before { file.write "foobar" }
|
152
|
+
let(:target) { file.read }
|
153
|
+
|
154
|
+
subject { source.from_file }
|
155
|
+
|
156
|
+
it "returns its content" do
|
157
|
+
expect(subject).to eq target
|
158
|
+
end
|
159
|
+
|
160
|
+
end # context
|
161
|
+
|
162
|
+
context "when the file is absent" do
|
163
|
+
|
164
|
+
subject { "".from_file }
|
165
|
+
|
166
|
+
it "returns the empty string" do
|
167
|
+
expect(subject).to eq ""
|
168
|
+
end
|
169
|
+
|
170
|
+
end # context
|
171
|
+
|
172
|
+
end # describe #from_file
|
173
|
+
|
174
|
+
describe "#to_folder" do
|
175
|
+
|
176
|
+
context "when a folder exists" do
|
177
|
+
|
178
|
+
let(:source) { File.expand_path("..", __FILE__) }
|
179
|
+
subject { source.to_folder }
|
180
|
+
|
181
|
+
it "returns a copy of its own if the folder exist" do
|
182
|
+
expect(subject).to eq source
|
183
|
+
expect { subject.freeze }.not_to change { source }
|
184
|
+
end
|
185
|
+
|
186
|
+
end # context
|
187
|
+
|
188
|
+
context "when a folder is absent" do
|
189
|
+
|
190
|
+
subject { ",,".to_folder }
|
191
|
+
|
192
|
+
it "returns nil if the folder is absent" do
|
193
|
+
expect(subject).to be_nil
|
194
|
+
end
|
195
|
+
|
196
|
+
end # context
|
197
|
+
|
198
|
+
end # describe #to_folder
|
199
|
+
|
200
|
+
end # describe String
|
201
|
+
|
202
|
+
end # describe Hexx::Storage::Patches
|