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.
- checksums.yaml +4 -4
- data/.gitignore +10 -5
- data/.travis.yml +4 -34
- data/CHANGELOG.md +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +5 -4
- data/build.gradle +116 -0
- data/config/checkstyle/checkstyle.xml +128 -0
- data/config/checkstyle/default.xml +108 -0
- data/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/gradle/wrapper/gradle-wrapper.properties +5 -0
- data/gradlew +172 -0
- data/gradlew.bat +84 -0
- data/lib/embulk/guess/jira.rb +24 -0
- data/lib/embulk/input/jira.rb +3 -169
- data/src/main/java/org/embulk/input/jira/AuthenticateMethod.java +27 -0
- data/src/main/java/org/embulk/input/jira/Constant.java +17 -0
- data/src/main/java/org/embulk/input/jira/Issue.java +150 -0
- data/src/main/java/org/embulk/input/jira/JiraInputPlugin.java +226 -0
- data/src/main/java/org/embulk/input/jira/client/JiraClient.java +254 -0
- data/src/main/java/org/embulk/input/jira/util/JiraException.java +18 -0
- data/src/main/java/org/embulk/input/jira/util/JiraUtil.java +264 -0
- data/src/test/java/org/embulk/input/jira/IssueTest.java +278 -0
- data/src/test/java/org/embulk/input/jira/JiraInputPluginTest.java +204 -0
- data/src/test/java/org/embulk/input/jira/JiraPluginTestRuntime.java +133 -0
- data/src/test/java/org/embulk/input/jira/TestHelpers.java +41 -0
- data/src/test/java/org/embulk/input/jira/client/JiraClientTest.java +222 -0
- data/src/test/java/org/embulk/input/jira/util/JiraUtilTest.java +318 -0
- data/src/test/resources/config.yml +13 -0
- data/src/test/resources/issue_flatten.json +129 -0
- data/src/test/resources/issue_flatten_expected.json +73 -0
- data/src/test/resources/issue_get.json +36 -0
- data/src/test/resources/issue_get_expected.json +62 -0
- data/src/test/resources/jira_client.json +81 -0
- data/src/test/resources/jira_input_plugin.json +114 -0
- data/src/test/resources/jira_util.json +26 -0
- metadata +55 -175
- data/Gemfile +0 -3
- data/LICENSE +0 -13
- data/Rakefile +0 -15
- data/embulk-input-jira.gemspec +0 -27
- data/gemfiles/embulk-0.8.0-latest +0 -4
- data/gemfiles/embulk-0.8.7 +0 -4
- data/gemfiles/embulk-0.8.8 +0 -4
- data/gemfiles/embulk-latest +0 -4
- data/gemfiles/template.erb +0 -4
- data/lib/embulk/input/jira_api.rb +0 -9
- data/lib/embulk/input/jira_api/client.rb +0 -144
- data/lib/embulk/input/jira_api/issue.rb +0 -133
- data/lib/embulk/input/jira_input_plugin_utils.rb +0 -58
- data/spec/embulk/input/jira-input-plugin-utils_spec.rb +0 -89
- data/spec/embulk/input/jira_api/client_spec.rb +0 -224
- data/spec/embulk/input/jira_api/issue_spec.rb +0 -394
- data/spec/embulk/input/jira_spec.rb +0 -322
- data/spec/embulk_spec.rb +0 -32
- data/spec/spec_helper.rb +0 -26
- data/spec/support/stdout_and_err_capture.rb +0 -45
@@ -0,0 +1,318 @@
|
|
1
|
+
package org.embulk.input.jira.util;
|
2
|
+
|
3
|
+
import com.google.gson.JsonObject;
|
4
|
+
|
5
|
+
import org.embulk.config.ConfigException;
|
6
|
+
import org.embulk.config.ConfigSource;
|
7
|
+
import org.embulk.input.jira.Issue;
|
8
|
+
import org.embulk.input.jira.JiraInputPlugin.PluginTask;
|
9
|
+
import org.embulk.input.jira.TestHelpers;
|
10
|
+
import org.embulk.spi.Column;
|
11
|
+
import org.embulk.spi.PageBuilder;
|
12
|
+
import org.embulk.spi.Schema;
|
13
|
+
import org.embulk.spi.json.JsonParser;
|
14
|
+
import org.embulk.spi.time.Timestamp;
|
15
|
+
import org.embulk.spi.time.TimestampParser;
|
16
|
+
import org.junit.BeforeClass;
|
17
|
+
import org.junit.Test;
|
18
|
+
import org.mockito.Mockito;
|
19
|
+
import org.msgpack.value.Value;
|
20
|
+
|
21
|
+
import java.io.IOException;
|
22
|
+
|
23
|
+
import static org.junit.Assert.assertEquals;
|
24
|
+
import static org.junit.Assert.assertNotNull;
|
25
|
+
import static org.junit.Assert.assertNull;
|
26
|
+
import static org.junit.Assert.assertTrue;
|
27
|
+
import static org.mockito.Mockito.times;
|
28
|
+
import static org.mockito.Mockito.verify;
|
29
|
+
|
30
|
+
public class JiraUtilTest
|
31
|
+
{
|
32
|
+
private static JsonObject data;
|
33
|
+
private static PluginTask pluginTask;
|
34
|
+
private static Schema schema;
|
35
|
+
private static Column booleanColumn;
|
36
|
+
private static Column longColumn;
|
37
|
+
private static Column doubleColumn;
|
38
|
+
private static Column stringColumn;
|
39
|
+
private static Column dateColumn;
|
40
|
+
private static Column jsonColumn;
|
41
|
+
|
42
|
+
@BeforeClass
|
43
|
+
public static void setUp() throws IOException
|
44
|
+
{
|
45
|
+
data = TestHelpers.getJsonFromFile("jira_util.json");
|
46
|
+
pluginTask = TestHelpers.config().loadConfig(PluginTask.class);
|
47
|
+
schema = pluginTask.getColumns().toSchema();
|
48
|
+
booleanColumn = schema.getColumn(0);
|
49
|
+
longColumn = schema.getColumn(1);
|
50
|
+
doubleColumn = schema.getColumn(2);
|
51
|
+
stringColumn = schema.getColumn(3);
|
52
|
+
dateColumn = schema.getColumn(4);
|
53
|
+
jsonColumn = schema.getColumn(5);
|
54
|
+
}
|
55
|
+
@Test
|
56
|
+
public void test_calculateTotalPage()
|
57
|
+
{
|
58
|
+
int resultPerPage = 50;
|
59
|
+
int expected = 0;
|
60
|
+
int totalCount = 0;
|
61
|
+
int actual = JiraUtil.calculateTotalPage(totalCount, resultPerPage);
|
62
|
+
assertEquals(expected, actual);
|
63
|
+
|
64
|
+
expected = 1;
|
65
|
+
totalCount = resultPerPage - 1;
|
66
|
+
actual = JiraUtil.calculateTotalPage(totalCount, resultPerPage);
|
67
|
+
assertEquals(expected, actual);
|
68
|
+
|
69
|
+
expected = 1;
|
70
|
+
totalCount = resultPerPage;
|
71
|
+
actual = JiraUtil.calculateTotalPage(totalCount, resultPerPage);
|
72
|
+
assertEquals(expected, actual);
|
73
|
+
|
74
|
+
expected = 2;
|
75
|
+
totalCount = resultPerPage + 1;
|
76
|
+
actual = JiraUtil.calculateTotalPage(totalCount, resultPerPage);
|
77
|
+
assertEquals(expected, actual);
|
78
|
+
}
|
79
|
+
|
80
|
+
@Test
|
81
|
+
public void test_buildPermissionUrl()
|
82
|
+
{
|
83
|
+
String url = "https://example.com";
|
84
|
+
String expected = "https://example.com/rest/api/latest/myself";
|
85
|
+
String actual = JiraUtil.buildPermissionUrl(url);
|
86
|
+
assertEquals(expected, actual);
|
87
|
+
|
88
|
+
url = "https://example.com/";
|
89
|
+
expected = "https://example.com/rest/api/latest/myself";
|
90
|
+
actual = JiraUtil.buildPermissionUrl(url);
|
91
|
+
assertEquals(expected, actual);
|
92
|
+
|
93
|
+
url = "https://example.com//";
|
94
|
+
expected = "https://example.com//rest/api/latest/myself";
|
95
|
+
actual = JiraUtil.buildPermissionUrl(url);
|
96
|
+
assertEquals(expected, actual);
|
97
|
+
|
98
|
+
url = "https://example.com/sub/subsub";
|
99
|
+
expected = "https://example.com/sub/subsub/rest/api/latest/myself";
|
100
|
+
actual = JiraUtil.buildPermissionUrl(url);
|
101
|
+
assertEquals(expected, actual);
|
102
|
+
}
|
103
|
+
|
104
|
+
@Test
|
105
|
+
public void test_buildSearchUrl() throws IOException
|
106
|
+
{
|
107
|
+
PluginTask task = TestHelpers.config().loadConfig(PluginTask.class);
|
108
|
+
String expected = "https://example.com/rest/api/latest/search";
|
109
|
+
String actual = JiraUtil.buildSearchUrl(task.getUri());
|
110
|
+
assertEquals(expected, actual);
|
111
|
+
}
|
112
|
+
|
113
|
+
@Test
|
114
|
+
public void test_validateTaskConfig() throws IOException
|
115
|
+
{
|
116
|
+
// Happy case
|
117
|
+
ConfigSource configSource = TestHelpers.config();
|
118
|
+
PluginTask task = configSource.loadConfig(PluginTask.class);
|
119
|
+
Exception exception = null;
|
120
|
+
try {
|
121
|
+
JiraUtil.validateTaskConfig(task);
|
122
|
+
}
|
123
|
+
catch (Exception e) {
|
124
|
+
exception = e;
|
125
|
+
}
|
126
|
+
assertNull(exception);
|
127
|
+
|
128
|
+
// empty username
|
129
|
+
configSource = TestHelpers.config();
|
130
|
+
configSource.set("username", "");
|
131
|
+
task = configSource.loadConfig(PluginTask.class);
|
132
|
+
exception = null;
|
133
|
+
try {
|
134
|
+
JiraUtil.validateTaskConfig(task);
|
135
|
+
}
|
136
|
+
catch (Exception e) {
|
137
|
+
exception = e;
|
138
|
+
}
|
139
|
+
assertNotNull(exception);
|
140
|
+
assertTrue(exception instanceof ConfigException);
|
141
|
+
assertEquals("Username or email could not be empty", exception.getMessage());
|
142
|
+
|
143
|
+
// empty password
|
144
|
+
configSource = TestHelpers.config();
|
145
|
+
configSource.set("password", "");
|
146
|
+
task = configSource.loadConfig(PluginTask.class);
|
147
|
+
exception = null;
|
148
|
+
try {
|
149
|
+
JiraUtil.validateTaskConfig(task);
|
150
|
+
}
|
151
|
+
catch (Exception e) {
|
152
|
+
exception = e;
|
153
|
+
}
|
154
|
+
assertNotNull(exception);
|
155
|
+
assertTrue(exception instanceof ConfigException);
|
156
|
+
assertEquals("Password could not be empty", exception.getMessage());
|
157
|
+
|
158
|
+
// empty uri
|
159
|
+
configSource = TestHelpers.config();
|
160
|
+
configSource.set("uri", "");
|
161
|
+
task = configSource.loadConfig(PluginTask.class);
|
162
|
+
exception = null;
|
163
|
+
try {
|
164
|
+
JiraUtil.validateTaskConfig(task);
|
165
|
+
}
|
166
|
+
catch (Exception e) {
|
167
|
+
exception = e;
|
168
|
+
}
|
169
|
+
assertNotNull(exception);
|
170
|
+
assertTrue(exception instanceof ConfigException);
|
171
|
+
assertEquals("JIRA API endpoint could not be empty", exception.getMessage());
|
172
|
+
|
173
|
+
// invalid uri
|
174
|
+
configSource = TestHelpers.config();
|
175
|
+
configSource.set("uri", "https://not-existed-domain");
|
176
|
+
task = configSource.loadConfig(PluginTask.class);
|
177
|
+
exception = null;
|
178
|
+
try {
|
179
|
+
JiraUtil.validateTaskConfig(task);
|
180
|
+
}
|
181
|
+
catch (Exception e) {
|
182
|
+
exception = e;
|
183
|
+
}
|
184
|
+
assertNotNull(exception);
|
185
|
+
assertTrue(exception instanceof ConfigException);
|
186
|
+
assertEquals("JIRA API endpoint is incorrect or not available", exception.getMessage());
|
187
|
+
|
188
|
+
// empty jql
|
189
|
+
configSource = TestHelpers.config();
|
190
|
+
configSource.set("jql", "");
|
191
|
+
task = configSource.loadConfig(PluginTask.class);
|
192
|
+
exception = null;
|
193
|
+
try {
|
194
|
+
JiraUtil.validateTaskConfig(task);
|
195
|
+
}
|
196
|
+
catch (Exception e) {
|
197
|
+
exception = e;
|
198
|
+
}
|
199
|
+
assertNotNull(exception);
|
200
|
+
assertTrue(exception instanceof ConfigException);
|
201
|
+
assertEquals("JQL could not be empty", exception.getMessage());
|
202
|
+
|
203
|
+
// initial_retry_interval_millis = 0
|
204
|
+
configSource = TestHelpers.config();
|
205
|
+
configSource.set("initial_retry_interval_millis", 0);
|
206
|
+
task = configSource.loadConfig(PluginTask.class);
|
207
|
+
exception = null;
|
208
|
+
try {
|
209
|
+
JiraUtil.validateTaskConfig(task);
|
210
|
+
}
|
211
|
+
catch (Exception e) {
|
212
|
+
exception = e;
|
213
|
+
}
|
214
|
+
assertNotNull(exception);
|
215
|
+
assertTrue(exception instanceof ConfigException);
|
216
|
+
assertEquals("Initial retry delay should be equal or greater than 1", exception.getMessage());
|
217
|
+
|
218
|
+
// retry_limit = -1
|
219
|
+
configSource = TestHelpers.config();
|
220
|
+
configSource.set("retry_limit", -1);
|
221
|
+
task = configSource.loadConfig(PluginTask.class);
|
222
|
+
exception = null;
|
223
|
+
try {
|
224
|
+
JiraUtil.validateTaskConfig(task);
|
225
|
+
}
|
226
|
+
catch (Exception e) {
|
227
|
+
exception = e;
|
228
|
+
}
|
229
|
+
assertNotNull(exception);
|
230
|
+
assertTrue(exception instanceof ConfigException);
|
231
|
+
assertEquals("Retry limit should between 0 and 10", exception.getMessage());
|
232
|
+
|
233
|
+
// retry_limit = 100
|
234
|
+
configSource = TestHelpers.config();
|
235
|
+
configSource.set("retry_limit", 100);
|
236
|
+
task = configSource.loadConfig(PluginTask.class);
|
237
|
+
exception = null;
|
238
|
+
try {
|
239
|
+
JiraUtil.validateTaskConfig(task);
|
240
|
+
}
|
241
|
+
catch (Exception e) {
|
242
|
+
exception = e;
|
243
|
+
}
|
244
|
+
assertNotNull(exception);
|
245
|
+
assertTrue(exception instanceof ConfigException);
|
246
|
+
assertEquals("Retry limit should between 0 and 10", exception.getMessage());
|
247
|
+
}
|
248
|
+
|
249
|
+
@Test
|
250
|
+
public void test_addRecord_allRight()
|
251
|
+
{
|
252
|
+
String testName = "allRight";
|
253
|
+
Issue issue = new Issue(data.get(testName).getAsJsonObject());
|
254
|
+
PageBuilder mock = Mockito.mock(PageBuilder.class);
|
255
|
+
|
256
|
+
Boolean boolValue = Boolean.TRUE;
|
257
|
+
Long longValue = Long.valueOf(1);
|
258
|
+
Double doubleValue = Double.valueOf(1);
|
259
|
+
String stringValue = "string";
|
260
|
+
Timestamp dateValue = TimestampParser.of("%Y-%m-%dT%H:%M:%S.%L%z", "UTC").parse("2019-01-01T00:00:00.000Z");
|
261
|
+
Value jsonValue = new JsonParser().parse("{}");
|
262
|
+
|
263
|
+
JiraUtil.addRecord(issue, schema, pluginTask, mock);
|
264
|
+
|
265
|
+
verify(mock, times(1)).setBoolean(booleanColumn, boolValue);
|
266
|
+
verify(mock, times(1)).setLong(longColumn, longValue);
|
267
|
+
verify(mock, times(1)).setDouble(doubleColumn, doubleValue);
|
268
|
+
verify(mock, times(1)).setString(stringColumn, stringValue);
|
269
|
+
verify(mock, times(1)).setTimestamp(dateColumn, dateValue);
|
270
|
+
verify(mock, times(1)).setJson(jsonColumn, jsonValue);
|
271
|
+
}
|
272
|
+
|
273
|
+
@Test
|
274
|
+
public void test_addRecord_allWrong()
|
275
|
+
{
|
276
|
+
String testName = "allWrong";
|
277
|
+
Issue issue = new Issue(data.get(testName).getAsJsonObject());
|
278
|
+
PageBuilder mock = Mockito.mock(PageBuilder.class);
|
279
|
+
|
280
|
+
String stringValue = "{}";
|
281
|
+
Value jsonValue = new JsonParser().parse("{}");
|
282
|
+
|
283
|
+
JiraUtil.addRecord(issue, schema, pluginTask, mock);
|
284
|
+
|
285
|
+
verify(mock, times(1)).setNull(booleanColumn);
|
286
|
+
verify(mock, times(1)).setNull(longColumn);
|
287
|
+
verify(mock, times(1)).setNull(doubleColumn);
|
288
|
+
verify(mock, times(1)).setString(stringColumn, stringValue);
|
289
|
+
verify(mock, times(1)).setNull(dateColumn);
|
290
|
+
verify(mock, times(1)).setJson(jsonColumn, jsonValue);
|
291
|
+
}
|
292
|
+
|
293
|
+
@Test
|
294
|
+
public void test_addRecord_allMissing()
|
295
|
+
{
|
296
|
+
String testName = "allMissing";
|
297
|
+
Issue issue = new Issue(data.get(testName).getAsJsonObject());
|
298
|
+
PageBuilder mock = Mockito.mock(PageBuilder.class);
|
299
|
+
|
300
|
+
JiraUtil.addRecord(issue, schema, pluginTask, mock);
|
301
|
+
|
302
|
+
verify(mock, times(6)).setNull(Mockito.any(Column.class));
|
303
|
+
}
|
304
|
+
|
305
|
+
@Test
|
306
|
+
public void test_addRecord_arrayAsString()
|
307
|
+
{
|
308
|
+
String testName = "arrayAsString";
|
309
|
+
Issue issue = new Issue(data.get(testName).getAsJsonObject());
|
310
|
+
PageBuilder mock = Mockito.mock(PageBuilder.class);
|
311
|
+
|
312
|
+
String stringValue = "1,{},[]";
|
313
|
+
|
314
|
+
JiraUtil.addRecord(issue, schema, pluginTask, mock);
|
315
|
+
|
316
|
+
verify(mock, times(1)).setString(stringColumn, stringValue);
|
317
|
+
}
|
318
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
type: jira
|
2
|
+
username: example@example.com
|
3
|
+
password: XXXXXXXXXXXXXXXXX
|
4
|
+
uri: "https://example.com/"
|
5
|
+
jql: project = example
|
6
|
+
retry_limit: 3
|
7
|
+
columns:
|
8
|
+
- {name: boolean, type: boolean}
|
9
|
+
- {name: long, type: long}
|
10
|
+
- {name: double, type: double}
|
11
|
+
- {name: string, type: string}
|
12
|
+
- {name: date, type: timestamp, format: '%Y-%m-%dT%H:%M:%S.%L%z'}
|
13
|
+
- {name: json, type: json}
|
@@ -0,0 +1,129 @@
|
|
1
|
+
{
|
2
|
+
"simple": {
|
3
|
+
"primitive": 1,
|
4
|
+
"string": "string",
|
5
|
+
"array": [],
|
6
|
+
"object": {},
|
7
|
+
"null": null
|
8
|
+
},
|
9
|
+
"twoLevels": {
|
10
|
+
"1stLevel": {
|
11
|
+
"2ndLevelPrimitive": 1,
|
12
|
+
"2ndLevelString": "string",
|
13
|
+
"2ndLevelArray": [],
|
14
|
+
"2ndLevelObject": {},
|
15
|
+
"2ndLevelNull": null
|
16
|
+
}
|
17
|
+
},
|
18
|
+
"threeLevels": {
|
19
|
+
"1stLevel": {
|
20
|
+
"2ndLevel": {
|
21
|
+
"3rdLevelPrimitive": 1,
|
22
|
+
"3rdLevelString": "string",
|
23
|
+
"3rdLevelArray": [],
|
24
|
+
"3rdLevelObject": {},
|
25
|
+
"3rdLevelNull": null
|
26
|
+
}
|
27
|
+
}
|
28
|
+
},
|
29
|
+
"threeLevelsWithoutKeys": {
|
30
|
+
"1stLevel": {
|
31
|
+
"2ndLevel": {
|
32
|
+
"3rdLevelPrimitive": 1,
|
33
|
+
"3rdLevelString": "string",
|
34
|
+
"3rdLevelArray": [],
|
35
|
+
"3rdLevelObject": {
|
36
|
+
"notKey": "notKey"
|
37
|
+
},
|
38
|
+
"3rdLevelNull": null
|
39
|
+
}
|
40
|
+
}
|
41
|
+
},
|
42
|
+
"threeLevelsWithKeys": {
|
43
|
+
"1stLevel": {
|
44
|
+
"2ndLevel": {
|
45
|
+
"3rdLevelPrimitive": 1,
|
46
|
+
"3rdLevelString": "string",
|
47
|
+
"3rdLevelArray": [],
|
48
|
+
"3rdLevelObject": {
|
49
|
+
"id": "id",
|
50
|
+
"name": "name",
|
51
|
+
"key": "key",
|
52
|
+
"notKey": "notKey"
|
53
|
+
},
|
54
|
+
"3rdLevelNull": null
|
55
|
+
}
|
56
|
+
}
|
57
|
+
},
|
58
|
+
"threeLevelsWithNullKeys": {
|
59
|
+
"1stLevel": {
|
60
|
+
"2ndLevel": {
|
61
|
+
"3rdLevelPrimitive": 1,
|
62
|
+
"3rdLevelString": "string",
|
63
|
+
"3rdLevelArray": [],
|
64
|
+
"3rdLevelObject": {
|
65
|
+
"id": "id",
|
66
|
+
"name": "name",
|
67
|
+
"key": null
|
68
|
+
},
|
69
|
+
"3rdLevelNull": null
|
70
|
+
}
|
71
|
+
}
|
72
|
+
},
|
73
|
+
"arrayWithAllJsonObjectWithSameKeysAndEmptyObject": {
|
74
|
+
"array": [
|
75
|
+
{
|
76
|
+
"primitive": 1,
|
77
|
+
"string": "string",
|
78
|
+
"array": [],
|
79
|
+
"object": {},
|
80
|
+
"null": null
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"primitive": 2,
|
84
|
+
"string": "string2",
|
85
|
+
"array": [],
|
86
|
+
"object": {},
|
87
|
+
"null": null
|
88
|
+
}
|
89
|
+
]
|
90
|
+
},
|
91
|
+
"arrayWithAllJsonObjectWithSameKeysAndNotEmptyObject": {
|
92
|
+
"array": [
|
93
|
+
{
|
94
|
+
"primitive": 1,
|
95
|
+
"string": "string",
|
96
|
+
"array": [],
|
97
|
+
"object": {
|
98
|
+
"primitive": 1
|
99
|
+
},
|
100
|
+
"null": null
|
101
|
+
},
|
102
|
+
{
|
103
|
+
"primitive": 2,
|
104
|
+
"string": "string2",
|
105
|
+
"array": [],
|
106
|
+
"object": {},
|
107
|
+
"null": null
|
108
|
+
}
|
109
|
+
]
|
110
|
+
},
|
111
|
+
"arrayWithAllJsonObjectWithoutSameKeys": {
|
112
|
+
"array": [
|
113
|
+
{
|
114
|
+
"primitive": 1,
|
115
|
+
"string": "string",
|
116
|
+
"array": [],
|
117
|
+
"object": {},
|
118
|
+
"null": null
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"primitive1": 2,
|
122
|
+
"string1": "string2",
|
123
|
+
"array1": [],
|
124
|
+
"object1": {},
|
125
|
+
"null1": null
|
126
|
+
}
|
127
|
+
]
|
128
|
+
}
|
129
|
+
}
|