@zohodesk/testinglibrary 0.0.57-n20-experimental → 0.0.58-n20-experimental

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.
@@ -10,6 +10,7 @@ var _fs = _interopRequireDefault(require("fs"));
10
10
  var _logger = require("../../utils/logger");
11
11
  var _timeFormat = require("../../utils/timeFormat");
12
12
  var _DataGeneratorHelper = require("./DataGeneratorHelper");
13
+ var _datePlaceholders = require("../../utils/datePlaceholders");
13
14
  var _DataGeneratorError = require("./DataGeneratorError");
14
15
  var _readConfigFile = require("../playwright/readConfigFile");
15
16
  var _configConstants = _interopRequireDefault(require("../playwright/constants/configConstants"));
@@ -38,8 +39,18 @@ class DataGenerator {
38
39
  } else {
39
40
  generators = await _assertClassBrand(_DataGenerator_brand, this, _getGenerator).call(this, generatorName);
40
41
  }
41
- const resolvedDataTable = await (0, _DataGeneratorHelper.resolveCacheReferences)(dataTable, cacheLayer);
42
- const processedGenerators = await (0, _DataGeneratorHelper.processGenerator)(generators, resolvedDataTable);
42
+
43
+ // Clone to prevent cross-test mutation of the cached generator index.
44
+ const generatorsCopy = generators.map(g => ({
45
+ ...g,
46
+ params: g.params ? {
47
+ ...g.params
48
+ } : undefined
49
+ }));
50
+ (0, _datePlaceholders.resolveDatePlaceholdersInGenerators)(generatorsCopy);
51
+ const dateResolvedTable = (0, _datePlaceholders.resolveDatePlaceholders)(dataTable);
52
+ const resolvedDataTable = await (0, _DataGeneratorHelper.resolveCacheReferences)(dateResolvedTable, cacheLayer);
53
+ const processedGenerators = await (0, _DataGeneratorHelper.processGenerator)(generatorsCopy, resolvedDataTable);
43
54
  const apiPayload = await _assertClassBrand(_DataGenerator_brand, this, _constructApiPayload).call(this, scenarioName, processedGenerators, actorInfo);
44
55
  const featureFlags = process.env.featureflags ? process.env.featureflags : '';
45
56
  const headers = {
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.resolveDatePlaceholders = resolveDatePlaceholders;
7
+ exports.resolveDatePlaceholdersInGenerators = resolveDatePlaceholdersInGenerators;
8
+ exports.resolveDatePlaceholdersInValue = resolveDatePlaceholdersInValue;
9
+ // Matches a full-cell date placeholder: ${TOKEN} or ${TOKEN:N}
10
+ // Uppercase-only token names never clash with TitleCase cache refs.
11
+ const DATE_PLACEHOLDER = /^\$\{([A-Z][A-Z_]*)(?::(\d+))?\}$/;
12
+ function _pad(n, width = 2) {
13
+ return String(n).padStart(width, '0');
14
+ }
15
+
16
+ // UTC day arithmetic — avoids DST boundary issues.
17
+ function _shiftDays(baseDate, days) {
18
+ const d = new Date(baseDate.getTime());
19
+ d.setUTCDate(d.getUTCDate() + days);
20
+ return d;
21
+ }
22
+ function _toISODate(d) {
23
+ return `${d.getUTCFullYear()}-${_pad(d.getUTCMonth() + 1)}-${_pad(d.getUTCDate())}`;
24
+ }
25
+ function _toISODateTime(d) {
26
+ return d.toISOString();
27
+ }
28
+ function _toEpochMs(d) {
29
+ return String(d.getTime());
30
+ }
31
+ function _toUIDate(d) {
32
+ return `${_pad(d.getUTCDate())}/${_pad(d.getUTCMonth() + 1)}/${d.getUTCFullYear()}`;
33
+ }
34
+ const TOKEN_HANDLERS = {
35
+ CURRENT_DATE: {
36
+ requiresN: false,
37
+ resolve: d => _toISODate(d)
38
+ },
39
+ PAST_DATE: {
40
+ requiresN: true,
41
+ resolve: (d, n) => _toISODate(_shiftDays(d, -n))
42
+ },
43
+ FUTURE_DATE: {
44
+ requiresN: true,
45
+ resolve: (d, n) => _toISODate(_shiftDays(d, n))
46
+ },
47
+ CURRENT_DATETIME: {
48
+ requiresN: false,
49
+ resolve: d => _toISODateTime(d)
50
+ },
51
+ PAST_DATETIME: {
52
+ requiresN: true,
53
+ resolve: (d, n) => _toISODateTime(_shiftDays(d, -n))
54
+ },
55
+ FUTURE_DATETIME: {
56
+ requiresN: true,
57
+ resolve: (d, n) => _toISODateTime(_shiftDays(d, n))
58
+ },
59
+ CURRENT_TIMESTAMP: {
60
+ requiresN: false,
61
+ resolve: d => _toEpochMs(d)
62
+ },
63
+ PAST_TIMESTAMP: {
64
+ requiresN: true,
65
+ resolve: (d, n) => _toEpochMs(_shiftDays(d, -n))
66
+ },
67
+ FUTURE_TIMESTAMP: {
68
+ requiresN: true,
69
+ resolve: (d, n) => _toEpochMs(_shiftDays(d, n))
70
+ },
71
+ CURRENT_DATE_UI: {
72
+ requiresN: false,
73
+ resolve: d => _toUIDate(d)
74
+ },
75
+ PAST_DATE_UI: {
76
+ requiresN: true,
77
+ resolve: (d, n) => _toUIDate(_shiftDays(d, -n))
78
+ },
79
+ FUTURE_DATE_UI: {
80
+ requiresN: true,
81
+ resolve: (d, n) => _toUIDate(_shiftDays(d, n))
82
+ }
83
+ };
84
+ const VALID_TOKENS = Object.keys(TOKEN_HANDLERS).join(', ');
85
+
86
+ /**
87
+ * Resolve a single dataTable cell value.
88
+ * Non-strings and strings without "${" are returned as-is.
89
+ * @param {*} value
90
+ * @param {Date} [now]
91
+ * @returns {*}
92
+ */
93
+ function resolveDatePlaceholdersInValue(value, now = new Date()) {
94
+ if (typeof value !== 'string' || !value.includes('${')) {
95
+ return value;
96
+ }
97
+ const match = value.match(DATE_PLACEHOLDER);
98
+ if (!match) {
99
+ return value;
100
+ }
101
+ const [, token, rawN] = match;
102
+ const handler = TOKEN_HANDLERS[token];
103
+ if (!handler) {
104
+ throw new Error(`DataGenerator: Unknown date placeholder token "\${${token}}". Valid tokens are: ${VALID_TOKENS}.`);
105
+ }
106
+ if (handler.requiresN) {
107
+ if (rawN === undefined) {
108
+ throw new Error(`DataGenerator: Placeholder "\${${token}}" requires a day offset N, e.g. "\${${token}:7}".`);
109
+ }
110
+ const n = parseInt(rawN, 10);
111
+ if (!Number.isFinite(n) || n < 1) {
112
+ throw new Error(`DataGenerator: Placeholder "\${${token}:${rawN}}" — N must be a positive integer ≥ 1.`);
113
+ }
114
+ return handler.resolve(now, n);
115
+ } else {
116
+ if (rawN !== undefined) {
117
+ const suggestionToken = token.replace('CURRENT_', 'FUTURE_');
118
+ throw new Error(`DataGenerator: Placeholder "\${${token}}" does not accept an offset. Did you mean "\${${suggestionToken}:${rawN}}"?`);
119
+ }
120
+ return handler.resolve(now);
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Resolve date placeholders in all cells of a dataTable rows array.
126
+ * @param {Object[]} rows
127
+ * @param {Date} [now]
128
+ * @returns {Object[]}
129
+ */
130
+ function resolveDatePlaceholders(rows, now = new Date()) {
131
+ if (!rows || !rows.length) {
132
+ return rows || [];
133
+ }
134
+ return rows.map(row => {
135
+ const resolved = {};
136
+ for (const [key, value] of Object.entries(row)) {
137
+ resolved[key] = resolveDatePlaceholdersInValue(value, now);
138
+ }
139
+ return resolved;
140
+ });
141
+ }
142
+ function _resolveObjectValues(obj, now) {
143
+ for (const key of Object.keys(obj)) {
144
+ const val = obj[key];
145
+ if (typeof val === 'string') {
146
+ obj[key] = resolveDatePlaceholdersInValue(val, now);
147
+ } else if (val !== null && typeof val === 'object') {
148
+ _resolveObjectValues(val, now);
149
+ }
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Resolve date placeholders in static params of a loaded generators array.
155
+ * Mutates in place — call only on a cloned copy of the generator index entry.
156
+ * @param {Object[]} generators
157
+ * @param {Date} [now]
158
+ * @returns {Object[]}
159
+ */
160
+ function resolveDatePlaceholdersInGenerators(generators, now = new Date()) {
161
+ if (!generators || !generators.length) {
162
+ return generators || [];
163
+ }
164
+ for (const gen of generators) {
165
+ if (gen.params && typeof gen.params === 'object') {
166
+ _resolveObjectValues(gen.params, now);
167
+ }
168
+ }
169
+ return generators;
170
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/testinglibrary",
3
- "version": "0.0.57-n20-experimental",
3
+ "version": "0.0.58-n20-experimental",
4
4
  "main": "./build/index.js",
5
5
  "scripts": {
6
6
  "postinstall": "node bin/postinstall.js",