masamune 0.14.0 → 0.15.0
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/README.md +10 -1
- data/Rakefile +37 -0
- data/bin/masamune-dump +22 -0
- data/bin/masamune-elastic-mapreduce +22 -0
- data/bin/masamune-hive +22 -0
- data/bin/masamune-psql +22 -0
- data/bin/masamune-shell +22 -0
- data/lib/masamune/cached_filesystem.rb +1 -1
- data/lib/masamune/commands/shell.rb +1 -1
- data/lib/masamune/configuration.rb +5 -7
- data/lib/masamune/data_plan/elem.rb +15 -7
- data/lib/masamune/data_plan/engine.rb +2 -0
- data/lib/masamune/data_plan/rule.rb +16 -5
- data/lib/masamune/data_plan/set.rb +8 -8
- data/lib/masamune/filesystem.rb +12 -6
- data/lib/masamune/schema/catalog.rb +6 -6
- data/lib/masamune/schema/column.rb +1 -1
- data/lib/masamune/schema/map.rb +6 -2
- data/lib/masamune/schema/store.rb +31 -3
- data/lib/masamune/tasks/shell_thor.rb +1 -1
- data/lib/masamune/thor.rb +12 -4
- data/lib/masamune/version.rb +1 -1
- data/lib/masamune.rb +0 -1
- data/spec/masamune/actions/elastic_mapreduce_spec.rb +0 -2
- data/spec/masamune/actions/execute_spec.rb +0 -2
- data/spec/masamune/actions/hadoop_filesystem_spec.rb +0 -2
- data/spec/masamune/actions/hadoop_streaming_spec.rb +0 -2
- data/spec/masamune/actions/hive_spec.rb +0 -2
- data/spec/masamune/actions/invoke_parallel_spec.rb +0 -2
- data/spec/masamune/actions/postgres_admin_spec.rb +0 -2
- data/spec/masamune/actions/postgres_spec.rb +0 -2
- data/spec/masamune/actions/s3cmd_spec.rb +0 -2
- data/spec/masamune/actions/transform_spec.rb +0 -2
- data/spec/masamune/after_initialization_callbacks_spec.rb +0 -2
- data/spec/masamune/cached_filesystem_spec.rb +0 -2
- data/spec/masamune/commands/hadoop_filesystem_spec.rb +0 -2
- data/spec/masamune/commands/hadoop_streaming_spec.rb +0 -2
- data/spec/masamune/commands/hive_spec.rb +0 -2
- data/spec/masamune/commands/postgres_admin_spec.rb +0 -2
- data/spec/masamune/commands/postgres_spec.rb +0 -2
- data/spec/masamune/commands/retry_with_backoff_spec.rb +0 -2
- data/spec/masamune/commands/s3cmd_spec.rb +0 -2
- data/spec/masamune/commands/shell_spec.rb +0 -2
- data/spec/masamune/configuration_spec.rb +12 -2
- data/spec/masamune/data_plan/builder_spec.rb +0 -2
- data/spec/masamune/data_plan/elem_spec.rb +73 -5
- data/spec/masamune/data_plan/engine_spec.rb +0 -2
- data/spec/masamune/data_plan/rule_spec.rb +51 -6
- data/spec/masamune/data_plan/set_spec.rb +2 -5
- data/spec/masamune/environment_spec.rb +0 -2
- data/spec/masamune/filesystem_spec.rb +33 -4
- data/spec/masamune/helpers/postgres_spec.rb +0 -2
- data/spec/masamune/rspec/job_fixture_spec.rb +365 -0
- data/spec/masamune/rspec/shared_example_group_spec.rb +73 -0
- data/spec/masamune/schema/catalog_spec.rb +14 -2
- data/spec/masamune/schema/column_spec.rb +0 -2
- data/spec/masamune/schema/dimension_spec.rb +0 -2
- data/spec/masamune/schema/fact_spec.rb +0 -2
- data/spec/masamune/schema/map_spec.rb +51 -2
- data/spec/masamune/schema/row_spec.rb +0 -2
- data/spec/masamune/schema/store_spec.rb +23 -2
- data/spec/masamune/schema/table_spec.rb +0 -2
- data/spec/masamune/string_format_spec.rb +0 -2
- data/spec/masamune/tasks/dump_thor_spec.rb +0 -3
- data/spec/masamune/tasks/elastic_mapreduce_thor_spec.rb +0 -3
- data/spec/masamune/tasks/hive_thor_spec.rb +0 -3
- data/spec/masamune/tasks/postgres_thor_spec.rb +0 -3
- data/spec/masamune/tasks/shell_thor_spec.rb +0 -3
- data/spec/masamune/template_spec.rb +0 -2
- data/spec/masamune/thor_spec.rb +53 -8
- data/spec/masamune/transform/bulk_upsert.dimension_spec.rb +0 -2
- data/spec/masamune/transform/consolidate_dimension_spec.rb +0 -2
- data/spec/masamune/transform/deduplicate_dimension_spec.rb +0 -2
- data/spec/masamune/transform/define_schema_spec.rb +0 -2
- data/spec/masamune/transform/define_table.dimension_spec.rb +0 -2
- data/spec/masamune/transform/define_table.fact_spec.rb +0 -2
- data/spec/masamune/transform/define_table.table_spec.rb +0 -2
- data/spec/masamune/transform/denormalize_table_spec.rb +0 -2
- data/spec/masamune/transform/insert_reference_values.dimension_spec.rb +0 -2
- data/spec/masamune/transform/insert_reference_values.fact_spec.rb +0 -2
- data/spec/masamune/transform/load_dimension_spec.rb +0 -2
- data/spec/masamune/transform/load_fact_spec.rb +0 -2
- data/spec/masamune/transform/relabel_dimension_spec.rb +0 -2
- data/spec/masamune/transform/rollup_fact_spec.rb +0 -2
- data/spec/masamune/transform/snapshot_dimension_spec.rb +0 -2
- data/spec/masamune/transform/stage_dimension_spec.rb +0 -2
- data/spec/masamune/transform/stage_fact_spec.rb +0 -2
- data/spec/masamune_spec.rb +0 -2
- data/spec/spec_helper.rb +2 -0
- data/spec/support/masamune/job_example_group.rb +62 -0
- data/spec/support/masamune/job_fixture.rb +137 -0
- data/spec/support/masamune/shared_example_group.rb +203 -0
- data/spec/support/masamune/step_example_group.rb +68 -0
- data/spec/support/masamune/step_fixture.rb +91 -0
- data/{lib/masamune/thor_loader.rb → spec/support/masamune/task_example_group.rb} +33 -10
- data/spec/support/rspec/example/action_example_group.rb +1 -1
- metadata +32 -3
@@ -0,0 +1,365 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
#
|
3
|
+
# Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
describe Masamune::JobFixture do
|
24
|
+
let!(:tmp_dir) { File.join(Dir.tmpdir, SecureRandom.hex) }
|
25
|
+
let(:fixture_path) { File.join(tmp_dir, 'example', 'spec') }
|
26
|
+
|
27
|
+
describe '.file_name' do
|
28
|
+
subject { described_class.file_name(options) }
|
29
|
+
context 'with file' do
|
30
|
+
let(:options) { { file: File.join(fixture_path, 'job_fixture.yml') } }
|
31
|
+
it { is_expected.to eq(File.join(fixture_path, 'job_fixture.yml')) }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with path' do
|
35
|
+
let(:options) { { path: fixture_path } }
|
36
|
+
it { is_expected.to eq(File.join(fixture_path, 'job_fixture.yml')) }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with path and type' do
|
40
|
+
let(:options) { { path: fixture_path, type: 'task' } }
|
41
|
+
it { is_expected.to eq(File.join(fixture_path, 'task_fixture.yml')) }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with path and name' do
|
45
|
+
let(:options) { { path: fixture_path, name: 'basic' } }
|
46
|
+
it { is_expected.to eq(File.join(fixture_path, 'basic.job_fixture.yml')) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#save' do
|
51
|
+
let(:instance) { described_class.new(path: fixture_path, data: data) }
|
52
|
+
let(:data) do
|
53
|
+
{
|
54
|
+
'inputs' => [
|
55
|
+
{
|
56
|
+
'file' => 'input_file',
|
57
|
+
'data' => 'input_data'
|
58
|
+
},
|
59
|
+
{
|
60
|
+
'file' => 'another_input_file',
|
61
|
+
'data' => <<-EOS.strip_heredoc
|
62
|
+
more_data
|
63
|
+
more_data
|
64
|
+
EOS
|
65
|
+
},
|
66
|
+
{
|
67
|
+
'reference' => {
|
68
|
+
'fixture' => 'other',
|
69
|
+
'section' => 'output'
|
70
|
+
}
|
71
|
+
}
|
72
|
+
],
|
73
|
+
'outputs' => [
|
74
|
+
{
|
75
|
+
'file' => 'output_file',
|
76
|
+
'data' => 'output_data'
|
77
|
+
},
|
78
|
+
{
|
79
|
+
'file' => 'another_output_file',
|
80
|
+
'data' => <<-EOS.strip_heredoc
|
81
|
+
more_data
|
82
|
+
more_data
|
83
|
+
EOS
|
84
|
+
}
|
85
|
+
]
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
before do
|
90
|
+
instance.save
|
91
|
+
end
|
92
|
+
|
93
|
+
subject { File.read(instance.file_name) }
|
94
|
+
|
95
|
+
it 'saves pretty fixture' do
|
96
|
+
is_expected.to eq <<-EOS.strip_heredoc
|
97
|
+
---
|
98
|
+
inputs:
|
99
|
+
-
|
100
|
+
file: input_file
|
101
|
+
data: input_data
|
102
|
+
-
|
103
|
+
file: another_input_file
|
104
|
+
data: |
|
105
|
+
more_data
|
106
|
+
more_data
|
107
|
+
-
|
108
|
+
reference:
|
109
|
+
fixture: other
|
110
|
+
section: output
|
111
|
+
|
112
|
+
outputs:
|
113
|
+
-
|
114
|
+
file: output_file
|
115
|
+
data: output_data
|
116
|
+
-
|
117
|
+
file: another_output_file
|
118
|
+
data: |
|
119
|
+
more_data
|
120
|
+
more_data
|
121
|
+
EOS
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '.load' do
|
126
|
+
let(:basic_data) do
|
127
|
+
{
|
128
|
+
'inputs' => [
|
129
|
+
{
|
130
|
+
'file' => 'basic_input_file',
|
131
|
+
'data' => 'basic_input_data'
|
132
|
+
}
|
133
|
+
],
|
134
|
+
'outputs' => [
|
135
|
+
{
|
136
|
+
'file' => 'basic_output_file',
|
137
|
+
'data' => 'basic_output_data'
|
138
|
+
}
|
139
|
+
]
|
140
|
+
}
|
141
|
+
end
|
142
|
+
|
143
|
+
let(:other_data) { {} }
|
144
|
+
|
145
|
+
before do
|
146
|
+
described_class.new(path: fixture_path, name: 'basic', data: basic_data).save
|
147
|
+
described_class.new(path: fixture_path, name: 'other', data: other_data).save
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'with basic fixture from path' do
|
151
|
+
subject(:instance) { described_class.load(path: fixture_path, name: 'basic') }
|
152
|
+
|
153
|
+
it 'loads basic fixture' do
|
154
|
+
expect(instance.inputs).to eq(basic_data['inputs'])
|
155
|
+
expect(instance.outputs).to eq(basic_data['outputs'])
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'with basic fixture from file' do
|
160
|
+
subject(:instance) { described_class.load(file: File.join(fixture_path, 'basic.job_fixture.yml')) }
|
161
|
+
|
162
|
+
it 'loads basic fixture' do
|
163
|
+
expect(instance.inputs).to eq(basic_data['inputs'])
|
164
|
+
expect(instance.outputs).to eq(basic_data['outputs'])
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'with basic fixture from path that does not exist' do
|
169
|
+
subject(:instance) { described_class.load(path: fixture_path, name: 'unknown') }
|
170
|
+
|
171
|
+
it { expect { instance }.to raise_error(ArgumentError) }
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'with basic fixture from file that does not exist' do
|
175
|
+
subject(:instance) { described_class.load(file: File.join(fixture_path, 'unknown.job_fixture.yml')) }
|
176
|
+
|
177
|
+
it { expect { instance }.to raise_error(ArgumentError) }
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'with reference fixture' do
|
181
|
+
let(:other_data) do
|
182
|
+
{
|
183
|
+
'inputs' => [
|
184
|
+
{
|
185
|
+
'file' => 'other_input_file',
|
186
|
+
'data' => 'other_input_data'
|
187
|
+
},
|
188
|
+
{
|
189
|
+
'reference' => {
|
190
|
+
'fixture' => 'basic'
|
191
|
+
}
|
192
|
+
}
|
193
|
+
],
|
194
|
+
'outputs' => [
|
195
|
+
{
|
196
|
+
'file' => 'other_output_file',
|
197
|
+
'data' => 'other_output_data'
|
198
|
+
}
|
199
|
+
]
|
200
|
+
}
|
201
|
+
end
|
202
|
+
|
203
|
+
subject(:instance) { described_class.load(path: fixture_path, name: 'other') }
|
204
|
+
|
205
|
+
it 'loads referenced fixture' do
|
206
|
+
expect(instance.inputs).to include(other_data['inputs'].first)
|
207
|
+
expect(instance.inputs).to include(basic_data['outputs'].first)
|
208
|
+
expect(instance.outputs).to eq(other_data['outputs'])
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'with reference fixture and path' do
|
213
|
+
let(:other_data) do
|
214
|
+
{
|
215
|
+
'inputs' => [
|
216
|
+
{
|
217
|
+
'file' => 'other_input_file',
|
218
|
+
'data' => 'other_input_data'
|
219
|
+
},
|
220
|
+
{
|
221
|
+
'reference' => {
|
222
|
+
'path' => fixture_path,
|
223
|
+
'fixture' => 'basic'
|
224
|
+
}
|
225
|
+
}
|
226
|
+
],
|
227
|
+
'outputs' => [
|
228
|
+
{
|
229
|
+
'file' => 'other_output_file',
|
230
|
+
'data' => 'other_output_data'
|
231
|
+
}
|
232
|
+
]
|
233
|
+
}
|
234
|
+
end
|
235
|
+
|
236
|
+
subject(:instance) { described_class.load(path: fixture_path, name: 'other') }
|
237
|
+
|
238
|
+
it 'loads referenced fixture' do
|
239
|
+
expect(instance.inputs).to include(other_data['inputs'].first)
|
240
|
+
expect(instance.inputs).to include(basic_data['outputs'].first)
|
241
|
+
expect(instance.outputs).to eq(other_data['outputs'])
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context 'with reference fixture from file' do
|
246
|
+
let(:other_data) do
|
247
|
+
{
|
248
|
+
'inputs' => [
|
249
|
+
{
|
250
|
+
'file' => 'other_input_file',
|
251
|
+
'data' => 'other_input_data'
|
252
|
+
},
|
253
|
+
{
|
254
|
+
'reference' => {
|
255
|
+
'file' => File.join(fixture_path, 'basic.job_fixture.yml')
|
256
|
+
}
|
257
|
+
}
|
258
|
+
],
|
259
|
+
'outputs' => [
|
260
|
+
{
|
261
|
+
'file' => 'other_output_file',
|
262
|
+
'data' => 'other_output_data'
|
263
|
+
}
|
264
|
+
]
|
265
|
+
}
|
266
|
+
end
|
267
|
+
|
268
|
+
subject(:instance) { described_class.load(path: fixture_path, name: 'other') }
|
269
|
+
|
270
|
+
it 'loads referenced fixture' do
|
271
|
+
expect(instance.inputs).to include(other_data['inputs'].first)
|
272
|
+
expect(instance.inputs).to include(basic_data['outputs'].first)
|
273
|
+
expect(instance.outputs).to eq(other_data['outputs'])
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
context 'with reference fixture and section' do
|
279
|
+
let(:other_data) do
|
280
|
+
{
|
281
|
+
'inputs' => [
|
282
|
+
{
|
283
|
+
'file' => 'other_input_file',
|
284
|
+
'data' => 'other_input_data'
|
285
|
+
},
|
286
|
+
{
|
287
|
+
'reference' => {
|
288
|
+
'fixture' => 'basic',
|
289
|
+
'section' => 'inputs'
|
290
|
+
}
|
291
|
+
}
|
292
|
+
],
|
293
|
+
'outputs' => [
|
294
|
+
{
|
295
|
+
'file' => 'other_output_file',
|
296
|
+
'data' => 'other_output_data'
|
297
|
+
}
|
298
|
+
]
|
299
|
+
}
|
300
|
+
end
|
301
|
+
|
302
|
+
subject(:instance) { described_class.load(path: fixture_path, name: 'other') }
|
303
|
+
|
304
|
+
it 'loads referenced fixture' do
|
305
|
+
expect(instance.inputs).to include(other_data['inputs'].first)
|
306
|
+
expect(instance.inputs).to include(basic_data['inputs'].first)
|
307
|
+
expect(instance.outputs).to eq(other_data['outputs'])
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'with reference fixture that does not exist' do
|
312
|
+
let(:other_data) do
|
313
|
+
{
|
314
|
+
'inputs' => [
|
315
|
+
{
|
316
|
+
'file' => 'other_input_file',
|
317
|
+
'data' => 'other_input_data'
|
318
|
+
},
|
319
|
+
{
|
320
|
+
'reference' => {
|
321
|
+
'fixture' => 'unknown'
|
322
|
+
}
|
323
|
+
}
|
324
|
+
],
|
325
|
+
'outputs' => [
|
326
|
+
{
|
327
|
+
'file' => 'other_output_file',
|
328
|
+
'data' => 'other_output_data'
|
329
|
+
}
|
330
|
+
]
|
331
|
+
}
|
332
|
+
end
|
333
|
+
|
334
|
+
subject(:instance) { described_class.load(path: fixture_path, name: 'other') }
|
335
|
+
|
336
|
+
it { expect { instance.inputs }.to raise_error(ArgumentError) }
|
337
|
+
end
|
338
|
+
|
339
|
+
context 'with invalid reference fixture' do
|
340
|
+
let(:other_data) do
|
341
|
+
{
|
342
|
+
'inputs' => [
|
343
|
+
{
|
344
|
+
'file' => 'other_input_file',
|
345
|
+
'data' => 'other_input_data'
|
346
|
+
},
|
347
|
+
{
|
348
|
+
'reference' => 'unknown'
|
349
|
+
}
|
350
|
+
],
|
351
|
+
'outputs' => [
|
352
|
+
{
|
353
|
+
'file' => 'other_output_file',
|
354
|
+
'data' => 'other_output_data'
|
355
|
+
}
|
356
|
+
]
|
357
|
+
}
|
358
|
+
end
|
359
|
+
|
360
|
+
subject(:instance) { described_class.load(path: fixture_path, name: 'other') }
|
361
|
+
|
362
|
+
it { expect { instance.inputs }.to raise_error(ArgumentError) }
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
#
|
3
|
+
# Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
describe Masamune::SharedExampleGroup do
|
24
|
+
it { is_expected.to be_a(Module) }
|
25
|
+
|
26
|
+
let(:klass) { Class.new.send(:include, described_class) }
|
27
|
+
|
28
|
+
describe '.example_fixture_file' do
|
29
|
+
before do
|
30
|
+
allow(klass).to receive(:file_path).and_return(file_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
subject { klass.example_fixture_file(options) }
|
34
|
+
|
35
|
+
context 'with file_path like task_spec.rb' do
|
36
|
+
let(:file_path) { './examples/apache_log/spec/task_spec.rb' }
|
37
|
+
|
38
|
+
context 'with options empty' do
|
39
|
+
let(:options) { {} }
|
40
|
+
it { is_expected.to eq('./examples/apache_log/spec/task_fixture.yml') }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'with options fixture:' do
|
44
|
+
let(:options) { { fixture: 'fixture_name' } }
|
45
|
+
it { is_expected.to eq('./examples/apache_log/spec/fixture_name.task_fixture.yml') }
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with options file:' do
|
49
|
+
let(:options) { { file: './examples/apache_log/spec/task_fixture.yml' } }
|
50
|
+
it { is_expected.to eq('./examples/apache_log/spec/task_fixture.yml') }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'with file_path like mapper_spec.rb' do
|
55
|
+
let(:file_path) { './examples/apache_log/spec/mapper_spec.rb' }
|
56
|
+
|
57
|
+
context 'with options empty' do
|
58
|
+
let(:options) { {} }
|
59
|
+
it { is_expected.to eq('./examples/apache_log/spec/mapper_fixture.yml') }
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with options fixture:' do
|
63
|
+
let(:options) { { fixture: 'fixture_name' } }
|
64
|
+
it { is_expected.to eq('./examples/apache_log/spec/fixture_name.mapper_fixture.yml') }
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with options file:' do
|
68
|
+
let(:options) { { file: './examples/apache_log/spec/mapper_fixture.yml' } }
|
69
|
+
it { is_expected.to eq('./examples/apache_log/spec/mapper_fixture.yml') }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -20,8 +20,6 @@
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
# THE SOFTWARE.
|
22
22
|
|
23
|
-
require 'spec_helper'
|
24
|
-
|
25
23
|
describe Masamune::Schema::Catalog do
|
26
24
|
let(:environment) { double }
|
27
25
|
let(:instance) { described_class.new(environment) }
|
@@ -145,6 +143,20 @@ describe Masamune::Schema::Catalog do
|
|
145
143
|
it { expect(table_two_columns).to include :column_four }
|
146
144
|
end
|
147
145
|
|
146
|
+
context 'when schema contains columns with symbol names' do
|
147
|
+
before do
|
148
|
+
instance.schema :postgres do
|
149
|
+
dimension :table_one, type: :two do
|
150
|
+
column :column_one
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
let(:table_one_columns) { postgres.table_one_dimension.columns }
|
156
|
+
|
157
|
+
it { expect(table_one_columns).to include :column_one }
|
158
|
+
end
|
159
|
+
|
148
160
|
context 'when schema contains columns and rows' do
|
149
161
|
before do
|
150
162
|
instance.schema :postgres do
|
@@ -20,8 +20,6 @@
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
# THE SOFTWARE.
|
22
22
|
|
23
|
-
require 'spec_helper'
|
24
|
-
|
25
23
|
describe Masamune::Schema::Map do
|
26
24
|
let(:environment) { double(logger: double) }
|
27
25
|
let(:catalog) { Masamune::Schema::Catalog.new(environment) }
|
@@ -547,6 +545,57 @@ describe Masamune::Schema::Map do
|
|
547
545
|
|
548
546
|
it_behaves_like 'apply input/output'
|
549
547
|
end
|
548
|
+
|
549
|
+
context 'with nested json and indifferent access' do
|
550
|
+
before do
|
551
|
+
catalog.schema :files do
|
552
|
+
file 'input' do
|
553
|
+
column 'data', type: :json
|
554
|
+
end
|
555
|
+
|
556
|
+
file 'output' do
|
557
|
+
column 'id', type: :integer
|
558
|
+
end
|
559
|
+
|
560
|
+
map from: files.input, to: files.output do |row|
|
561
|
+
[
|
562
|
+
{ 'id' => row[:data][:user][:id] },
|
563
|
+
{ 'id' => row['data']['user']['id'] }
|
564
|
+
]
|
565
|
+
end
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
let(:source) do
|
570
|
+
catalog.files.input
|
571
|
+
end
|
572
|
+
|
573
|
+
let(:target) do
|
574
|
+
catalog.files.output
|
575
|
+
end
|
576
|
+
|
577
|
+
let(:source_data) do
|
578
|
+
<<-EOS.strip_heredoc
|
579
|
+
{"user":{"id":1}}
|
580
|
+
{"user":{"id":2}}
|
581
|
+
EOS
|
582
|
+
end
|
583
|
+
|
584
|
+
let(:target_data) do
|
585
|
+
<<-EOS.strip_heredoc
|
586
|
+
1
|
587
|
+
1
|
588
|
+
2
|
589
|
+
2
|
590
|
+
EOS
|
591
|
+
end
|
592
|
+
|
593
|
+
it 'should match target data' do
|
594
|
+
is_expected.to eq(target_data)
|
595
|
+
end
|
596
|
+
|
597
|
+
it_behaves_like 'apply input/output'
|
598
|
+
end
|
550
599
|
end
|
551
600
|
|
552
601
|
describe Masamune::Schema::Map::JSONEncoder do
|
@@ -20,8 +20,6 @@
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
# THE SOFTWARE.
|
22
22
|
|
23
|
-
require 'spec_helper'
|
24
|
-
|
25
23
|
describe Masamune::Schema::Store do
|
26
24
|
let(:environment) { double }
|
27
25
|
|
@@ -39,11 +37,34 @@ describe Masamune::Schema::Store do
|
|
39
37
|
subject(:store) { described_class.new(environment, type: :postgres) }
|
40
38
|
it { expect(store.format).to eq(:csv) }
|
41
39
|
it { expect(store.headers).to be_truthy }
|
40
|
+
it { expect(store.json_encoding).to eq(:quoted) }
|
41
|
+
|
42
|
+
context 'with format override' do
|
43
|
+
subject(:store) { described_class.new(environment, type: :postgres, format: :raw) }
|
44
|
+
it { expect(store.format).to eq(:raw) }
|
45
|
+
it { expect(store.headers).to be_falsey }
|
46
|
+
it { expect(store.json_encoding).to eq(:raw) }
|
47
|
+
end
|
42
48
|
end
|
43
49
|
|
44
50
|
context 'with type :hive' do
|
45
51
|
subject(:store) { described_class.new(environment, type: :hive) }
|
46
52
|
it { expect(store.format).to eq(:tsv) }
|
47
53
|
it { expect(store.headers).to be_falsey }
|
54
|
+
it { expect(store.json_encoding).to eq(:raw) }
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'with type :files' do
|
58
|
+
subject(:store) { described_class.new(environment, type: :files) }
|
59
|
+
it { expect(store.format).to eq(:raw) }
|
60
|
+
it { expect(store.headers).to be_falsey }
|
61
|
+
it { expect(store.json_encoding).to eq(:raw) }
|
62
|
+
|
63
|
+
context 'with format overrides' do
|
64
|
+
subject(:store) { described_class.new(environment, type: :files, format: :csv, headers: true, json_encoding: :quoted) }
|
65
|
+
it { expect(store.format).to eq(:csv) }
|
66
|
+
it { expect(store.headers).to be_truthy }
|
67
|
+
it { expect(store.json_encoding).to eq(:quoted) }
|
68
|
+
end
|
48
69
|
end
|
49
70
|
end
|