appium 2.0.0-beta.21 → 2.0.0-beta.25

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 (93) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1 -2
  3. package/build/check-npm-pack-files.js +23 -0
  4. package/build/commands-yml/parse.js +319 -0
  5. package/build/commands-yml/validator.js +130 -0
  6. package/build/index.js +19 -0
  7. package/build/lib/appium.js +22 -7
  8. package/build/lib/cli/args.js +13 -15
  9. package/build/lib/cli/npm.js +27 -16
  10. package/build/lib/cli/parser.js +7 -3
  11. package/build/lib/config-file.js +4 -7
  12. package/build/lib/config.js +57 -48
  13. package/build/lib/extension-config.js +1 -1
  14. package/build/lib/main.js +28 -28
  15. package/build/lib/plugin-config.js +2 -2
  16. package/build/lib/plugins.js +4 -2
  17. package/build/lib/schema/appium-config-schema.js +3 -2
  18. package/build/lib/schema/arg-spec.js +5 -3
  19. package/build/lib/schema/cli-args.js +25 -16
  20. package/build/lib/schema/keywords.js +14 -4
  21. package/build/lib/schema/schema.js +86 -9
  22. package/build/lib/utils.js +16 -36
  23. package/build/postinstall.js +90 -0
  24. package/build/test/cli/cli-e2e-specs.js +221 -0
  25. package/build/test/cli/cli-helpers.js +86 -0
  26. package/build/test/cli/cli-specs.js +71 -0
  27. package/build/test/cli/fixtures/test-driver/package.json +27 -0
  28. package/build/test/cli/schema-args-specs.js +48 -0
  29. package/build/test/cli/schema-e2e-specs.js +47 -0
  30. package/build/test/config-e2e-specs.js +112 -0
  31. package/build/test/config-file-e2e-specs.js +191 -0
  32. package/build/test/config-file-specs.js +281 -0
  33. package/build/test/config-specs.js +258 -0
  34. package/build/test/driver-e2e-specs.js +435 -0
  35. package/build/test/driver-specs.js +386 -0
  36. package/build/test/ext-config-io-specs.js +181 -0
  37. package/build/test/extension-config-specs.js +365 -0
  38. package/build/test/fixtures/allow-feat.txt +5 -0
  39. package/build/test/fixtures/caps.json +3 -0
  40. package/build/test/fixtures/config/allow-insecure.txt +3 -0
  41. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +5 -0
  42. package/build/test/fixtures/config/appium.config.bad.json +32 -0
  43. package/build/test/fixtures/config/appium.config.ext-good.json +9 -0
  44. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +10 -0
  45. package/build/test/fixtures/config/appium.config.good.js +40 -0
  46. package/build/test/fixtures/config/appium.config.good.json +33 -0
  47. package/build/test/fixtures/config/appium.config.good.yaml +30 -0
  48. package/build/test/fixtures/config/appium.config.invalid.json +31 -0
  49. package/build/test/fixtures/config/appium.config.security-array.json +5 -0
  50. package/build/test/fixtures/config/appium.config.security-delimited.json +5 -0
  51. package/build/test/fixtures/config/appium.config.security-path.json +5 -0
  52. package/build/test/fixtures/config/driver-fake.config.json +8 -0
  53. package/build/test/fixtures/config/nodeconfig.json +3 -0
  54. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  55. package/build/test/fixtures/default-args.js +35 -0
  56. package/build/test/fixtures/deny-feat.txt +5 -0
  57. package/build/test/fixtures/driver.schema.js +20 -0
  58. package/build/test/fixtures/extensions.yaml +27 -0
  59. package/build/test/fixtures/flattened-schema.js +532 -0
  60. package/build/test/fixtures/plugin.schema.js +20 -0
  61. package/build/test/fixtures/schema-with-extensions.js +28 -0
  62. package/build/test/grid-register-specs.js +74 -0
  63. package/build/test/helpers.js +75 -0
  64. package/build/test/logger-specs.js +76 -0
  65. package/build/test/npm-specs.js +20 -0
  66. package/build/test/parser-specs.js +319 -0
  67. package/build/test/plugin-e2e-specs.js +316 -0
  68. package/build/test/schema/arg-spec-specs.js +70 -0
  69. package/build/test/schema/cli-args-specs.js +408 -0
  70. package/build/test/schema/schema-specs.js +407 -0
  71. package/build/test/utils-specs.js +288 -0
  72. package/index.js +11 -0
  73. package/lib/appium-config.schema.json +2 -1
  74. package/lib/appium.js +51 -8
  75. package/lib/cli/args.js +17 -14
  76. package/lib/cli/npm.js +68 -6
  77. package/lib/cli/parser.js +5 -2
  78. package/lib/config-file.js +9 -12
  79. package/lib/config.js +104 -56
  80. package/lib/extension-config.js +1 -1
  81. package/lib/main.js +94 -40
  82. package/lib/plugin-config.js +1 -1
  83. package/lib/plugins.js +2 -0
  84. package/lib/schema/appium-config-schema.js +1 -0
  85. package/lib/schema/arg-spec.js +13 -3
  86. package/lib/schema/cli-args.js +22 -34
  87. package/lib/schema/keywords.js +20 -4
  88. package/lib/schema/schema.js +150 -24
  89. package/lib/utils.js +28 -29
  90. package/package.json +9 -14
  91. package/types/types.d.ts +5 -0
  92. package/build/lib/cli/argparse-actions.js +0 -104
  93. package/lib/cli/argparse-actions.js +0 -77
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _configFile = require("../lib/config-file");
8
+
9
+ var _schema = require("../lib/schema/schema");
10
+
11
+ var _driverSchema = _interopRequireDefault(require("./fixtures/driver.schema.js"));
12
+
13
+ var _helpers = require("./helpers");
14
+
15
+ describe('config file behavior', function () {
16
+ const GOOD_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.good.json');
17
+ const BAD_NODECONFIG_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.bad-nodeconfig.json');
18
+ const BAD_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.bad.json');
19
+ const INVALID_JSON_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.invalid.json');
20
+ const SECURITY_ARRAY_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.security-array.json');
21
+ const SECURITY_DELIMITED_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.security-delimited.json');
22
+ const SECURITY_PATH_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.security-path.json');
23
+ const UNKNOWN_PROPS_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.ext-unknown-props.json');
24
+ const EXT_PROPS_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.ext-good.json');
25
+ beforeEach(function () {
26
+ (0, _schema.finalizeSchema)();
27
+ });
28
+ afterEach(function () {
29
+ (0, _schema.resetSchema)();
30
+ });
31
+ describe('when provided a path to a config file', function () {
32
+ describe('when the config file is valid per the schema', function () {
33
+ it('should return a valid config object', async function () {
34
+ const result = await (0, _configFile.readConfigFile)(GOOD_FILEPATH);
35
+ result.should.deep.equal({
36
+ config: require(GOOD_FILEPATH),
37
+ filepath: GOOD_FILEPATH,
38
+ errors: []
39
+ });
40
+ });
41
+ describe('server.nodeconfig behavior', function () {
42
+ describe('when a string', function () {
43
+ it('should return errors', async function () {
44
+ const result = await (0, _configFile.readConfigFile)(BAD_NODECONFIG_FILEPATH);
45
+ result.should.have.nested.property('errors[0].instancePath', '/server/nodeconfig');
46
+ });
47
+ });
48
+ describe('when an object', function () {
49
+ it('should return a valid config object', async function () {
50
+ const result = await (0, _configFile.readConfigFile)(GOOD_FILEPATH);
51
+ result.should.have.property('errors').that.is.empty;
52
+ });
53
+ });
54
+ });
55
+ describe('server.allow-insecure behavior', function () {
56
+ describe('when a string path', function () {
57
+ it('should return errors', async function () {
58
+ const result = await (0, _configFile.readConfigFile)(SECURITY_PATH_FILEPATH);
59
+ result.should.have.nested.property('errors[0].instancePath', '/server/allow-insecure');
60
+ });
61
+ });
62
+ describe('when a comma-delimited string', function () {
63
+ it('should return errors', async function () {
64
+ const result = await (0, _configFile.readConfigFile)(SECURITY_DELIMITED_FILEPATH);
65
+ result.should.have.nested.property('errors[0].instancePath', '/server/allow-insecure');
66
+ });
67
+ });
68
+ describe('when an array', function () {
69
+ it('should return a valid config object', async function () {
70
+ const result = await (0, _configFile.readConfigFile)(SECURITY_ARRAY_FILEPATH);
71
+ result.should.deep.equal({
72
+ config: require(SECURITY_ARRAY_FILEPATH),
73
+ filepath: SECURITY_ARRAY_FILEPATH,
74
+ errors: []
75
+ });
76
+ });
77
+ });
78
+ });
79
+ });
80
+ describe('when the config file is invalid per the schema', function () {
81
+ describe('without extensions', function () {
82
+ it('should return an object containing errors', async function () {
83
+ const result = await (0, _configFile.readConfigFile)(BAD_FILEPATH);
84
+ result.should.have.deep.property('config', (0, _configFile.normalizeConfig)(require(BAD_FILEPATH)));
85
+ result.should.have.property('filepath', BAD_FILEPATH);
86
+ result.should.have.deep.property('errors').that.contains.members([{
87
+ instancePath: '',
88
+ schemaPath: '#/additionalProperties',
89
+ keyword: 'additionalProperties',
90
+ params: {
91
+ additionalProperty: 'appium-home'
92
+ },
93
+ message: 'must NOT have additional properties',
94
+ isIdentifierLocation: true
95
+ }, {
96
+ instancePath: '/server/allow-cors',
97
+ schemaPath: '#/properties/server/properties/allow-cors/type',
98
+ keyword: 'type',
99
+ params: {
100
+ type: 'boolean'
101
+ },
102
+ message: 'must be boolean'
103
+ }, {
104
+ instancePath: '/server/allow-insecure',
105
+ schemaPath: '#/properties/server/properties/allow-insecure/type',
106
+ keyword: 'type',
107
+ params: {
108
+ type: 'array'
109
+ },
110
+ message: 'must be array'
111
+ }, {
112
+ instancePath: '/server/callback-port',
113
+ schemaPath: '#/properties/server/properties/callback-port/maximum',
114
+ keyword: 'maximum',
115
+ params: {
116
+ comparison: '<=',
117
+ limit: 65535
118
+ },
119
+ message: 'must be <= 65535'
120
+ }, {
121
+ instancePath: '/server/log-level',
122
+ schemaPath: '#/properties/server/properties/log-level/enum',
123
+ keyword: 'enum',
124
+ params: {
125
+ allowedValues: ['info', 'info:debug', 'info:info', 'info:warn', 'info:error', 'warn', 'warn:debug', 'warn:info', 'warn:warn', 'warn:error', 'error', 'error:debug', 'error:info', 'error:warn', 'error:error', 'debug', 'debug:debug', 'debug:info', 'debug:warn', 'debug:error']
126
+ },
127
+ message: 'must be equal to one of the allowed values'
128
+ }, {
129
+ instancePath: '/server/log-no-colors',
130
+ schemaPath: '#/properties/server/properties/log-no-colors/type',
131
+ keyword: 'type',
132
+ params: {
133
+ type: 'boolean'
134
+ },
135
+ message: 'must be boolean'
136
+ }, {
137
+ instancePath: '/server/port',
138
+ schemaPath: '#/properties/server/properties/port/type',
139
+ keyword: 'type',
140
+ params: {
141
+ type: 'integer'
142
+ },
143
+ message: 'must be integer'
144
+ }]).and.lengthOf(7);
145
+ result.should.have.property('reason').that.is.a.string;
146
+ });
147
+ });
148
+ describe('with extensions', function () {
149
+ let result;
150
+ beforeEach(function () {
151
+ (0, _schema.resetSchema)();
152
+ (0, _schema.registerSchema)('driver', 'fake', _driverSchema.default);
153
+ (0, _schema.finalizeSchema)();
154
+ });
155
+ describe('when provided a config file with unknown properties', function () {
156
+ beforeEach(async function () {
157
+ result = await (0, _configFile.readConfigFile)(UNKNOWN_PROPS_FILEPATH);
158
+ });
159
+ it('should return an object containing errors', function () {
160
+ result.should.have.deep.property('errors', [{
161
+ instancePath: '/server/driver/fake',
162
+ schemaPath: 'driver-fake.json/additionalProperties',
163
+ keyword: 'additionalProperties',
164
+ params: {
165
+ additionalProperty: 'bubb'
166
+ },
167
+ message: 'must NOT have additional properties',
168
+ isIdentifierLocation: true
169
+ }]);
170
+ });
171
+ });
172
+ describe('when provided a config file with valid properties', function () {
173
+ beforeEach(async function () {
174
+ result = await (0, _configFile.readConfigFile)(EXT_PROPS_FILEPATH);
175
+ });
176
+ it('should return an object containing no errors', function () {
177
+ result.should.have.deep.property('errors', []);
178
+ });
179
+ });
180
+ });
181
+ });
182
+ describe('when the config file is invalid JSON', function () {
183
+ it('should reject with a user-friendly error message', async function () {
184
+ await (0, _configFile.readConfigFile)(INVALID_JSON_FILEPATH).should.be.rejectedWith(new RegExp(`${INVALID_JSON_FILEPATH} is invalid`));
185
+ });
186
+ });
187
+ });
188
+ });require('source-map-support').install();
189
+
190
+
191
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvY29uZmlnLWZpbGUtZTJlLXNwZWNzLmpzIl0sIm5hbWVzIjpbImRlc2NyaWJlIiwiR09PRF9GSUxFUEFUSCIsIkJBRF9OT0RFQ09ORklHX0ZJTEVQQVRIIiwiQkFEX0ZJTEVQQVRIIiwiSU5WQUxJRF9KU09OX0ZJTEVQQVRIIiwiU0VDVVJJVFlfQVJSQVlfRklMRVBBVEgiLCJTRUNVUklUWV9ERUxJTUlURURfRklMRVBBVEgiLCJTRUNVUklUWV9QQVRIX0ZJTEVQQVRIIiwiVU5LTk9XTl9QUk9QU19GSUxFUEFUSCIsIkVYVF9QUk9QU19GSUxFUEFUSCIsImJlZm9yZUVhY2giLCJhZnRlckVhY2giLCJpdCIsInJlc3VsdCIsInNob3VsZCIsImRlZXAiLCJlcXVhbCIsImNvbmZpZyIsInJlcXVpcmUiLCJmaWxlcGF0aCIsImVycm9ycyIsImhhdmUiLCJuZXN0ZWQiLCJwcm9wZXJ0eSIsInRoYXQiLCJpcyIsImVtcHR5IiwiY29udGFpbnMiLCJtZW1iZXJzIiwiaW5zdGFuY2VQYXRoIiwic2NoZW1hUGF0aCIsImtleXdvcmQiLCJwYXJhbXMiLCJhZGRpdGlvbmFsUHJvcGVydHkiLCJtZXNzYWdlIiwiaXNJZGVudGlmaWVyTG9jYXRpb24iLCJ0eXBlIiwiY29tcGFyaXNvbiIsImxpbWl0IiwiYWxsb3dlZFZhbHVlcyIsImFuZCIsImxlbmd0aE9mIiwiYSIsInN0cmluZyIsImV4dFNjaGVtYSIsImJlIiwicmVqZWN0ZWRXaXRoIiwiUmVnRXhwIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQUEsUUFBUSxDQUFDLHNCQUFELEVBQXlCLFlBQVk7QUFDM0MsUUFBTUMsYUFBYSxHQUFHLDZCQUFlLFFBQWYsRUFBeUIseUJBQXpCLENBQXRCO0FBQ0EsUUFBTUMsdUJBQXVCLEdBQUcsNkJBQzlCLFFBRDhCLEVBRTlCLG1DQUY4QixDQUFoQztBQUlBLFFBQU1DLFlBQVksR0FBRyw2QkFBZSxRQUFmLEVBQXlCLHdCQUF6QixD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TyxDQUFSO0FBc0NELEtBMUlPLENBQVI7QUE0SUF2QixJQUFBQSxRQUFRLENBQUMsc0NBQUQsRUFBeUMsWUFBWTtBQUMzRFksTUFBQUEsRUFBRSxDQUFDLGtEQUFELEVBQXFELGtCQUFrQjtBQUN2RSxjQUFNLGdDQUFlUixxQkFBZixFQUFzQ1UsTUFBdEMsQ0FBNkMrQixFQUE3QyxDQUFnREMsWUFBaEQsQ0FDSixJQUFJQyxNQUFKLENBQVksR0FBRTNDLHFCQUFzQixhQUFwQyxDQURJLENBQU47QUFHRCxPQUpDLENBQUY7QUFLRCxLQU5PLENBQVI7QUFPRCxHQW5OTyxDQUFSO0FBb05ELENBN1BPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHsgcmVhZENvbmZpZ0ZpbGUsIG5vcm1hbGl6ZUNvbmZpZyB9IGZyb20gJy4uL2xpYi9jb25maWctZmlsZSc7XG5pbXBvcnQgeyBmaW5hbGl6ZVNjaGVtYSwgcmVnaXN0ZXJTY2hlbWEsIHJlc2V0U2NoZW1hIH0gZnJvbSAnLi4vbGliL3NjaGVtYS9zY2hlbWEnO1xuaW1wb3J0IGV4dFNjaGVtYSBmcm9tICcuL2ZpeHR1cmVzL2RyaXZlci5zY2hlbWEuanMnO1xuaW1wb3J0IHsgcmVzb2x2ZUZpeHR1cmUgfSBmcm9tICcuL2hlbHBlcnMnO1xuXG5kZXNjcmliZSgnY29uZmlnIGZpbGUgYmVoYXZpb3InLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IEdPT0RfRklMRVBBVEggPSByZXNvbHZlRml4dHVyZSgnY29uZmlnJywgJ2FwcGl1bS5jb25maWcuZ29vZC5qc29uJyk7XG4gIGNvbnN0IEJBRF9OT0RFQ09ORklHX0ZJTEVQQVRIID0gcmVzb2x2ZUZpeHR1cmUoXG4gICAgJ2NvbmZpZycsXG4gICAgJ2FwcGl1bS5jb25maWcuYmFkLW5vZGVjb25maWcuanNvbicsXG4gICk7XG4gIGNvbnN0IEJBRF9GSUxFUEFUSCA9IHJlc29sdmVGaXh0dXJlKCdjb25maWcnLCAnYXBwaXVtLmNvbmZpZy5iYWQuanNvbicpO1xuICBjb25zdCBJTlZBTElEX0pTT05fRklMRVBBVEggPSByZXNvbHZlRml4dHVyZShcbiAgICAnY29uZmlnJyxcbiAgICAnYXBwaXVtLmNvbmZpZy5pbnZhbGlkLmpzb24nLFxuICApO1xuICBjb25zdCBTRUNVUklUWV9BUlJBWV9GSUxFUEFUSCA9IHJlc29sdmVGaXh0dXJlKFxuICAgICdjb25maWcnLFxuICAgICdhcHBpdW0uY29uZmlnLnNlY3VyaXR5LWFycmF5Lmpzb24nLFxuICApO1xuICBjb25zdCBTRUNVUklUWV9ERUxJTUlURURfRklMRVBBVEggPSByZXNvbHZlRml4dHVyZShcbiAgICAnY29uZmlnJyxcbiAgICAnYXBwaXVtLmNvbmZpZy5zZWN1cml0eS1kZWxpbWl0ZWQuanNvbicsXG4gICk7XG4gIGNvbnN0IFNFQ1VSSVRZX1BBVEhfRklMRVBBVEggPSByZXNvbHZlRml4dHVyZShcbiAgICAnY29uZmlnJyxcbiAgICAnYXBwaXVtLmNvbmZpZy5zZWN1cml0eS1wYXRoLmpzb24nLFxuICApO1xuICBjb25zdCBVTktOT1dOX1BST1BTX0ZJTEVQQVRIID0gcmVzb2x2ZUZpeHR1cmUoXG4gICAgJ2NvbmZpZycsXG4gICAgJ2FwcGl1bS5jb25maWcuZXh0LXVua25vd24tcHJvcHMuanNvbicsXG4gICk7XG4gIGNvbnN0IEVYVF9QUk9QU19GSUxFUEFUSCA9IHJlc29sdmVGaXh0dXJlKFxuICAgICdjb25maWcnLFxuICAgICdhcHBpdW0uY29uZmlnLmV4dC1nb29kLmpzb24nLFxuICApO1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIGZpbmFsaXplU2NoZW1hKCk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRTY2hlbWEoKTtcbiAgfSk7XG5cblxuICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBhIHBhdGggdG8gYSBjb25maWcgZmlsZScsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnd2hlbiB0aGUgY29uZmlnIGZpbGUgaXMgdmFsaWQgcGVyIHRoZSBzY2hlbWEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHZhbGlkIGNvbmZpZyBvYmplY3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRDb25maWdGaWxlKEdPT0RfRklMRVBBVEgpO1xuICAgICAgICByZXN1bHQuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICAgIGNvbmZpZzogcmVxdWlyZShHT09EX0ZJTEVQQVRIKSxcbiAgICAgICAgICBmaWxlcGF0aDogR09PRF9GSUxFUEFUSCxcbiAgICAgICAgICBlcnJvcnM6IFtdLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnc2VydmVyLm5vZGVjb25maWcgYmVoYXZpb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIGEgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGVycm9ycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRDb25maWdGaWxlKEJBRF9OT0RFQ09ORklHX0ZJTEVQQVRIKTtcbiAgICAgICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5uZXN0ZWQucHJvcGVydHkoXG4gICAgICAgICAgICAgICdlcnJvcnNbMF0uaW5zdGFuY2VQYXRoJyxcbiAgICAgICAgICAgICAgJy9zZXJ2ZXIvbm9kZWNvbmZpZycsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnd2hlbiBhbiBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSB2YWxpZCBjb25maWcgb2JqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoR09PRF9GSUxFUEFUSCk7XG4gICAgICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Vycm9ycycpLnRoYXQuaXMuZW1wdHk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdzZXJ2ZXIuYWxsb3ctaW5zZWN1cmUgYmVoYXZpb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIGEgc3RyaW5nIHBhdGgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZXJyb3JzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoU0VDVVJJVFlfUEFUSF9GSUxFUEFUSCk7XG4gICAgICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUubmVzdGVkLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnZXJyb3JzWzBdLmluc3RhbmNlUGF0aCcsXG4gICAgICAgICAgICAgICcvc2VydmVyL2FsbG93LWluc2VjdXJlJyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIGEgY29tbWEtZGVsaW1pdGVkIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBlcnJvcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZShTRUNVUklUWV9ERUxJTUlURURfRklMRVBBVEgpO1xuICAgICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLm5lc3RlZC5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ2Vycm9yc1swXS5pbnN0YW5jZVBhdGgnLFxuICAgICAgICAgICAgICAnL3NlcnZlci9hbGxvdy1pbnNlY3VyZScsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnd2hlbiBhbiBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHZhbGlkIGNvbmZpZyBvYmplY3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZShTRUNVUklUWV9BUlJBWV9GSUxFUEFUSCk7XG4gICAgICAgICAgICByZXN1bHQuc2hvdWxkLmRlZXAuZXF1YWwoe1xuICAgICAgICAgICAgICBjb25maWc6IHJlcXVpcmUoU0VDVVJJVFlfQVJSQVlfRklMRVBBVEgpLFxuICAgICAgICAgICAgICBmaWxlcGF0aDogU0VDVVJJVFlfQVJSQVlfRklMRVBBVEgsXG4gICAgICAgICAgICAgIGVycm9yczogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBjb25maWcgZmlsZSBpcyBpbnZhbGlkIHBlciB0aGUgc2NoZW1hJywgZnVuY3Rpb24gKCkge1xuICAgICAgZGVzY3JpYmUoJ3dpdGhvdXQgZXh0ZW5zaW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgZXJyb3JzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRDb25maWdGaWxlKEJBRF9GSUxFUEFUSCk7XG4gICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLmRlZXAucHJvcGVydHkoJ2NvbmZpZycsIG5vcm1hbGl6ZUNvbmZpZyhyZXF1aXJlKEJBRF9GSUxFUEFUSCkpKTtcbiAgICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZpbGVwYXRoJywgQkFEX0ZJTEVQQVRIKTtcbiAgICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUuZGVlcC5wcm9wZXJ0eSgnZXJyb3JzJykudGhhdC5jb250YWlucy5tZW1iZXJzKFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaW5zdGFuY2VQYXRoOiAnJyxcbiAgICAgICAgICAgICAgc2NoZW1hUGF0aDogJyMvYWRkaXRpb25hbFByb3BlcnRpZXMnLFxuICAgICAgICAgICAgICBrZXl3b3JkOiAnYWRkaXRpb25hbFByb3BlcnRpZXMnLFxuICAgICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICBhZGRpdGlvbmFsUHJvcGVydHk6ICdhcHBpdW0taG9tZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdtdXN0IE5PVCBoYXZlIGFkZGl0aW9uYWwgcHJvcGVydGllcycsXG4gICAgICAgICAgICAgIGlzSWRlbnRpZmllckxvY2F0aW9uOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaW5zdGFuY2VQYXRoOiAnL3NlcnZlci9hbGxvdy1jb3JzJyxcbiAgICAgICAgICAgICAgc2NoZW1hUGF0aDogJyMvcHJvcGVydGllcy9zZXJ2ZXIvcHJvcGVydGllcy9hbGxvdy1jb3JzL3R5cGUnLFxuICAgICAgICAgICAgICBrZXl3b3JkOiAndHlwZScsXG4gICAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ211c3QgYmUgYm9vbGVhbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpbnN0YW5jZVBhdGg6ICcvc2VydmVyL2FsbG93LWluc2VjdXJlJyxcbiAgICAgICAgICAgICAgc2NoZW1hUGF0aDogJyMvcHJvcGVydGllcy9zZXJ2ZXIvcHJvcGVydGllcy9hbGxvdy1pbnNlY3VyZS90eXBlJyxcbiAgICAgICAgICAgICAga2V5d29yZDogJ3R5cGUnLFxuICAgICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnYXJyYXknXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdtdXN0IGJlIGFycmF5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGluc3RhbmNlUGF0aDogJy9zZXJ2ZXIvY2FsbGJhY2stcG9ydCcsXG4gICAgICAgICAgICAgIHNjaGVtYVBhdGg6XG4gICAgICAgICAgICAgICAgJyMvcHJvcGVydGllcy9zZXJ2ZXIvcHJvcGVydGllcy9jYWxsYmFjay1wb3J0L21heGltdW0nLFxuICAgICAgICAgICAgICBrZXl3b3JkOiAnbWF4aW11bScsXG4gICAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAgIGNvbXBhcmlzb246ICc8PScsXG4gICAgICAgICAgICAgICAgbGltaXQ6IDY1NTM1LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBtZXNzYWdlOiAnbXVzdCBiZSA8PSA2NTUzNScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpbnN0YW5jZVBhdGg6ICcvc2VydmVyL2xvZy1sZXZlbCcsXG4gICAgICAgICAgICAgIHNjaGVtYVBhdGg6ICcjL3Byb3BlcnRpZXMvc2VydmVyL3Byb3BlcnRpZXMvbG9nLWxldmVsL2VudW0nLFxuICAgICAgICAgICAgICBrZXl3b3JkOiAnZW51bScsXG4gICAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAgIGFsbG93ZWRWYWx1ZXM6IFtcbiAgICAgICAgICAgICAgICAgICdpbmZvJyxcbiAgICAgICAgICAgICAgICAgICdpbmZvOmRlYnVnJyxcbiAgICAgICAgICAgICAgICAgICdpbmZvOmluZm8nLFxuICAgICAgICAgICAgICAgICAgJ2luZm86d2FybicsXG4gICAgICAgICAgICAgICAgICAnaW5mbzplcnJvcicsXG4gICAgICAgICAgICAgICAgICAnd2FybicsXG4gICAgICAgICAgICAgICAgICAnd2FybjpkZWJ1ZycsXG4gICAgICAgICAgICAgICAgICAnd2FybjppbmZvJyxcbiAgICAgICAgICAgICAgICAgICd3YXJuOndhcm4nLFxuICAgICAgICAgICAgICAgICAgJ3dhcm46ZXJyb3InLFxuICAgICAgICAgICAgICAgICAgJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICdlcnJvcjpkZWJ1ZycsXG4gICAgICAgICAgICAgICAgICAnZXJyb3I6aW5mbycsXG4gICAgICAgICAgICAgICAgICAnZXJyb3I6d2FybicsXG4gICAgICAgICAgICAgICAgICAnZXJyb3I6ZXJyb3InLFxuICAgICAgICAgICAgICAgICAgJ2RlYnVnJyxcbiAgICAgICAgICAgICAgICAgICdkZWJ1ZzpkZWJ1ZycsXG4gICAgICAgICAgICAgICAgICAnZGVidWc6aW5mbycsXG4gICAgICAgICAgICAgICAgICAnZGVidWc6d2FybicsXG4gICAgICAgICAgICAgICAgICAnZGVidWc6ZXJyb3InLFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdtdXN0IGJlIGVxdWFsIHRvIG9uZSBvZiB0aGUgYWxsb3dlZCB2YWx1ZXMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaW5zdGFuY2VQYXRoOiAnL3NlcnZlci9sb2ctbm8tY29sb3JzJyxcbiAgICAgICAgICAgICAgc2NoZW1hUGF0aDogJyMvcHJvcGVydGllcy9zZXJ2ZXIvcHJvcGVydGllcy9sb2ctbm8tY29sb3JzL3R5cGUnLFxuICAgICAgICAgICAgICBrZXl3b3JkOiAndHlwZScsXG4gICAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ211c3QgYmUgYm9vbGVhbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpbnN0YW5jZVBhdGg6ICcvc2VydmVyL3BvcnQnLFxuICAgICAgICAgICAgICBzY2hlbWFQYXRoOiAnIy9wcm9wZXJ0aWVzL3NlcnZlci9wcm9wZXJ0aWVzL3BvcnQvdHlwZScsXG4gICAgICAgICAgICAgIGtleXdvcmQ6ICd0eXBlJyxcbiAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2ludGVnZXInLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBtZXNzYWdlOiAnbXVzdCBiZSBpbnRlZ2VyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSkuYW5kLmxlbmd0aE9mKDcpO1xuXG4gICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWFzb24nKS50aGF0LmlzLmEuc3RyaW5nO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2l0aCBleHRlbnNpb25zJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvKiogQHR5cGUge2ltcG9ydCgnLi4vbGliL2NvbmZpZy1maWxlJykuUmVhZENvbmZpZ0ZpbGVSZXN1bHR9ICovXG4gICAgICAgIGxldCByZXN1bHQ7XG5cbiAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmVzZXRTY2hlbWEoKTtcbiAgICAgICAgICByZWdpc3RlclNjaGVtYSgnZHJpdmVyJywgJ2Zha2UnLCBleHRTY2hlbWEpO1xuICAgICAgICAgIGZpbmFsaXplU2NoZW1hKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGEgY29uZmlnIGZpbGUgd2l0aCB1bmtub3duIHByb3BlcnRpZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZShVTktOT1dOX1BST1BTX0ZJTEVQQVRIKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBvYmplY3QgY29udGFpbmluZyBlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUuZGVlcC5wcm9wZXJ0eSgnZXJyb3JzJywgW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaW5zdGFuY2VQYXRoOiAnL3NlcnZlci9kcml2ZXIvZmFrZScsXG4gICAgICAgICAgICAgICAgc2NoZW1hUGF0aDpcbiAgICAgICAgICAgICAgICAgICdkcml2ZXItZmFrZS5qc29uL2FkZGl0aW9uYWxQcm9wZXJ0aWVzJyxcbiAgICAgICAgICAgICAgICBrZXl3b3JkOiAnYWRkaXRpb25hbFByb3BlcnRpZXMnLFxuICAgICAgICAgICAgICAgIHBhcmFtczoge2FkZGl0aW9uYWxQcm9wZXJ0eTogJ2J1YmInfSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnbXVzdCBOT1QgaGF2ZSBhZGRpdGlvbmFsIHByb3BlcnRpZXMnLFxuICAgICAgICAgICAgICAgIGlzSWRlbnRpZmllckxvY2F0aW9uOiB0cnVlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGEgY29uZmlnIGZpbGUgd2l0aCB2YWxpZCBwcm9wZXJ0aWVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoRVhUX1BST1BTX0ZJTEVQQVRIKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBvYmplY3QgY29udGFpbmluZyBubyBlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUuZGVlcC5wcm9wZXJ0eSgnZXJyb3JzJywgW10pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3doZW4gdGhlIGNvbmZpZyBmaWxlIGlzIGludmFsaWQgSlNPTicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IHdpdGggYSB1c2VyLWZyaWVuZGx5IGVycm9yIG1lc3NhZ2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IHJlYWRDb25maWdGaWxlKElOVkFMSURfSlNPTl9GSUxFUEFUSCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBuZXcgUmVnRXhwKGAke0lOVkFMSURfSlNPTl9GSUxFUEFUSH0gaXMgaW52YWxpZGApLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3QvY29uZmlnLWZpbGUtZTJlLXNwZWNzLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uIn0=
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _fs = _interopRequireDefault(require("fs"));
8
+
9
+ var _sinon = _interopRequireDefault(require("sinon"));
10
+
11
+ var _yaml = _interopRequireDefault(require("yaml"));
12
+
13
+ var schema = _interopRequireWildcard(require("../lib/schema/schema"));
14
+
15
+ var _helpers = require("./helpers");
16
+
17
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
18
+
19
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
20
+
21
+ const expect = chai.expect;
22
+ describe('config-file', function () {
23
+ const GOOD_YAML_CONFIG_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.good.yaml');
24
+ const GOOD_JSON_CONFIG_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.good.json');
25
+ const GOOD_JS_CONFIG_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.good.js');
26
+
27
+ const GOOD_YAML_CONFIG = _yaml.default.parse(_fs.default.readFileSync(GOOD_YAML_CONFIG_FILEPATH, 'utf8'));
28
+
29
+ const GOOD_JSON_CONFIG = require(GOOD_JSON_CONFIG_FILEPATH);
30
+
31
+ const BAD_JSON_CONFIG_FILEPATH = (0, _helpers.resolveFixture)('config', 'appium.config.bad.json');
32
+
33
+ const BAD_JSON_CONFIG = require(BAD_JSON_CONFIG_FILEPATH);
34
+
35
+ let sandbox;
36
+ let readConfigFile;
37
+ let lc;
38
+ let configFileModule;
39
+ let mocks;
40
+ before(function () {
41
+ schema.finalizeSchema();
42
+ });
43
+ beforeEach(function () {
44
+ sandbox = _sinon.default.createSandbox();
45
+ const load = sandbox.stub().resolves({
46
+ config: GOOD_JSON_CONFIG,
47
+ filepath: GOOD_JSON_CONFIG_FILEPATH
48
+ });
49
+ load.withArgs(GOOD_YAML_CONFIG_FILEPATH).resolves({
50
+ config: GOOD_YAML_CONFIG,
51
+ filepath: GOOD_YAML_CONFIG_FILEPATH
52
+ });
53
+ load.withArgs(BAD_JSON_CONFIG_FILEPATH).resolves({
54
+ config: BAD_JSON_CONFIG,
55
+ filepath: BAD_JSON_CONFIG_FILEPATH
56
+ });
57
+ const search = sandbox.stub().resolves({
58
+ config: GOOD_JSON_CONFIG,
59
+ filepath: GOOD_JSON_CONFIG_FILEPATH
60
+ });
61
+ lc = {
62
+ load,
63
+ search
64
+ };
65
+ mocks = {
66
+ lilconfig: {
67
+ lilconfig: sandbox.stub().returns(lc)
68
+ },
69
+ '@sidvind/better-ajv-errors': sandbox.stub().returns('')
70
+ };
71
+ configFileModule = _helpers.rewiremock.proxy(() => require('../lib/config-file'), mocks);
72
+ readConfigFile = configFileModule.readConfigFile;
73
+ sandbox.spy(schema, 'validate');
74
+ });
75
+ afterEach(function () {
76
+ sandbox.restore();
77
+ });
78
+ describe('readConfigFile()', function () {
79
+ let result;
80
+ it('should support yaml', async function () {
81
+ const {
82
+ config
83
+ } = await readConfigFile(GOOD_YAML_CONFIG_FILEPATH);
84
+ expect(config).to.eql(GOOD_JSON_CONFIG);
85
+ expect(schema.validate).to.have.been.calledOnce;
86
+ });
87
+ it('should support json', async function () {
88
+ const {
89
+ config
90
+ } = await readConfigFile(GOOD_JSON_CONFIG_FILEPATH);
91
+ expect(config).to.eql(GOOD_JSON_CONFIG);
92
+ expect(schema.validate).to.have.been.calledOnce;
93
+ });
94
+ it('should support js', async function () {
95
+ const {
96
+ config
97
+ } = await readConfigFile(GOOD_JS_CONFIG_FILEPATH);
98
+ expect(config).to.eql(GOOD_JSON_CONFIG);
99
+ expect(schema.validate).to.have.been.calledOnce;
100
+ });
101
+ describe('when no filepath provided', function () {
102
+ beforeEach(async function () {
103
+ result = await readConfigFile();
104
+ });
105
+ it('should search for a config file', function () {
106
+ expect(lc.search).to.have.been.calledOnce;
107
+ expect(schema.validate).to.have.been.calledOnce;
108
+ });
109
+ it('should not try to load a config file directly', function () {
110
+ expect(lc.load).to.not.have.been.called;
111
+ });
112
+ describe('when no config file is found', function () {
113
+ beforeEach(async function () {
114
+ lc.search.resolves();
115
+ schema.validate.resetHistory();
116
+ result = await readConfigFile();
117
+ });
118
+ it('should resolve with an empty object', function () {
119
+ expect(result).to.be.an('object').that.is.empty;
120
+ expect(schema.validate).not.to.have.been.called;
121
+ });
122
+ });
123
+ describe('when a config file is found', function () {
124
+ describe('when the config file is empty', function () {
125
+ beforeEach(async function () {
126
+ lc.search.resolves({
127
+ isEmpty: true,
128
+ filepath: '/path/to/file.json',
129
+ config: {}
130
+ });
131
+ result = await readConfigFile();
132
+ });
133
+ it('should resolve with an object with an `isEmpty` property', function () {
134
+ expect(result).to.have.property('isEmpty', true);
135
+ });
136
+ });
137
+ describe('when the config file is not empty', function () {
138
+ it('should validate the config against a schema', function () {
139
+ expect(schema.validate).to.have.been.calledOnceWith(GOOD_JSON_CONFIG);
140
+ });
141
+ describe('when the config file is valid', function () {
142
+ beforeEach(async function () {
143
+ result = await readConfigFile();
144
+ });
145
+ it('should resolve with an object having `config` property and empty array of errors', function () {
146
+ expect(result).to.deep.equal({
147
+ config: GOOD_JSON_CONFIG,
148
+ errors: [],
149
+ filepath: GOOD_JSON_CONFIG_FILEPATH
150
+ });
151
+ });
152
+ });
153
+ describe('when the config file is invalid', function () {
154
+ beforeEach(function () {
155
+ lc.search.resolves({
156
+ config: {
157
+ foo: 'bar'
158
+ },
159
+ filepath: '/path/to/file.json'
160
+ });
161
+ });
162
+ beforeEach(async function () {
163
+ result = await readConfigFile();
164
+ });
165
+ it('should resolve with an object having a nonempty array of errors', function () {
166
+ expect(result).to.have.property('errors').that.is.not.empty;
167
+ });
168
+ });
169
+ });
170
+ });
171
+ });
172
+ describe('when filepath provided', function () {
173
+ beforeEach(async function () {
174
+ result = await readConfigFile('appium.json');
175
+ });
176
+ it('should not attempt to find a config file', function () {
177
+ expect(lc.search).to.not.have.been.called;
178
+ });
179
+ it('should try to load a config file directly', function () {
180
+ expect(lc.load).to.have.been.calledOnce;
181
+ });
182
+ describe('when no config file exists at path', function () {
183
+ beforeEach(function () {
184
+ lc.load.rejects(Object.assign(new Error(), {
185
+ code: 'ENOENT'
186
+ }));
187
+ });
188
+ it('should reject with user-friendly message', async function () {
189
+ await expect(readConfigFile('appium.json')).to.be.rejectedWith(/not found at user-provided path/);
190
+ });
191
+ });
192
+ describe('when the config file is invalid JSON', function () {
193
+ beforeEach(function () {
194
+ lc.load.rejects(new SyntaxError());
195
+ });
196
+ it('should reject with user-friendly message', async function () {
197
+ await expect(readConfigFile('appium.json')).to.be.rejectedWith(/Config file at user-provided path appium.json is invalid/);
198
+ });
199
+ });
200
+ describe('when something else is wrong with loading the config file', function () {
201
+ beforeEach(function () {
202
+ lc.load.rejects(new Error('guru meditation'));
203
+ });
204
+ it('should pass error through', async function () {
205
+ await expect(readConfigFile('appium.json')).to.be.rejectedWith(/guru meditation/);
206
+ });
207
+ });
208
+ describe('when a config file is found', function () {
209
+ describe('when the config file is empty', function () {
210
+ beforeEach(async function () {
211
+ lc.search.resolves({
212
+ isEmpty: true,
213
+ filepath: '/path/to/file.json',
214
+ config: {}
215
+ });
216
+ result = await readConfigFile();
217
+ });
218
+ it('should resolve with an object with an `isEmpty` property', function () {
219
+ expect(result).to.have.property('isEmpty', true);
220
+ });
221
+ });
222
+ describe('when the config file is not empty', function () {
223
+ it('should validate the config against a schema', function () {
224
+ expect(schema.validate).to.have.been.calledOnceWith(GOOD_JSON_CONFIG);
225
+ });
226
+ describe('when the config file is valid', function () {
227
+ beforeEach(async function () {
228
+ result = await readConfigFile();
229
+ });
230
+ it('should resolve with an object having `config` property and empty array of errors', function () {
231
+ expect(result).to.deep.equal({
232
+ errors: [],
233
+ config: GOOD_JSON_CONFIG,
234
+ filepath: GOOD_JSON_CONFIG_FILEPATH
235
+ });
236
+ });
237
+ });
238
+ describe('when the config file is invalid', function () {
239
+ beforeEach(async function () {
240
+ result = await readConfigFile(BAD_JSON_CONFIG_FILEPATH);
241
+ });
242
+ it('should resolve with an object having a nonempty array of errors', function () {
243
+ expect(result).to.have.property('errors').that.is.not.empty;
244
+ });
245
+ });
246
+ });
247
+ });
248
+ });
249
+ });
250
+ describe('formatErrors()', function () {
251
+ describe('when provided `errors` as an empty array', function () {
252
+ it('should throw', function () {
253
+ expect(() => configFileModule.formatErrors([])).to.throw(TypeError, 'Array of errors must be non-empty');
254
+ });
255
+ });
256
+ describe('when provided `errors` as `undefined`', function () {
257
+ it('should throw', function () {
258
+ expect(() => configFileModule.formatErrors()).to.throw(TypeError, 'Array of errors must be non-empty');
259
+ });
260
+ });
261
+ describe('when provided `errors` as a non-empty array', function () {
262
+ it('should return a string', function () {
263
+ expect(configFileModule.formatErrors([{}])).to.be.a('string');
264
+ });
265
+ });
266
+ describe('when `opts.json` is a string', function () {
267
+ it('should call `betterAjvErrors()` with option `json: opts.json`', function () {
268
+ configFileModule.formatErrors([{}], {}, {
269
+ json: '{"foo": "bar"}'
270
+ });
271
+ expect(mocks['@sidvind/better-ajv-errors']).to.have.been.calledWith(schema.getSchema(), {}, [{}], {
272
+ format: 'cli',
273
+ json: '{"foo": "bar"}'
274
+ });
275
+ });
276
+ });
277
+ });
278
+ });require('source-map-support').install();
279
+
280
+
281
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvY29uZmlnLWZpbGUtc3BlY3MuanMiXSwibmFtZXMiOlsiZXhwZWN0IiwiY2hhaSIsImRlc2NyaWJlIiwiR09PRF9ZQU1MX0NPTkZJR19GSUxFUEFUSCIsIkdPT0RfSlNPTl9DT05GSUdfRklMRVBBVEgiLCJHT09EX0pTX0NPTkZJR19GSUxFUEFUSCIsIkdPT0RfWUFNTF9DT05GSUciLCJZQU1MIiwicGFyc2UiLCJmcyIsInJlYWRGaWxlU3luYyIsIkdPT0RfSlNPTl9DT05GSUciLCJyZXF1aXJlIiwiQkFEX0pTT05fQ09ORklHX0ZJTEVQQVRIIiwiQkFEX0pTT05fQ09ORklHIiwic2FuZGJveCIsInJlYWRDb25maWdGaWxlIiwibGMiLCJjb25maWdGaWxlTW9kdWxlIiwibW9ja3MiLCJiZWZvcmUiLCJzY2hlbWEiLCJmaW5hbGl6ZVNjaGVtYSIsImJlZm9yZUVhY2giLCJzaW5vbiIsImNyZWF0ZVNhbmRib3giLCJsb2FkIiwic3R1YiIsInJlc29sdmVzIiwiY29uZmlnIiwiZmlsZXBhdGgiLCJ3aXRoQXJncyIsInNlYXJjaCIsImxpbGNvbmZpZyIsInJldHVybnMiLCJyZXdpcmVtb2NrIiwicHJveHkiLCJzcHkiLCJhZnRlckVhY2giLCJyZXN0b3JlIiwicmVzdWx0IiwiaXQiLCJ0byIsImVxbCIsInZhbGlkYXRlIiwiaGF2ZSIsImJlZW4iLCJjYWxsZWRPbmNlIiwibm90IiwiY2FsbGVkIiwicmVzZXRIaXN0b3J5IiwiYmUiLCJhbiIsInRoYXQiLCJpcyIsImVtcHR5IiwiaXNFbXB0eSIsInByb3BlcnR5IiwiY2FsbGVkT25jZVdpdGgiLCJkZWVwIiwiZXF1YWwiLCJlcnJvcnMiLCJmb28iLCJyZWplY3RzIiwiT2JqZWN0IiwiYXNzaWduIiwiRXJyb3IiLCJjb2RlIiwicmVqZWN0ZWRXaXRoIiwiU3ludGF4RXJyb3IiLCJmb3JtYXRFcnJvcnMiLCJ0aHJvdyIsIlR5cGVFcnJvciIsImEiLCJqc29uIiwiY2FsbGVkV2l0aCIsImdldFNjaGVtYSIs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QUFBQSxNQUFNLENBQUNrQixnQkFBZ0IsQ0FBQ29ELFlBQWpCLENBQThCLENBQUMsRUFBRCxDQUE5QixDQUFELENBQU4sQ0FBNEM1QixFQUE1QyxDQUErQ1MsRUFBL0MsQ0FBa0RzQixDQUFsRCxDQUFvRCxRQUFwRDtBQUNELE9BSEMsQ0FBRjtBQUlELEtBTE8sQ0FBUjtBQU9BdkUsSUFBQUEsUUFBUSxDQUFDLDhCQUFELEVBQWlDLFlBQVk7QUFDbkR1QyxNQUFBQSxFQUFFLENBQUMsK0RBQUQsRUFBa0UsWUFBWTtBQUU5RXZCLFFBQUFBLGdCQUFnQixDQUFDb0QsWUFBakIsQ0FBOEIsQ0FBQyxFQUFELENBQTlCLEVBQW9DLEVBQXBDLEVBQXdDO0FBQUNJLFVBQUFBLElBQUksRUFBRTtBQUFQLFNBQXhDO0FBQ0ExRSxRQUFBQSxNQUFNLENBQUNtQixLQUFLLENBQUMsNEJBQUQsQ0FBTixDQUFOLENBQTRDdUIsRUFBNUMsQ0FBK0NHLElBQS9DLENBQW9EQyxJQUFwRCxDQUF5RDZCLFVBQXpELENBQ0V0RCxNQUFNLENBQUN1RCxTQUFQLEVBREYsRUFFRSxFQUZGLEVBR0UsQ0FBQyxFQUFELENBSEYsRUFJRTtBQUFDQyxVQUFBQSxNQUFNLEVBQUUsS0FBVDtBQUFnQkgsVUFBQUEsSUFBSSxFQUFFO0FBQXRCLFNBSkY7QUFNRCxPQVRDLENBQUY7QUFVRCxLQVhPLENBQVI7QUFZRCxHQXZDTyxDQUFSO0FBd0NELENBbldPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgWUFNTCBmcm9tICd5YW1sJztcbmltcG9ydCAqIGFzIHNjaGVtYSBmcm9tICcuLi9saWIvc2NoZW1hL3NjaGVtYSc7XG5pbXBvcnQgeyByZXNvbHZlRml4dHVyZSwgcmV3aXJlbW9jayB9IGZyb20gJy4vaGVscGVycyc7XG5cbmNvbnN0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuXG5kZXNjcmliZSgnY29uZmlnLWZpbGUnLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IEdPT0RfWUFNTF9DT05GSUdfRklMRVBBVEggPSByZXNvbHZlRml4dHVyZShcbiAgICAnY29uZmlnJyxcbiAgICAnYXBwaXVtLmNvbmZpZy5nb29kLnlhbWwnLFxuICApO1xuICBjb25zdCBHT09EX0pTT05fQ09ORklHX0ZJTEVQQVRIID0gcmVzb2x2ZUZpeHR1cmUoXG4gICAgJ2NvbmZpZycsXG4gICAgJ2FwcGl1bS5jb25maWcuZ29vZC5qc29uJyxcbiAgKTtcbiAgY29uc3QgR09PRF9KU19DT05GSUdfRklMRVBBVEggPSByZXNvbHZlRml4dHVyZSgnY29uZmlnJywgJ2FwcGl1bS5jb25maWcuZ29vZC5qcycpO1xuICBjb25zdCBHT09EX1lBTUxfQ09ORklHID0gWUFNTC5wYXJzZShcbiAgICBmcy5yZWFkRmlsZVN5bmMoR09PRF9ZQU1MX0NPTkZJR19GSUxFUEFUSCwgJ3V0ZjgnKSxcbiAgKTtcbiAgY29uc3QgR09PRF9KU09OX0NPTkZJRyA9IHJlcXVpcmUoR09PRF9KU09OX0NPTkZJR19GSUxFUEFUSCk7XG4gIGNvbnN0IEJBRF9KU09OX0NPTkZJR19GSUxFUEFUSCA9IHJlc29sdmVGaXh0dXJlKFxuICAgICdjb25maWcnLFxuICAgICdhcHBpdW0uY29uZmlnLmJhZC5qc29uJyxcbiAgKTtcbiAgY29uc3QgQkFEX0pTT05fQ09ORklHID0gcmVxdWlyZShCQURfSlNPTl9DT05GSUdfRklMRVBBVEgpO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7aW1wb3J0KCdzaW5vbicpLlNpbm9uU2FuZGJveH1cbiAgICovXG4gIGxldCBzYW5kYm94O1xuXG4gIC8qKlxuICAgKiBgcmVhZENvbmZpZ0ZpbGUoKWAgZnJvbSBhbiBpc29sYXRlZCBgY29uZmlnLWZpbGVgIG1vZHVsZVxuICAgKiBAdHlwZSB7dHlwZW9mIGltcG9ydCgnLi4vbGliL2NvbmZpZy1maWxlJykucmVhZENvbmZpZ0ZpbGV9XG4gICAqL1xuICBsZXQgcmVhZENvbmZpZ0ZpbGU7XG4gIC8qKlxuICAgKiBNb2NrIGluc3RhbmNlIG9mIGBsaWxjb25maWdgIGNvbnRhaW5pbmcgc3R1YnMgZm9yXG4gICAqIGBsaWxjb25maWcjc2VhcmNoKClgIGFuZCBgbGlsY29uZmlnI2xvYWRgLlxuICAgKiBOb3QgX2FjdHVhbGx5XyBhIGBTaW5vblN0dWJiZWRJbnN0YW5jZWAsIGJ1dCBkdWNrLXR5cGVkLlxuICAgKiBAdHlwZSB7aW1wb3J0KCdzaW5vbicpLlNpbm9uU3R1YmJlZEluc3RhbmNlPFJldHVyblR5cGU8aW1wb3J0KCdsaWxjb25maWcnKS5saWxjb25maWc+Pn1cbiAgICovXG4gIGxldCBsYztcblxuICAvKipcbiAgICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4uL2xpYi9jb25maWctZmlsZScpfVxuICAgKi9cbiAgbGV0IGNvbmZpZ0ZpbGVNb2R1bGU7XG5cbiAgbGV0IG1vY2tzO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgLy8gZ2VuZXJhbGx5IGNhbGxlZCB2aWEgdGhlIENMSSBwYXJzZXIsIHRoaXMgbmVlZHMgdG8gYmUgZG9uZSBtYW51YWxseSBpbiB0ZXN0cy5cbiAgICAvLyB3ZSBkb24ndCBuZWVkIHRvIGRvIHRoaXMgYmVmb3JlIF9lYWNoXyB0ZXN0LCBiZWNhdXNlIHdlJ3JlIG5vdCBjaGFuZ2luZyB0aGUgc2NoZW1hLlxuICAgIC8vIGlmIHdlIGRpZCBjaGFuZ2UgdGhlIHNjaGVtYSwgdGhpcyB3b3VsZCBuZWVkIHRvIGJlIGluIGBiZWZvcmVFYWNoKClgIGFuZCBgYWZ0ZXJFYWNoKClgXG4gICAgLy8gd291bGQgbmVlZCB0byBjYWxsIGBzY2hlbWEucmVzZXQoKWAuXG4gICAgc2NoZW1hLmZpbmFsaXplU2NoZW1hKCk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICAvLyB3ZSBoYXZlIHRvIG1hbnVhbGx5IHR5cGUgdGhpcyAoYW5kIGBzZWFyY2goKWApIGJlY2F1c2Ugd2UnZCBvbmx5IGdldCB0aGUgcmVhbCB0eXBlXG4gICAgLy8gd2hlbiBzdHViYmluZyBhbiBvYmplY3QgcHJvcDsgZS5nLiwgYHN0dWIobGlsY29uZmlnLCAnbG9hZCcpYFxuICAgIGNvbnN0IGxvYWQgPSAvKiogQHR5cGUge0FzeW5jU2VhcmNoZXJMb2FkU3R1Yn0gKi8gKFxuICAgICAgc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoe1xuICAgICAgICBjb25maWc6IEdPT0RfSlNPTl9DT05GSUcsXG4gICAgICAgIGZpbGVwYXRoOiBHT09EX0pTT05fQ09ORklHX0ZJTEVQQVRILFxuICAgICAgfSlcbiAgICApO1xuICAgIGxvYWQud2l0aEFyZ3MoR09PRF9ZQU1MX0NPTkZJR19GSUxFUEFUSCkucmVzb2x2ZXMoe1xuICAgICAgY29uZmlnOiBHT09EX1lBTUxfQ09ORklHLFxuICAgICAgZmlsZXBhdGg6IEdPT0RfWUFNTF9DT05GSUdfRklMRVBBVEgsXG4gICAgfSk7XG4gICAgbG9hZC53aXRoQXJncyhCQURfSlNPTl9DT05GSUdfRklMRVBBVEgpLnJlc29sdmVzKHtcbiAgICAgIGNvbmZpZzogQkFEX0pTT05fQ09ORklHLFxuICAgICAgZmlsZXBhdGg6IEJBRF9KU09OX0NPTkZJR19GSUxFUEFUSCxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNlYXJjaCA9IC8qKiBAdHlwZSB7QXN5bmNTZWFyY2hlckxvYWRTdHVifSAqLyAoXG4gICAgICBzYW5kYm94LnN0dWIoKS5yZXNvbHZlcyh7XG4gICAgICAgIGNvbmZpZzogR09PRF9KU09OX0NPTkZJRyxcbiAgICAgICAgZmlsZXBhdGg6IEdPT0RfSlNPTl9DT05GSUdfRklMRVBBVEgsXG4gICAgICB9KVxuICAgICk7XG5cbiAgICBsYyA9IHtcbiAgICAgIGxvYWQsXG4gICAgICBzZWFyY2gsXG4gICAgfTtcblxuICAgIG1vY2tzID0ge1xuICAgICAgbGlsY29uZmlnOiB7XG4gICAgICAgIGxpbGNvbmZpZzogc2FuZGJveC5zdHViKCkucmV0dXJucyhsYyksXG4gICAgICB9LFxuICAgICAgJ0BzaWR2aW5kL2JldHRlci1hanYtZXJyb3JzJzogc2FuZGJveC5zdHViKCkucmV0dXJucygnJyksXG4gICAgfTtcblxuICAgIC8vIGxvYWRzIHRoZSBgY29uZmlnLWZpbGVgIG1vZHVsZSB1c2luZyB0aGUgbGlsY29uZmlnIG1vY2suXG4gICAgLy8gd2Ugb25seSBtb2NrIGxpbGNvbmZpZyBiZWNhdXNlIGl0J2Qgb3RoZXJ3aXNlIGJlIGEgcGFpbiBpbiB0aGUgcmVhciB0byB0ZXN0XG4gICAgLy8gc2VhcmNoaW5nIGZvciBjb25maWcgZmlsZXMsIGFuZCBpdCBpbmNyZWFzZXMgdGhlIGxpa2VsaWhvb2QgdGhhdCB3ZSdkIGxvYWQgdGhlIHdyb25nIGZpbGUuXG4gICAgY29uZmlnRmlsZU1vZHVsZSA9IHJld2lyZW1vY2sucHJveHkoKCkgPT4gcmVxdWlyZSgnLi4vbGliL2NvbmZpZy1maWxlJyksIG1vY2tzKTtcbiAgICByZWFkQ29uZmlnRmlsZSA9IGNvbmZpZ0ZpbGVNb2R1bGUucmVhZENvbmZpZ0ZpbGU7XG5cbiAgICAvLyBqdXN0IHdhbnQgdG8gYmUgZXh0cmEtc3VyZSBgdmFsaWRhdGUoKWAgaGFwcGVuc1xuICAgIHNhbmRib3guc3B5KHNjaGVtYSwgJ3ZhbGlkYXRlJyk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdyZWFkQ29uZmlnRmlsZSgpJywgZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoJy4uL2xpYi9jb25maWctZmlsZScpLlJlYWRDb25maWdGaWxlUmVzdWx0fVxuICAgICAqL1xuICAgIGxldCByZXN1bHQ7XG5cbiAgICBpdCgnc2hvdWxkIHN1cHBvcnQgeWFtbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHtjb25maWd9ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoR09PRF9ZQU1MX0NPTkZJR19GSUxFUEFUSCk7XG4gICAgICBleHBlY3QoY29uZmlnKS50by5lcWwoR09PRF9KU09OX0NPTkZJRyk7XG4gICAgICBleHBlY3Qoc2NoZW1hLnZhbGlkYXRlKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VwcG9ydCBqc29uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2NvbmZpZ30gPSBhd2FpdCByZWFkQ29uZmlnRmlsZShHT09EX0pTT05fQ09ORklHX0ZJTEVQQVRIKTtcbiAgICAgIGV4cGVjdChjb25maWcpLnRvLmVxbChHT09EX0pTT05fQ09ORklHKTtcbiAgICAgIGV4cGVjdChzY2hlbWEudmFsaWRhdGUpLnRvLmhhdmUuYmVlbi5jYWxsZWRPbmNlO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdXBwb3J0IGpzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2NvbmZpZ30gPSBhd2FpdCByZWFkQ29uZmlnRmlsZShHT09EX0pTX0NPTkZJR19GSUxFUEFUSCk7XG4gICAgICBleHBlY3QoY29uZmlnKS50by5lcWwoR09PRF9KU09OX0NPTkZJRyk7XG4gICAgICBleHBlY3Qoc2NoZW1hLnZhbGlkYXRlKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aGVuIG5vIGZpbGVwYXRoIHByb3ZpZGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJlc3VsdCA9IGF3YWl0IHJlYWRDb25maWdGaWxlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzZWFyY2ggZm9yIGEgY29uZmlnIGZpbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdChsYy5zZWFyY2gpLnRvLmhhdmUuYmVlbi5jYWxsZWRPbmNlO1xuICAgICAgICBleHBlY3Qoc2NoZW1hLnZhbGlkYXRlKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCB0cnkgdG8gbG9hZCBhIGNvbmZpZyBmaWxlIGRpcmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobGMubG9hZCkudG8ubm90LmhhdmUuYmVlbi5jYWxsZWQ7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gbm8gY29uZmlnIGZpbGUgaXMgZm91bmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxjLnNlYXJjaC5yZXNvbHZlcygpO1xuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KCdzaW5vbicpLlNpbm9uU3BpZWRNZW1iZXI8dHlwZW9mIHNjaGVtYS52YWxpZGF0ZT59ICovKHNjaGVtYS52YWxpZGF0ZSkucmVzZXRIaXN0b3J5KCk7XG4gICAgICAgICAgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZXNvbHZlIHdpdGggYW4gZW1wdHkgb2JqZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmJlLmFuKCdvYmplY3QnKS50aGF0LmlzLmVtcHR5O1xuICAgICAgICAgIGV4cGVjdChzY2hlbWEudmFsaWRhdGUpLm5vdC50by5oYXZlLmJlZW4uY2FsbGVkO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBhIGNvbmZpZyBmaWxlIGlzIGZvdW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnd2hlbiB0aGUgY29uZmlnIGZpbGUgaXMgZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsYy5zZWFyY2gucmVzb2x2ZXMoe1xuICAgICAgICAgICAgICBpc0VtcHR5OiB0cnVlLFxuICAgICAgICAgICAgICBmaWxlcGF0aDogJy9wYXRoL3RvL2ZpbGUuanNvbicsXG4gICAgICAgICAgICAgIGNvbmZpZzoge30sXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSB3aXRoIGFuIG9iamVjdCB3aXRoIGFuIGBpc0VtcHR5YCBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmhhdmUucHJvcGVydHkoJ2lzRW1wdHknLCB0cnVlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGNvbmZpZyBmaWxlIGlzIG5vdCBlbXB0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHRoZSBjb25maWcgYWdhaW5zdCBhIHNjaGVtYScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChzY2hlbWEudmFsaWRhdGUpLnRvLmhhdmUuYmVlbi5jYWxsZWRPbmNlV2l0aChcbiAgICAgICAgICAgICAgR09PRF9KU09OX0NPTkZJRyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBkZXNjcmliZSgnd2hlbiB0aGUgY29uZmlnIGZpbGUgaXMgdmFsaWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgcmVzdWx0ID0gYXdhaXQgcmVhZENvbmZpZ0ZpbGUoKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpdCgnc2hvdWxkIHJlc29sdmUgd2l0aCBhbiBvYmplY3QgaGF2aW5nIGBjb25maWdgIHByb3BlcnR5IGFuZCBlbXB0eSBhcnJheSBvZiBlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmRlZXAuZXF1YWwoe1xuICAgICAgICAgICAgICAgIGNvbmZpZzogR09PRF9KU09OX0NPTkZJRyxcbiAgICAgICAgICAgICAgICBlcnJvcnM6IFtdLFxuICAgICAgICAgICAgICAgIGZpbGVwYXRoOiBHT09EX0pTT05fQ09ORklHX0ZJTEVQQVRILFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGNvbmZpZyBmaWxlIGlzIGludmFsaWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgbGMuc2VhcmNoLnJlc29sdmVzKHtcbiAgICAgICAgICAgICAgICBjb25maWc6IHtmb286ICdiYXInfSxcbiAgICAgICAgICAgICAgICBmaWxlcGF0aDogJy9wYXRoL3RvL2ZpbGUuanNvbicsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSB3aXRoIGFuIG9iamVjdCBoYXZpbmcgYSBub25lbXB0eSBhcnJheSBvZiBlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmhhdmUucHJvcGVydHkoJ2Vycm9ycycpLnRoYXQuaXMubm90LmVtcHR5O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBmaWxlcGF0aCBwcm92aWRlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZSgnYXBwaXVtLmpzb24nKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCBhdHRlbXB0IHRvIGZpbmQgYSBjb25maWcgZmlsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KGxjLnNlYXJjaCkudG8ubm90LmhhdmUuYmVlbi5jYWxsZWQ7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0cnkgdG8gbG9hZCBhIGNvbmZpZyBmaWxlIGRpcmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBleHBlY3QobGMubG9hZCkudG8uaGF2ZS5iZWVuLmNhbGxlZE9uY2U7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gbm8gY29uZmlnIGZpbGUgZXhpc3RzIGF0IHBhdGgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxjLmxvYWQucmVqZWN0cyhPYmplY3QuYXNzaWduKG5ldyBFcnJvcigpLCB7Y29kZTogJ0VOT0VOVCd9KSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IHdpdGggdXNlci1mcmllbmRseSBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChyZWFkQ29uZmlnRmlsZSgnYXBwaXVtLmpzb24nKSkudG8uYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICAgL25vdCBmb3VuZCBhdCB1c2VyLXByb3ZpZGVkIHBhdGgvLFxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBjb25maWcgZmlsZSBpcyBpbnZhbGlkIEpTT04nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxjLmxvYWQucmVqZWN0cyhuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IHdpdGggdXNlci1mcmllbmRseSBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChyZWFkQ29uZmlnRmlsZSgnYXBwaXVtLmpzb24nKSkudG8uYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICAgL0NvbmZpZyBmaWxlIGF0IHVzZXItcHJvdmlkZWQgcGF0aCBhcHBpdW0uanNvbiBpcyBpbnZhbGlkLyxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBzb21ldGhpbmcgZWxzZSBpcyB3cm9uZyB3aXRoIGxvYWRpbmcgdGhlIGNvbmZpZyBmaWxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBsYy5sb2FkLnJlamVjdHMobmV3IEVycm9yKCdndXJ1IG1lZGl0YXRpb24nKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcGFzcyBlcnJvciB0aHJvdWdoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChyZWFkQ29uZmlnRmlsZSgnYXBwaXVtLmpzb24nKSkudG8uYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICAgL2d1cnUgbWVkaXRhdGlvbi8sXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gYSBjb25maWcgZmlsZSBpcyBmb3VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGNvbmZpZyBmaWxlIGlzIGVtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGMuc2VhcmNoLnJlc29sdmVzKHtcbiAgICAgICAgICAgICAgaXNFbXB0eTogdHJ1ZSxcbiAgICAgICAgICAgICAgZmlsZXBhdGg6ICcvcGF0aC90by9maWxlLmpzb24nLFxuICAgICAgICAgICAgICBjb25maWc6IHt9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZSgpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXNvbHZlIHdpdGggYW4gb2JqZWN0IHdpdGggYW4gYGlzRW1wdHlgIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uaGF2ZS5wcm9wZXJ0eSgnaXNFbXB0eScsIHRydWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnd2hlbiB0aGUgY29uZmlnIGZpbGUgaXMgbm90IGVtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgdGhlIGNvbmZpZyBhZ2FpbnN0IGEgc2NoZW1hJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHNjaGVtYS52YWxpZGF0ZSkudG8uaGF2ZS5iZWVuLmNhbGxlZE9uY2VXaXRoKFxuICAgICAgICAgICAgICBHT09EX0pTT05fQ09ORklHLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBjb25maWcgZmlsZSBpcyB2YWxpZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSB3aXRoIGFuIG9iamVjdCBoYXZpbmcgYGNvbmZpZ2AgcHJvcGVydHkgYW5kIGVtcHR5IGFycmF5IG9mIGVycm9ycycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG8uZGVlcC5lcXVhbCh7XG4gICAgICAgICAgICAgICAgZXJyb3JzOiBbXSxcbiAgICAgICAgICAgICAgICBjb25maWc6IEdPT0RfSlNPTl9DT05GSUcsXG4gICAgICAgICAgICAgICAgZmlsZXBhdGg6IEdPT0RfSlNPTl9DT05GSUdfRklMRVBBVEgsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBkZXNjcmliZSgnd2hlbiB0aGUgY29uZmlnIGZpbGUgaXMgaW52YWxpZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXN1bHQgPSBhd2FpdCByZWFkQ29uZmlnRmlsZShCQURfSlNPTl9DT05GSUdfRklMRVBBVEgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSB3aXRoIGFuIG9iamVjdCBoYXZpbmcgYSBub25lbXB0eSBhcnJheSBvZiBlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmhhdmUucHJvcGVydHkoJ2Vycm9ycycpLnRoYXQuaXMubm90LmVtcHR5O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdmb3JtYXRFcnJvcnMoKScsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBgZXJyb3JzYCBhcyBhbiBlbXB0eSBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4cGVjdCgoKSA9PiBjb25maWdGaWxlTW9kdWxlLmZvcm1hdEVycm9ycyhbXSkpLnRvLnRocm93KFxuICAgICAgICAgIFR5cGVFcnJvcixcbiAgICAgICAgICAnQXJyYXkgb2YgZXJyb3JzIG11c3QgYmUgbm9uLWVtcHR5JyxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgYGVycm9yc2AgYXMgYHVuZGVmaW5lZGAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHRocm93JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGV4cGVjdCgoKSA9PiBjb25maWdGaWxlTW9kdWxlLmZvcm1hdEVycm9ycygpKS50by50aHJvdyhcbiAgICAgICAgICBUeXBlRXJyb3IsXG4gICAgICAgICAgJ0FycmF5IG9mIGVycm9ycyBtdXN0IGJlIG5vbi1lbXB0eScsXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGBlcnJvcnNgIGFzIGEgbm9uLWVtcHR5IGFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgZXhwZWN0KGNvbmZpZ0ZpbGVNb2R1bGUuZm9ybWF0RXJyb3JzKFt7fV0pKS50by5iZS5hKCdzdHJpbmcnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3doZW4gYG9wdHMuanNvbmAgaXMgYSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIGNhbGwgYGJldHRlckFqdkVycm9ycygpYCB3aXRoIG9wdGlvbiBganNvbjogb3B0cy5qc29uYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBjb25maWdGaWxlTW9kdWxlLmZvcm1hdEVycm9ycyhbe31dLCB7fSwge2pzb246ICd7XCJmb29cIjogXCJiYXJcIn0nfSk7XG4gICAgICAgIGV4cGVjdChtb2Nrc1snQHNpZHZpbmQvYmV0dGVyLWFqdi1lcnJvcnMnXSkudG8uaGF2ZS5iZWVuLmNhbGxlZFdpdGgoXG4gICAgICAgICAgc2NoZW1hLmdldFNjaGVtYSgpLFxuICAgICAgICAgIHt9LFxuICAgICAgICAgIFt7fV0sXG4gICAgICAgICAge2Zvcm1hdDogJ2NsaScsIGpzb246ICd7XCJmb29cIjogXCJiYXJcIn0nfSxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG4vLyB0aGUgZm9sbG93aW5nIGFyZSBqdXN0IGFsaWFzZXNcblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhanYnKS5FcnJvck9iamVjdH0gRXJyb3JPYmplY3RcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ2FqdicpLlZhbGlkYXRlRnVuY3Rpb259IFZhbGlkYXRlRnVuY3Rpb25cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ3Npbm9uJykuU2lub25TdHViYmVkTWVtYmVyPFJldHVyblR5cGU8aW1wb3J0KCdsaWxjb25maWcnKS5saWxjb25maWc+Wydsb2FkJ10+fSBBc3luY1NlYXJjaGVyTG9hZFN0dWJcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ3Npbm9uJykuU2lub25TdHViYmVkTWVtYmVyPFJldHVyblR5cGU8aW1wb3J0KCdsaWxjb25maWcnKS5saWxjb25maWc+WydzZWFyY2gnXT59IEFzeW5jU2VhcmNoZXJTZWFyY2hTdHViXG4gKi9cbiJdLCJmaWxlIjoidGVzdC9jb25maWctZmlsZS1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9