masamune 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -1
  3. data/Rakefile +37 -0
  4. data/bin/masamune-dump +22 -0
  5. data/bin/masamune-elastic-mapreduce +22 -0
  6. data/bin/masamune-hive +22 -0
  7. data/bin/masamune-psql +22 -0
  8. data/bin/masamune-shell +22 -0
  9. data/lib/masamune/cached_filesystem.rb +1 -1
  10. data/lib/masamune/commands/shell.rb +1 -1
  11. data/lib/masamune/configuration.rb +5 -7
  12. data/lib/masamune/data_plan/elem.rb +15 -7
  13. data/lib/masamune/data_plan/engine.rb +2 -0
  14. data/lib/masamune/data_plan/rule.rb +16 -5
  15. data/lib/masamune/data_plan/set.rb +8 -8
  16. data/lib/masamune/filesystem.rb +12 -6
  17. data/lib/masamune/schema/catalog.rb +6 -6
  18. data/lib/masamune/schema/column.rb +1 -1
  19. data/lib/masamune/schema/map.rb +6 -2
  20. data/lib/masamune/schema/store.rb +31 -3
  21. data/lib/masamune/tasks/shell_thor.rb +1 -1
  22. data/lib/masamune/thor.rb +12 -4
  23. data/lib/masamune/version.rb +1 -1
  24. data/lib/masamune.rb +0 -1
  25. data/spec/masamune/actions/elastic_mapreduce_spec.rb +0 -2
  26. data/spec/masamune/actions/execute_spec.rb +0 -2
  27. data/spec/masamune/actions/hadoop_filesystem_spec.rb +0 -2
  28. data/spec/masamune/actions/hadoop_streaming_spec.rb +0 -2
  29. data/spec/masamune/actions/hive_spec.rb +0 -2
  30. data/spec/masamune/actions/invoke_parallel_spec.rb +0 -2
  31. data/spec/masamune/actions/postgres_admin_spec.rb +0 -2
  32. data/spec/masamune/actions/postgres_spec.rb +0 -2
  33. data/spec/masamune/actions/s3cmd_spec.rb +0 -2
  34. data/spec/masamune/actions/transform_spec.rb +0 -2
  35. data/spec/masamune/after_initialization_callbacks_spec.rb +0 -2
  36. data/spec/masamune/cached_filesystem_spec.rb +0 -2
  37. data/spec/masamune/commands/hadoop_filesystem_spec.rb +0 -2
  38. data/spec/masamune/commands/hadoop_streaming_spec.rb +0 -2
  39. data/spec/masamune/commands/hive_spec.rb +0 -2
  40. data/spec/masamune/commands/postgres_admin_spec.rb +0 -2
  41. data/spec/masamune/commands/postgres_spec.rb +0 -2
  42. data/spec/masamune/commands/retry_with_backoff_spec.rb +0 -2
  43. data/spec/masamune/commands/s3cmd_spec.rb +0 -2
  44. data/spec/masamune/commands/shell_spec.rb +0 -2
  45. data/spec/masamune/configuration_spec.rb +12 -2
  46. data/spec/masamune/data_plan/builder_spec.rb +0 -2
  47. data/spec/masamune/data_plan/elem_spec.rb +73 -5
  48. data/spec/masamune/data_plan/engine_spec.rb +0 -2
  49. data/spec/masamune/data_plan/rule_spec.rb +51 -6
  50. data/spec/masamune/data_plan/set_spec.rb +2 -5
  51. data/spec/masamune/environment_spec.rb +0 -2
  52. data/spec/masamune/filesystem_spec.rb +33 -4
  53. data/spec/masamune/helpers/postgres_spec.rb +0 -2
  54. data/spec/masamune/rspec/job_fixture_spec.rb +365 -0
  55. data/spec/masamune/rspec/shared_example_group_spec.rb +73 -0
  56. data/spec/masamune/schema/catalog_spec.rb +14 -2
  57. data/spec/masamune/schema/column_spec.rb +0 -2
  58. data/spec/masamune/schema/dimension_spec.rb +0 -2
  59. data/spec/masamune/schema/fact_spec.rb +0 -2
  60. data/spec/masamune/schema/map_spec.rb +51 -2
  61. data/spec/masamune/schema/row_spec.rb +0 -2
  62. data/spec/masamune/schema/store_spec.rb +23 -2
  63. data/spec/masamune/schema/table_spec.rb +0 -2
  64. data/spec/masamune/string_format_spec.rb +0 -2
  65. data/spec/masamune/tasks/dump_thor_spec.rb +0 -3
  66. data/spec/masamune/tasks/elastic_mapreduce_thor_spec.rb +0 -3
  67. data/spec/masamune/tasks/hive_thor_spec.rb +0 -3
  68. data/spec/masamune/tasks/postgres_thor_spec.rb +0 -3
  69. data/spec/masamune/tasks/shell_thor_spec.rb +0 -3
  70. data/spec/masamune/template_spec.rb +0 -2
  71. data/spec/masamune/thor_spec.rb +53 -8
  72. data/spec/masamune/transform/bulk_upsert.dimension_spec.rb +0 -2
  73. data/spec/masamune/transform/consolidate_dimension_spec.rb +0 -2
  74. data/spec/masamune/transform/deduplicate_dimension_spec.rb +0 -2
  75. data/spec/masamune/transform/define_schema_spec.rb +0 -2
  76. data/spec/masamune/transform/define_table.dimension_spec.rb +0 -2
  77. data/spec/masamune/transform/define_table.fact_spec.rb +0 -2
  78. data/spec/masamune/transform/define_table.table_spec.rb +0 -2
  79. data/spec/masamune/transform/denormalize_table_spec.rb +0 -2
  80. data/spec/masamune/transform/insert_reference_values.dimension_spec.rb +0 -2
  81. data/spec/masamune/transform/insert_reference_values.fact_spec.rb +0 -2
  82. data/spec/masamune/transform/load_dimension_spec.rb +0 -2
  83. data/spec/masamune/transform/load_fact_spec.rb +0 -2
  84. data/spec/masamune/transform/relabel_dimension_spec.rb +0 -2
  85. data/spec/masamune/transform/rollup_fact_spec.rb +0 -2
  86. data/spec/masamune/transform/snapshot_dimension_spec.rb +0 -2
  87. data/spec/masamune/transform/stage_dimension_spec.rb +0 -2
  88. data/spec/masamune/transform/stage_fact_spec.rb +0 -2
  89. data/spec/masamune_spec.rb +0 -2
  90. data/spec/spec_helper.rb +2 -0
  91. data/spec/support/masamune/job_example_group.rb +62 -0
  92. data/spec/support/masamune/job_fixture.rb +137 -0
  93. data/spec/support/masamune/shared_example_group.rb +203 -0
  94. data/spec/support/masamune/step_example_group.rb +68 -0
  95. data/spec/support/masamune/step_fixture.rb +91 -0
  96. data/{lib/masamune/thor_loader.rb → spec/support/masamune/task_example_group.rb} +33 -10
  97. data/spec/support/rspec/example/action_example_group.rb +1 -1
  98. 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::Column do
26
24
  describe '.initialize' do
27
25
  subject(:column) { described_class.new(id: 'id') }
@@ -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::Dimension do
26
24
  let(:store) { double }
27
25
 
@@ -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::Fact do
26
24
  let(:store) { double(id: 'store', type: :postgres) }
27
25
 
@@ -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::Row do
26
24
  subject(:row) { described_class.new }
27
25
  it { expect(row).to_not be_nil }
@@ -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
@@ -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::Table do
26
24
  context 'without id' do
27
25
  subject(:table) { described_class.new }
@@ -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::StringFormat do
26
24
  let(:instance) { Object.new.extend(described_class) }
27
25
 
@@ -20,9 +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
- require 'thor'
25
-
26
23
  require 'masamune/tasks/dump_thor'
27
24
 
28
25
  describe Masamune::Tasks::DumpThor do
@@ -20,9 +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
- require 'thor'
25
-
26
23
  require 'masamune/tasks/elastic_mapreduce_thor'
27
24
 
28
25
  describe Masamune::Tasks::ElasticMapreduceThor do
@@ -20,9 +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
- require 'thor'
25
-
26
23
  require 'masamune/tasks/hive_thor'
27
24
 
28
25
  describe Masamune::Tasks::HiveThor do
@@ -20,9 +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
- require 'thor'
25
-
26
23
  require 'masamune/tasks/postgres_thor'
27
24
 
28
25
  describe Masamune::Tasks::PostgresThor do
@@ -20,9 +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
- require 'thor'
25
-
26
23
  require 'masamune/tasks/shell_thor'
27
24
 
28
25
  describe Masamune::Tasks::ShellThor do