embulk-input-jira 0.2.5 → 0.2.6

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -5
  3. data/.travis.yml +4 -34
  4. data/CHANGELOG.md +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +5 -4
  7. data/build.gradle +116 -0
  8. data/config/checkstyle/checkstyle.xml +128 -0
  9. data/config/checkstyle/default.xml +108 -0
  10. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  11. data/gradle/wrapper/gradle-wrapper.properties +5 -0
  12. data/gradlew +172 -0
  13. data/gradlew.bat +84 -0
  14. data/lib/embulk/guess/jira.rb +24 -0
  15. data/lib/embulk/input/jira.rb +3 -169
  16. data/src/main/java/org/embulk/input/jira/AuthenticateMethod.java +27 -0
  17. data/src/main/java/org/embulk/input/jira/Constant.java +17 -0
  18. data/src/main/java/org/embulk/input/jira/Issue.java +150 -0
  19. data/src/main/java/org/embulk/input/jira/JiraInputPlugin.java +226 -0
  20. data/src/main/java/org/embulk/input/jira/client/JiraClient.java +254 -0
  21. data/src/main/java/org/embulk/input/jira/util/JiraException.java +18 -0
  22. data/src/main/java/org/embulk/input/jira/util/JiraUtil.java +264 -0
  23. data/src/test/java/org/embulk/input/jira/IssueTest.java +278 -0
  24. data/src/test/java/org/embulk/input/jira/JiraInputPluginTest.java +204 -0
  25. data/src/test/java/org/embulk/input/jira/JiraPluginTestRuntime.java +133 -0
  26. data/src/test/java/org/embulk/input/jira/TestHelpers.java +41 -0
  27. data/src/test/java/org/embulk/input/jira/client/JiraClientTest.java +222 -0
  28. data/src/test/java/org/embulk/input/jira/util/JiraUtilTest.java +318 -0
  29. data/src/test/resources/config.yml +13 -0
  30. data/src/test/resources/issue_flatten.json +129 -0
  31. data/src/test/resources/issue_flatten_expected.json +73 -0
  32. data/src/test/resources/issue_get.json +36 -0
  33. data/src/test/resources/issue_get_expected.json +62 -0
  34. data/src/test/resources/jira_client.json +81 -0
  35. data/src/test/resources/jira_input_plugin.json +114 -0
  36. data/src/test/resources/jira_util.json +26 -0
  37. metadata +55 -175
  38. data/Gemfile +0 -3
  39. data/LICENSE +0 -13
  40. data/Rakefile +0 -15
  41. data/embulk-input-jira.gemspec +0 -27
  42. data/gemfiles/embulk-0.8.0-latest +0 -4
  43. data/gemfiles/embulk-0.8.7 +0 -4
  44. data/gemfiles/embulk-0.8.8 +0 -4
  45. data/gemfiles/embulk-latest +0 -4
  46. data/gemfiles/template.erb +0 -4
  47. data/lib/embulk/input/jira_api.rb +0 -9
  48. data/lib/embulk/input/jira_api/client.rb +0 -144
  49. data/lib/embulk/input/jira_api/issue.rb +0 -133
  50. data/lib/embulk/input/jira_input_plugin_utils.rb +0 -58
  51. data/spec/embulk/input/jira-input-plugin-utils_spec.rb +0 -89
  52. data/spec/embulk/input/jira_api/client_spec.rb +0 -224
  53. data/spec/embulk/input/jira_api/issue_spec.rb +0 -394
  54. data/spec/embulk/input/jira_spec.rb +0 -322
  55. data/spec/embulk_spec.rb +0 -32
  56. data/spec/spec_helper.rb +0 -26
  57. data/spec/support/stdout_and_err_capture.rb +0 -45
@@ -1,224 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Embulk::Input::JiraApi::Client do
4
- describe ".setup" do
5
- subject { Embulk::Input::JiraApi::Client.setup {} }
6
-
7
- it "returns Embulk::Input::JiraApi::Client instance" do
8
- expect(subject.is_a?(Embulk::Input::JiraApi::Client)).to be_truthy
9
- end
10
-
11
- it "calls Jiralicious.configure" do
12
- allow(Jiralicious).to receive(:configure)
13
- end
14
- end
15
-
16
- describe "#search" do
17
- let(:jql) { "project=FOO" }
18
- let(:api) { Embulk::Input::JiraApi::Client.new }
19
-
20
- subject { api.search(jql) }
21
-
22
- it do
23
- allow(Jiralicious).to receive(:search).with(jql)
24
- end
25
-
26
- describe "retry and timeout" do
27
- before do
28
- allow(Timeout).to receive(:timeout) { raise Timeout::Error }
29
- allow(api).to receive(:sleep)
30
- end
31
-
32
- it "retry DEFAULT_SEARCH_RETRY_TIMES times then raise error" do
33
- expect(Timeout).to receive(:timeout).exactly(Embulk::Input::JiraApi::Client::DEFAULT_SEARCH_RETRY_TIMES + 1)
34
- expect { subject }.to raise_error
35
- end
36
- end
37
- end
38
-
39
- describe "#search_issues" do
40
- let(:jql) { "project=FOO" }
41
- let(:jira_api) { Embulk::Input::JiraApi::Client.new }
42
- let(:title_401) { "Unauthorized (401)"}
43
- let(:multi_json_error) {MultiJson::ParseError.build(StandardError.new("<title>#{title_401}</title>"), {})}
44
- let(:results) do
45
- [
46
- {
47
- "id" => 1,
48
- "jira_key" => "FOO-1",
49
- "fields" =>
50
- {
51
- "summary" => "issue summary",
52
- "project" =>
53
- {
54
- "key" => "FO1"
55
- }
56
- }
57
- },
58
- {
59
- "id" => 2,
60
- "jira_key" => "FOO-2",
61
- "fields" =>
62
- {
63
- "summary" => "jira issue",
64
- "project" =>
65
- {
66
- "key" => "FO2"
67
- }
68
- }
69
- }
70
- ]
71
- end
72
-
73
- subject { jira_api.search_issues(jql) }
74
-
75
- it "Search issues successfully" do
76
- allow(Jiralicious).to receive_message_chain(:search, :issues_raw).and_return(results)
77
- allow(jira_api).to receive(:find_issue).and_return(results.first)
78
-
79
- expect(subject).to be_kind_of Array
80
- expect(subject.map(&:class)).to match_array [Embulk::Input::JiraApi::Issue, Embulk::Input::JiraApi::Issue]
81
- end
82
-
83
- it "Search issues successfully when first item success - 401 - second items success" do
84
- allow(Jiralicious).to receive_message_chain(:search, :issues_raw).and_return(results)
85
- allow(jira_api).to receive(:find_issue).and_return(results.first).and_raise(multi_json_error).and_return(results.first)
86
-
87
- expect(subject).to be_kind_of Array
88
- expect(subject.map(&:class)).to match_array [Embulk::Input::JiraApi::Issue, Embulk::Input::JiraApi::Issue]
89
- end
90
-
91
- it "Search issues successfully when 401 - first and second items success" do
92
- allow(Jiralicious).to receive_message_chain(:search, :issues_raw).and_return(results)
93
- allow(jira_api).to receive(:find_issue).and_raise(multi_json_error).and_return(results.first)
94
-
95
- expect(subject).to be_kind_of Array
96
- expect(subject.map(&:class)).to match_array [Embulk::Input::JiraApi::Issue, Embulk::Input::JiraApi::Issue]
97
- end
98
-
99
- it "Search issues got 401 due to high concurrent load issues" do
100
- allow(Jiralicious).to receive_message_chain(:search, :issues_raw).and_return(results)
101
- allow(jira_api).to receive(:find_issue).and_raise(multi_json_error)
102
- allow(jira_api).to receive(:sleep)
103
-
104
- expect { subject }.to raise_error(StandardError, title_401)
105
- end
106
- end
107
-
108
- describe "#total_count" do
109
- subject { jira_api.total_count(jql) }
110
-
111
- let(:jira_api) { Embulk::Input::JiraApi::Client.new }
112
- let(:jql) { "project=FOO" }
113
- let(:results) { Object.new } # add mock later
114
- let(:results_count) { 5 }
115
-
116
- before do
117
- allow(results).to receive(:num_results).and_return(results_count)
118
- end
119
-
120
- it "calls Embulk::Input::JiraApi::Client#search with proper arguments" do
121
- expect(jira_api).to receive(:search).with(jql, max_results: 1).and_return(results)
122
- subject
123
- end
124
-
125
- it "returns issues count" do
126
- allow(jira_api).to receive(:search).with(jql, max_results: 1).and_return(results)
127
- expect(subject).to eq results_count
128
- end
129
- end
130
-
131
- describe "#timeout_and_retry" do
132
- let(:wait) { 1 }
133
- let(:retry_times) { 3 }
134
- let(:jira_api) { Embulk::Input::JiraApi::Client.new }
135
- let(:block) { proc{ "it works" } }
136
-
137
- subject { jira_api.send(:timeout_and_retry, wait, retry_times, &block) }
138
-
139
- before do
140
- allow(jira_api).to receive(:sleep)
141
- end
142
-
143
- it "return given block result if timeout is not occured" do
144
- expect(subject).to eq block.call
145
- end
146
-
147
- it "Always timeout, raise error after N times retry" do
148
- allow(Timeout).to receive(:timeout) { raise Timeout::Error }
149
-
150
- expect(Timeout).to receive(:timeout).with(wait).exactly(retry_times + 1).times
151
- expect { subject }.to raise_error(Timeout::Error)
152
- end
153
-
154
- describe "invalid JSON response" do
155
- let(:block) { proc{ MultiJson.load("<title>#{title}</title>")} }
156
- before { allow(Embulk.logger).to receive(:warn) }
157
-
158
- # Disable this test to enable retry for 401
159
- # context "Unauthorized" do
160
- # let(:title) { "Unauthorized (401)" }
161
- #
162
- # it do
163
- # expect { subject }.to raise_error(Embulk::ConfigError)
164
- # end
165
- # end
166
-
167
- context "Unavailable" do
168
- let(:title) { "Atlassian Cloud Notifications - Page Unavailable"}
169
-
170
- it do
171
- expect { subject }.to raise_error(StandardError, title)
172
- end
173
- end
174
- end
175
- end
176
-
177
- describe "#calculate_rate_limit" do
178
- let(:jira_api) { Embulk::Input::JiraApi::Client.new }
179
- it "current_limit = 50, all_items = 50, fail_items=50, times=1" do
180
- current_limit = 50
181
- all_items = 50
182
- fail_items = 50
183
- times = 1
184
- expected_result = Embulk::Input::JiraApi::Client::MIN_RATE_LIMIT
185
- expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
186
- end
187
-
188
- it "current_limit = 50, all_items = 50, fail_items=20, times=1" do
189
- current_limit = 50
190
- all_items = 50
191
- fail_items = 20
192
- times = 1
193
- expected_result = 20
194
- expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
195
- end
196
-
197
- it "current_limit = MIN_RATE_LIMIT, all_items = 50, fail_items=20, times=2" do
198
- current_limit = Embulk::Input::JiraApi::Client::MIN_RATE_LIMIT
199
- all_items = 50
200
- fail_items = 20
201
- times = 2
202
- expected_result = Embulk::Input::JiraApi::Client::MIN_RATE_LIMIT
203
- expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
204
- end
205
-
206
- it "current_limit = 10, all_items = 30, fail_items=25, times=2" do
207
- current_limit = 10
208
- all_items = 30
209
- fail_items = 25
210
- times = 2
211
- expected_result = 5
212
- expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
213
- end
214
-
215
- it "current_limit = 50, all_items = 50, fail_items=20, times=DEFAULT_SEARCH_RETRY_TIMES/2" do
216
- current_limit = 50
217
- all_items = 50
218
- fail_items = 20
219
- times = Embulk::Input::JiraApi::Client::DEFAULT_SEARCH_RETRY_TIMES/2
220
- expected_result = Embulk::Input::JiraApi::Client::MIN_RATE_LIMIT
221
- expect(jira_api.calculate_rate_limit(current_limit, all_items, fail_items, times)).to eq expected_result
222
- end
223
- end
224
- end
@@ -1,394 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Embulk::Input::JiraApi::Issue do
4
- describe ".initialize" do
5
- context "when argument has 'fields' key" do
6
- let(:issue_attributes) do
7
- {
8
- "id" => 1,
9
- "jira_key" => "PRO-1",
10
- "fields" =>
11
- {
12
- "summary" => "jira issue",
13
- "project" =>
14
- {
15
- "key" => "FOO",
16
- },
17
- }
18
- }
19
- end
20
-
21
- it "has @id with argument['id']" do
22
- expect(Embulk::Input::JiraApi::Issue.new(issue_attributes).id).to eq issue_attributes["id"]
23
- end
24
-
25
- it "has @key with argument['jira_key']" do
26
- expect(Embulk::Input::JiraApi::Issue.new(issue_attributes).key).to eq issue_attributes["jira_key"]
27
- end
28
-
29
- it "has @fields with argument['fields']" do
30
- expect(Embulk::Input::JiraApi::Issue.new(issue_attributes).fields).to eq issue_attributes["fields"]
31
- end
32
- end
33
-
34
- context "when argument doesn't have 'fields' key" do
35
- let(:issue_attributes) do
36
- {}
37
- end
38
-
39
- it "raises error" do
40
- expect { Embulk::Input::JiraApi::Issue.new(issue_attributes) }.to raise_error
41
- end
42
- end
43
- end
44
-
45
- describe "#[]" do
46
- subject { Embulk::Input::JiraApi::Issue.new(issue_attributes)[attribute_name] }
47
-
48
- let(:issue_attributes) do
49
- {
50
- "id" => "1",
51
- "jira_key" => "FOO-1",
52
- "fields" => fields_attributes
53
- }
54
- end
55
-
56
- context "when target attribute_name is especially key" do
57
- let(:fields_attributes) { {} }
58
-
59
- context 'id' do
60
- let(:attribute_name) { 'id' }
61
-
62
- it "returns issue id" do
63
- expect(subject).to eq "1"
64
- end
65
- end
66
-
67
- context 'key' do
68
- let(:attribute_name) { 'key' }
69
-
70
- it "returns issue key" do
71
- expect(subject).to eq "FOO-1"
72
- end
73
- end
74
- end
75
-
76
- context "when fields_attributes is empty Hash" do
77
- let(:fields_attributes) { {} }
78
-
79
- let(:attribute_name) { 'key1' }
80
-
81
- it "returns nil" do
82
- expect(subject).to eq nil
83
- end
84
- end
85
-
86
- context "when fields_attributes is empty Hash including Array" do
87
- let(:fields_attributes) { { 'key1' => [] } }
88
-
89
- let(:attribute_name) { 'key1' }
90
-
91
- it "returns empty Array" do
92
- expect(subject).to eq []
93
- end
94
- end
95
-
96
- context "when fields_attributes is Hash" do
97
- let(:fields_attributes) do
98
- {'key' => 'value'}
99
- end
100
-
101
- let(:attribute_name) { 'key' }
102
-
103
- it "returns 'value'" do
104
- expect(subject).to eq "FOO-1"
105
- end
106
- end
107
-
108
- context "when fields_attributes is `{'key1' => {'key2' => 'value2', 'key3' => 'value3'}}`" do
109
- let(:fields_attributes) do
110
- {'key1' => {'key2' => 'value2', 'key3' => 'value3'}}
111
- end
112
-
113
- context "when attribute_name is 'key1'" do
114
- let(:attribute_name) { 'key1' }
115
-
116
- it "returns key1's JSON" do
117
- expect(subject).to eq({'key2' => 'value2', 'key3' => 'value3'}.to_json)
118
- end
119
- end
120
-
121
- context "when attribute_name is 'key1.key2'" do
122
- let(:attribute_name) { 'key1.key2' }
123
-
124
- it "returns 'value2'" do
125
- expect(subject).to eq 'value2'
126
- end
127
- end
128
- end
129
-
130
- context "when fields_attributes is `{'key1' => [{'key2' => 'value2-1'}, {'key2' => 'value2-2'}]}`" do
131
- let(:fields_attributes) do
132
- {'key1' => [{'key2' => 'value2-1'}, {'key2' => 'value2-2'}]}
133
- end
134
-
135
- context "when attribute_name is 'key1'" do
136
- let(:attribute_name) { 'key1' }
137
-
138
- it "returns JSON array" do
139
- expect(subject).to eq '{"key2":"value2-1"},{"key2":"value2-2"}'
140
- end
141
- end
142
-
143
- context "when attribute_name is 'key1.key2'" do
144
- let(:attribute_name) { 'key1.key2' }
145
-
146
- it "returns CSV values assigned by 'key2' key" do
147
- expect(subject).to eq 'value2-1,value2-2'
148
- end
149
- end
150
- end
151
-
152
- context "when fields_attributes is `{'key1' => [{'key2' => 'value2-1'}, nil]}`" do
153
- let(:fields_attributes) do
154
- {'key1' => [{'key2' => 'value2-1'}, nil]}
155
- end
156
-
157
- context "when attribute_name is 'key1'" do
158
- let(:attribute_name) { 'key1' }
159
-
160
- it "returns CSV value including null" do
161
- expect(subject).to eq '{"key2":"value2-1"},null'
162
- end
163
- end
164
-
165
- context "when attribute_name is 'key1.key2'" do
166
- let(:attribute_name) { 'key1.key2' }
167
-
168
- it "returns JSON array including null" do
169
- expect(subject).to eq 'value2-1,null'
170
- end
171
- end
172
- end
173
-
174
- context "when fields_attributes is `{'key1' => ['element1', 'element2', 'element3']}`" do
175
- let(:fields_attributes) do
176
- {
177
- 'key1' => ['element1', 'element2', 'element3'],
178
- }
179
- end
180
-
181
- let(:attribute_name) { 'key1' }
182
-
183
- it "returns CSV values assigned by 'key1'" do
184
- expect(subject).to eq 'element1,element2,element3'
185
- end
186
- end
187
- end
188
-
189
- describe "#to_record" do
190
- subject do
191
- Embulk::Input::JiraApi::Issue.new(issue_attributes).to_record
192
- end
193
-
194
- shared_examples 'return guessed record' do
195
- it do
196
- expect(subject).to eq expected_record
197
- end
198
- end
199
-
200
- let(:issue_attributes) do
201
- {"jira_key" => "FOO-1", "id" => "1", "fields" => fields_attributes}
202
- end
203
-
204
- let(:expected_record) do
205
- {
206
- "key" => "FOO-1",
207
- "id" => "1"
208
- }.merge(exptected_record_from_fields)
209
- end
210
-
211
- context "when fields_attributes is `{'key' => 'value'}`" do
212
- let(:fields_attributes) do
213
- {'key' => 'value'}
214
- end
215
-
216
- let(:exptected_record_from_fields) do
217
- {'key' => 'value'}
218
- end
219
-
220
- it_behaves_like "return guessed record"
221
- end
222
-
223
- context "when fields_attributes is `{'key1' => {'key2' => 'value2', 'key3' => 'value3'}}`" do
224
- let(:fields_attributes) do
225
- {
226
- 'key1' => {
227
- 'key2' => 'value2',
228
- 'key3' => 'value3',
229
- }
230
- }
231
- end
232
-
233
- let(:exptected_record_from_fields) do
234
- {
235
- "key1.key2" => "value2",
236
- "key1.key3" => "value3"
237
- }
238
- end
239
-
240
- it_behaves_like "return guessed record"
241
- end
242
-
243
- context "when fields_attributes is `{'key1' => {'key2' => {'key3' => last_child}}}`" do
244
- let(:fields_attributes) do
245
- {'key1' => {'key2' => {'key3' => last_child}}}
246
- end
247
-
248
- context "when last_child is String" do
249
- let(:last_child) do
250
- "String"
251
- end
252
-
253
- let(:exptected_record_from_fields) do
254
- {"key1.key2.key3" => "String"}
255
- end
256
-
257
- it_behaves_like "return guessed record"
258
- end
259
-
260
- context "when last_child has 'key' key" do
261
- let(:last_child) do
262
- {"key" => "BAR-1"}
263
- end
264
-
265
- let(:exptected_record_from_fields) do
266
- {"key1.key2.key3.key" => "BAR-1"}
267
- end
268
-
269
- it_behaves_like "return guessed record"
270
- end
271
-
272
- context "when last_child has 'id' key" do
273
- let(:last_child) do
274
- {"id" => "20"}
275
- end
276
-
277
- let(:exptected_record_from_fields) do
278
- {"key1.key2.key3.id" => "20"}
279
- end
280
-
281
- it_behaves_like "return guessed record"
282
- end
283
-
284
- context "when last_child has 'name' key" do
285
- let(:last_child) do
286
- {"name" => "Foo name"}
287
- end
288
-
289
- let(:exptected_record_from_fields) do
290
- {"key1.key2.key3.name" => "Foo name"}
291
- end
292
-
293
- it_behaves_like "return guessed record"
294
- end
295
-
296
- context "when last_child has another key except 'key', 'id', 'name'" do
297
- let(:last_child) do
298
- {"customfield_0001" => "value0001"}
299
- end
300
-
301
- let(:exptected_record_from_fields) do
302
- {"key1.key2.key3" => "{\"customfield_0001\":\"value0001\"}"}
303
- end
304
-
305
- it_behaves_like "return guessed record"
306
- end
307
-
308
- context "when last_child Hash Array" do
309
- let(:last_child) do
310
- [
311
- {"key4" => "value4", "key5" => "value5-1"},
312
- {"key6" => "value6", "key5" => "value5-2"},
313
- ]
314
- end
315
-
316
- let(:exptected_record_from_fields) do
317
- {"key1.key2.key3" => '{"key4":["value4",null],"key5":["value5-1","value5-2"],"key6":[null,"value6"]}'}
318
- end
319
-
320
- it_behaves_like "return guessed record"
321
- end
322
- end
323
-
324
- context "when fields_attributes is `{'key1' => ['element1-1', 'element1-2', 'element1-3'], 'key2' => ['element2-1', 'element2-2', 'element2-3']}`" do
325
- let(:fields_attributes) do
326
- {
327
- 'key1' => ['element1-1', 'element1-2', 'element1-3'],
328
- 'key2' => ['element2-1', 'element2-2', 'element2-3'],
329
- }
330
- end
331
-
332
- let(:exptected_record_from_fields) do
333
- {
334
- 'key1' => '"element1-1,element1-2,element1-3"',
335
- 'key2' => '"element2-1,element2-2,element2-3"',
336
- }
337
- end
338
-
339
- it_behaves_like "return guessed record"
340
- end
341
-
342
- context "when fields_attributes is `{'key' => []}`" do
343
- let(:fields_attributes) do
344
- {'key' => []}
345
- end
346
-
347
- let(:exptected_record_from_fields) do
348
- {"key" => '""'}
349
- end
350
-
351
- it_behaves_like "return guessed record"
352
- end
353
-
354
- context "when fields_attributes is `{'key1' => { 'key2' => [{'key3' => 'value3-1'}, {'key3'=> 'value3-2'}]}}`" do
355
- let(:fields_attributes) do
356
- {
357
- 'key1' => {
358
- 'key2' => [
359
- {'key3' => 'value3-1'}, {'key3'=> 'value3-2'},
360
- ]
361
- }
362
- }
363
- end
364
-
365
- let(:exptected_record_from_fields) do
366
- {
367
- "key1.key2.key3" => '"value3-1,value3-2"',
368
- }
369
- end
370
-
371
- it_behaves_like "return guessed record"
372
- end
373
-
374
- context "when fields_attributes is `{'key1' => { 'key2' => ['element2-1', 'element2-2', 'element2-3'], 'key3' => ['element3-1', 'element3-2', 'element3-3']}}`" do
375
- let(:fields_attributes) do
376
- {
377
- 'key1' => {
378
- 'key2' => ['element2-1', 'element2-2', 'element2-3'],
379
- 'key3' => ['element3-1', 'element3-2', 'element3-3']
380
- }
381
- }
382
- end
383
-
384
- let(:exptected_record_from_fields) do
385
- {
386
- "key1.key2" => '"element2-1,element2-2,element2-3"',
387
- "key1.key3" => '"element3-1,element3-2,element3-3"',
388
- }
389
- end
390
-
391
- it_behaves_like "return guessed record"
392
- end
393
- end
394
- end