@stacks/rendezvous 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,6 +56,7 @@ npx rv <path-to-clarinet-project> <contract-name> <type>
56
56
  - `--path` – The path to use for the replay functionality.
57
57
  - `--runs` – The number of test iterations to use for exercising the contracts.
58
58
  (default: `100`)
59
+ - `--bail` – Stop after the first failure.
59
60
  - `--dial` – The path to a JavaScript file containing custom pre- and
60
61
  post-execution functions (dialers).
61
62
 
package/dist/app.js CHANGED
@@ -94,10 +94,12 @@ const helpMessage = `
94
94
  --seed - The seed to use for the replay functionality.
95
95
  --path - The path to use for the replay functionality.
96
96
  --runs - The runs to use for iterating over the tests. Default: 100.
97
+ --bail - Stop after the first failure.
97
98
  --dial – The path to a JavaScript file containing custom pre- and post-execution functions (dialers).
98
99
  --help - Show the help message.
99
100
  `;
100
- const parseOptionalArgument = (argName) => {
101
+ const parseBooleanOption = (argName) => process.argv.slice(4).includes(`--${argName}`);
102
+ const parseOption = (argName) => {
101
103
  var _a;
102
104
  return (_a = process.argv
103
105
  .find((arg, idx) => idx >= 4 && arg.toLowerCase().startsWith(`--${argName}`))) === null || _a === void 0 ? void 0 : _a.split("=")[1];
@@ -140,24 +142,28 @@ function main() {
140
142
  const manifestPath = (0, path_1.join)(manifestDir, (0, exports.getManifestFileName)(manifestDir, sutContractName));
141
143
  radio.emit("logMessage", `Using manifest path: ${manifestPath}`);
142
144
  radio.emit("logMessage", `Target contract: ${sutContractName}`);
143
- const seed = parseInt(parseOptionalArgument("seed"), 10) || undefined;
145
+ const seed = parseInt(parseOption("seed"), 10) || undefined;
144
146
  if (seed !== undefined) {
145
147
  radio.emit("logMessage", `Using seed: ${seed}`);
146
148
  }
147
- const path = parseOptionalArgument("path") || undefined;
149
+ const path = parseOption("path") || undefined;
148
150
  if (path !== undefined) {
149
151
  radio.emit("logMessage", `Using path: ${path}`);
150
152
  }
151
- const runs = parseInt(parseOptionalArgument("runs"), 10) || undefined;
153
+ const runs = parseInt(parseOption("runs"), 10) || undefined;
152
154
  if (runs !== undefined) {
153
155
  radio.emit("logMessage", `Using runs: ${runs}`);
154
156
  }
157
+ const bail = parseBooleanOption("bail");
158
+ if (bail) {
159
+ radio.emit("logMessage", `Bailing on first failure.`);
160
+ }
155
161
  /**
156
162
  * The path to the dialer file. The dialer file allows the user to register
157
163
  * custom pre and post-execution JavaScript functions to be executed before
158
164
  * and after the public function calls during invariant testing.
159
165
  */
160
- const dialPath = parseOptionalArgument("dial") || undefined;
166
+ const dialPath = parseOption("dial") || undefined;
161
167
  if (dialPath !== undefined) {
162
168
  radio.emit("logMessage", `Using dial path: ${dialPath}`);
163
169
  }
@@ -181,11 +187,11 @@ function main() {
181
187
  // If "test", call `checkProperties` for property-based testing.
182
188
  switch (type) {
183
189
  case "invariant": {
184
- yield (0, invariant_1.checkInvariants)(simnet, sutContractName, rendezvousList, rendezvousAllFunctions, seed, path, runs, dialerRegistry, radio);
190
+ yield (0, invariant_1.checkInvariants)(simnet, sutContractName, rendezvousList, rendezvousAllFunctions, seed, path, runs, bail, dialerRegistry, radio);
185
191
  break;
186
192
  }
187
193
  case "test": {
188
- (0, property_1.checkProperties)(simnet, sutContractName, rendezvousList, rendezvousAllFunctions, seed, path, runs, radio);
194
+ (0, property_1.checkProperties)(simnet, sutContractName, rendezvousList, rendezvousAllFunctions, seed, path, runs, bail, radio);
189
195
  break;
190
196
  }
191
197
  }
package/dist/invariant.js CHANGED
@@ -31,11 +31,13 @@ const dialer_1 = require("./dialer");
31
31
  * @param seed The seed for reproducible invariant testing.
32
32
  * @param path The path for reproducible invariant testing.
33
33
  * @param runs The number of test runs.
34
+ * @param bail Stop execution after the first failure and prevent further
35
+ * shrinking.
34
36
  * @param dialerRegistry The custom dialer registry.
35
37
  * @param radio The custom logging event emitter.
36
38
  * @returns void
37
39
  */
38
- const checkInvariants = (simnet, targetContractName, rendezvousList, rendezvousAllFunctions, seed, path, runs, dialerRegistry, radio) => __awaiter(void 0, void 0, void 0, function* () {
40
+ const checkInvariants = (simnet, targetContractName, rendezvousList, rendezvousAllFunctions, seed, path, runs, bail, dialerRegistry, radio) => __awaiter(void 0, void 0, void 0, function* () {
39
41
  // A map where the keys are the Rendezvous identifiers and the values are
40
42
  // arrays of their SUT (System Under Test) functions. This map will be used
41
43
  // to access the SUT functions for each Rendezvous contract afterwards.
@@ -298,11 +300,12 @@ const checkInvariants = (simnet, targetContractName, rendezvousList, rendezvousA
298
300
  simnet.mineEmptyBurnBlocks(r.burnBlocks);
299
301
  }
300
302
  })), {
301
- verbose: true,
303
+ endOnFailure: bail,
304
+ numRuns: runs,
305
+ path: path,
302
306
  reporter: radioReporter,
303
307
  seed: seed,
304
- path: path,
305
- numRuns: runs,
308
+ verbose: true,
306
309
  });
307
310
  });
308
311
  exports.checkInvariants = checkInvariants;
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacks/rendezvous",
3
- "version": "0.7.3",
3
+ "version": "0.8.0",
4
4
  "description": "Meet your contract's vulnerabilities head-on.",
5
5
  "main": "app.js",
6
6
  "bin": {
package/dist/property.js CHANGED
@@ -21,10 +21,12 @@ const traits_1 = require("./traits");
21
21
  * @param seed The seed for reproducible property-based tests.
22
22
  * @param path The path for reproducible property-based tests.
23
23
  * @param runs The number of test runs.
24
+ * @param bail Stop execution after the first failure and prevent further
25
+ * shrinking.
24
26
  * @param radio The custom logging event emitter.
25
27
  * @returns void
26
28
  */
27
- const checkProperties = (simnet, targetContractName, rendezvousList, rendezvousAllFunctions, seed, path, runs, radio) => {
29
+ const checkProperties = (simnet, targetContractName, rendezvousList, rendezvousAllFunctions, seed, path, runs, bail, radio) => {
28
30
  const testContractId = rendezvousList[0];
29
31
  // A map where the keys are the test contract identifiers and the values are
30
32
  // arrays of their test functions. This map will be used to access the test
@@ -202,11 +204,12 @@ const checkProperties = (simnet, targetContractName, rendezvousList, rendezvousA
202
204
  }
203
205
  }
204
206
  }), {
205
- verbose: true,
207
+ endOnFailure: bail,
208
+ numRuns: runs,
209
+ path: path,
206
210
  reporter: radioReporter,
207
211
  seed: seed,
208
- path: path,
209
- numRuns: runs,
212
+ verbose: true,
210
213
  });
211
214
  };
212
215
  exports.checkProperties = checkProperties;
package/dist/traits.js CHANGED
@@ -17,21 +17,37 @@ const enrichInterfaceWithTraitData = (ast, traitReferenceMap, functionInterfaceL
17
17
  const enriched = new Map();
18
18
  const enrichArgs = (args, functionName, traitReferenceMap, path = []) => {
19
19
  return args.map((arg) => {
20
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
20
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
21
21
  const listNested = !arg.name;
22
22
  const currentPath = listNested ? path : [...path, arg.name];
23
+ // Exit early if the traitReferenceMap does not have anything we are
24
+ // looking for. It means that the current parameter does not have an
25
+ // associated trait reference.
26
+ if (!traitReferenceMap ||
27
+ (!traitReferenceMap[arg.name] &&
28
+ !traitReferenceMap.tuple &&
29
+ !traitReferenceMap.list &&
30
+ !traitReferenceMap.response &&
31
+ !traitReferenceMap.optional &&
32
+ !((_a = traitReferenceMap[arg.name]) === null || _a === void 0 ? void 0 : _a.tuple) &&
33
+ !((_b = traitReferenceMap[arg.name]) === null || _b === void 0 ? void 0 : _b.list) &&
34
+ !((_c = traitReferenceMap[arg.name]) === null || _c === void 0 ? void 0 : _c.response) &&
35
+ !((_d = traitReferenceMap[arg.name]) === null || _d === void 0 ? void 0 : _d.optional) &&
36
+ traitReferenceMap !== "trait_reference")) {
37
+ return arg;
38
+ }
23
39
  if (arg.type && arg.type.tuple) {
24
40
  return Object.assign(Object.assign({}, arg), { type: {
25
41
  tuple: enrichArgs(arg.type.tuple, functionName, listNested
26
42
  ? traitReferenceMap.tuple
27
- : (_a = traitReferenceMap[arg.name]) === null || _a === void 0 ? void 0 : _a.tuple, currentPath),
43
+ : (_e = traitReferenceMap[arg.name]) === null || _e === void 0 ? void 0 : _e.tuple, currentPath),
28
44
  } });
29
45
  }
30
46
  else if (arg.type && arg.type.list) {
31
47
  return Object.assign(Object.assign({}, arg), { type: {
32
48
  list: enrichArgs([arg.type.list], functionName, listNested
33
49
  ? traitReferenceMap.list
34
- : (_b = traitReferenceMap[arg.name]) === null || _b === void 0 ? void 0 : _b.list, arg.type.list.type.tuple
50
+ : (_f = traitReferenceMap[arg.name]) === null || _f === void 0 ? void 0 : _f.list, arg.type.list.type.tuple
35
51
  ? [...currentPath, "tuple"]
36
52
  : arg.type.list.type.response
37
53
  ? [...currentPath, "response"]
@@ -45,13 +61,13 @@ const enrichInterfaceWithTraitData = (ast, traitReferenceMap, functionInterfaceL
45
61
  const errorPath = listNested ? currentPath : [...currentPath, "error"];
46
62
  const okTraitReference = enrichArgs([{ name: "ok", type: arg.type.response.ok }], functionName, {
47
63
  ok: listNested
48
- ? (_c = traitReferenceMap.response) === null || _c === void 0 ? void 0 : _c.ok
49
- : (_e = (_d = traitReferenceMap[arg.name]) === null || _d === void 0 ? void 0 : _d.response) === null || _e === void 0 ? void 0 : _e.ok,
64
+ ? (_g = traitReferenceMap.response) === null || _g === void 0 ? void 0 : _g.ok
65
+ : (_j = (_h = traitReferenceMap[arg.name]) === null || _h === void 0 ? void 0 : _h.response) === null || _j === void 0 ? void 0 : _j.ok,
50
66
  }, okPath)[0];
51
67
  const errorTraitReference = enrichArgs([{ name: "error", type: arg.type.response.error }], functionName, {
52
68
  error: listNested
53
- ? (_f = traitReferenceMap.response) === null || _f === void 0 ? void 0 : _f.error
54
- : (_h = (_g = traitReferenceMap[arg.name]) === null || _g === void 0 ? void 0 : _g.response) === null || _h === void 0 ? void 0 : _h.error,
69
+ ? (_k = traitReferenceMap.response) === null || _k === void 0 ? void 0 : _k.error
70
+ : (_m = (_l = traitReferenceMap[arg.name]) === null || _l === void 0 ? void 0 : _l.response) === null || _m === void 0 ? void 0 : _m.error,
55
71
  }, errorPath)[0];
56
72
  return Object.assign(Object.assign({}, arg), { type: {
57
73
  response: {
@@ -65,7 +81,7 @@ const enrichInterfaceWithTraitData = (ast, traitReferenceMap, functionInterfaceL
65
81
  const optionalTraitReference = enrichArgs([{ name: "optional", type: arg.type.optional }], functionName, {
66
82
  optional: listNested
67
83
  ? traitReferenceMap.optional
68
- : (_j = traitReferenceMap[arg.name]) === null || _j === void 0 ? void 0 : _j.optional,
84
+ : (_o = traitReferenceMap[arg.name]) === null || _o === void 0 ? void 0 : _o.optional,
69
85
  }, optionalPath)[0];
70
86
  return Object.assign(Object.assign({}, arg), { type: {
71
87
  optional: optionalTraitReference.type,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacks/rendezvous",
3
- "version": "0.7.3",
3
+ "version": "0.8.0",
4
4
  "description": "Meet your contract's vulnerabilities head-on.",
5
5
  "main": "app.js",
6
6
  "bin": {