risei 1.3.4 → 2.0.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.
Files changed (69) hide show
  1. package/README.md +142 -379
  2. package/Read-me reduced.md +294 -0
  3. package/Read-me redux.md +581 -0
  4. package/index.js +5 -5
  5. package/package.json +10 -11
  6. package/system/ASpoofingFixture.js +7 -8
  7. package/system/ATestCaller.js +3 -3
  8. package/system/ATestFinder.js +2 -2
  9. package/system/ATestReporter.js +2 -1
  10. package/system/ATestSource.js +5 -1
  11. package/system/ChosenTestFinder.js +4 -4
  12. package/system/ClassTestGroup.js +2 -2
  13. package/system/LocalCaller.js +5 -5
  14. package/system/{ClassMethodSpoofer.js → MethodSpoofer.js} +54 -48
  15. package/system/MethodTestGroup.js +2 -2
  16. package/system/Moment.js +1 -1
  17. package/system/NameAnalyzer.js +26 -0
  18. package/system/PropertySpoofer.js +156 -0
  19. package/system/Risei.js +5 -5
  20. package/system/SpoofDef.js +260 -0
  21. package/system/TerminalReporter.js +8 -8
  22. package/system/{TestDefinition.js → TestDef.js} +153 -107
  23. package/system/TestFinder.js +3 -3
  24. package/system/TestFrame.js +15 -52
  25. package/system/TestGroup.js +1 -1
  26. package/system/TestResult.js +2 -2
  27. package/system/TestRunner.js +23 -107
  28. package/system/TestStages.js +80 -76
  29. package/system/TestSummary.js +1 -1
  30. package/system/TotalComparer.js +60 -11
  31. package/system/TotalDisplayer.js +33 -12
  32. package/system/TypeAnalyzer.js +41 -79
  33. package/system/TypeIdentifier.js +18 -8
  34. package/system/Types.js +3 -1
  35. package/test-target-objects/ConditionalThrowTarget.js +11 -0
  36. package/test-target-objects/Counter.js +46 -0
  37. package/test-target-objects/DomTarget.js +37 -0
  38. package/test-target-objects/InterSpoofer.js +230 -0
  39. package/test-target-objects/MixedContents.js +33 -0
  40. package/test-target-objects/MutationTarget.js +37 -0
  41. package/test-target-objects/ObjectComposer.js +34 -0
  42. package/test-target-objects/PolySpoofableInner.js +29 -0
  43. package/test-target-objects/PolySpoofableOuter.js +52 -0
  44. package/test-target-objects/PropertiesTarget.js +98 -0
  45. package/test-target-objects/Returner.js +7 -0
  46. package/test-target-objects/Searcher.js +25 -0
  47. package/test-target-objects/Sorter.js +91 -0
  48. package/test-target-objects/Spoofable.js +36 -0
  49. package/test-target-objects/StateTarget.js +34 -0
  50. package/test-target-objects/StaticTarget.js +17 -0
  51. package/test-target-objects/TestableTarget.js +57 -0
  52. package/trial-tests/SelfTests.outward-rt.js +511 -0
  53. package/trial-tests/TopicTests.outward-rt.js +313 -0
  54. package/usage-examples/Gold-bar-example.png +0 -0
  55. package/usage-examples/Title-example.png +0 -0
  56. package/xternal-tests/ASpoofingFixture.tests.js +242 -0
  57. package/xternal-tests/MethodSpoofer.tests.js +130 -0
  58. package/xternal-tests/SpoofDef.tests.js +91 -0
  59. package/xternal-tests/TotalComparer.tests.js +1055 -0
  60. package/xternal-tests/package.json +7 -0
  61. package/system/AComparer.js +0 -9
  62. package/system/ATestFixture.js +0 -44
  63. package/system/ClassPropertySpoofer.js +0 -185
  64. package/system/ObjectMethodSpoofer.js +0 -58
  65. package/system/ObjectPropertySpoofer.js +0 -136
  66. package/system/SpoofDefinition.js +0 -243
  67. package/system/TestFrameChooser.js +0 -54
  68. package/system/TestFrames.js +0 -232
  69. package/system/TotalCopier.js +0 -106
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "mocha-tests",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "dependencies": {
6
+ }
7
+ }
@@ -1,9 +0,0 @@
1
- /**/
2
-
3
- /* Defines operations that a comparer must implement. */
4
-
5
- export class AComparer {
6
- compare(expected, actual) {
7
- throw new Error("Implement compare() on a subclass of AComparer.");
8
- }
9
- }
@@ -1,44 +0,0 @@
1
- /**/
2
-
3
- export class ATestFixture {
4
- // region Private fields
5
-
6
- #name;
7
- #kind;
8
- #fixture;
9
-
10
- // endregion Private fields
11
-
12
- // region Properties
13
-
14
- get name() {
15
- return this.#name;
16
- }
17
-
18
- set name(value) {
19
- this.#name = value;
20
- }
21
-
22
- get kind() {
23
- return this.#kind;
24
- }
25
-
26
- set kind(value) {
27
- this.#kind = value;
28
- }
29
-
30
- get fixture() {
31
- return this.#fixture;
32
- }
33
-
34
- set fixture(value) {
35
- this.#fixture = value;
36
- }
37
-
38
- // endregion Properties
39
-
40
- constructor(name, kind) {
41
- this.#name = name;
42
- this.#kind = kind;
43
- }
44
- }
@@ -1,185 +0,0 @@
1
- /**/
2
-
3
- import { ASpoofingFixture } from "./ASpoofingFixture.js";
4
- import { SpoofDefinition } from "./SpoofDefinition.js";
5
- import { TypeAnalyzer } from "./TypeAnalyzer.js";
6
-
7
- /* &cruft, implement this under test so that anything that can be spoofed
8
- from the class level is spoofed, but not expecting it to get
9
- absolutely everything, and supporting poly-spoofing syntax */
10
- export class ClassPropertySpoofer extends ASpoofingFixture {
11
- /* Algorithm: Forward method spoof() looks at spoof definitions in .plus and applies them
12
- to each class' prototypes after first saving the original member definitions.
13
- Reverse method unspoof() restores each original member definition.
14
- Fundamentally different from what ObjectMethodSpoofer does. */
15
-
16
- // region Private fields
17
-
18
- #spoofsByClass = new Map();
19
- #originalsByClass = new Map();
20
-
21
- // endregion Private fields
22
-
23
- // region Properties
24
-
25
- get spoofsByClass() {
26
- return this.#spoofsByClass;
27
- }
28
-
29
- set spoofsByClass(value) {
30
- this.#spoofsByClass = value;
31
- }
32
-
33
- get originalsByClass() {
34
- return this.#originalsByClass;
35
- }
36
-
37
- set originalsByClass(value) {
38
- this.#originalsByClass = value;
39
- }
40
-
41
- // endregion Properties
42
-
43
- constructor() {
44
- super("ClassPropertySpoofer", "Construction");
45
- }
46
-
47
- /* Spoofs methods of classes as defined in nonce
48
- spoof-tuple definitions in any test.plus. */
49
- spoof(test) {
50
- // Localizing.
51
- let type = test.on;
52
- let spoofNonces = test.plus;
53
-
54
- // Spoofing definitions are always in an array.
55
- if (!Array.isArray(spoofNonces)) {
56
- return;
57
- }
58
-
59
- // Converting to scope object type.
60
- let spoofDefinitions = SpoofDefinition.fromNonceTuples(spoofNonces);
61
-
62
- // Storing spoofing definitions.
63
- this.#retainSpoofsByClass(type, spoofDefinitions);
64
-
65
- // Storing originals for restoring later.
66
- this.#reserveOriginalsByClass();
67
-
68
- // Actually spoofing.
69
- this.#spoofMembersByClass();
70
- }
71
-
72
- // region Dependencies of spoof()
73
-
74
- #retainSpoofsByClass(type, spoofDefinitions) {
75
- // Map of Maps: by type, then by method.
76
- for (let tuple of spoofDefinitions) {
77
- // If no .target, use `type`.
78
- if (!tuple.target) {
79
- tuple.target = type;
80
- }
81
-
82
- let spoofsByTarget = this.#supplyMemberMap(this.#spoofsByClass, tuple.target);
83
-
84
- // A single-method spoof is set for later use.
85
- if (tuple.method) {
86
- spoofsByTarget.set(tuple.method, tuple.output);
87
- continue;
88
- }
89
-
90
- // Two or more method spoofs are set for later use.
91
- if (tuple.output) {
92
- let ofAsPairs = tuple.output;
93
-
94
- for (let pair of ofAsPairs) {
95
- spoofsByTarget.set(pair.of, pair.as);
96
- }
97
-
98
- continue;
99
- }
100
- }
101
- }
102
-
103
- #reserveOriginalsByClass() {
104
- /* Any spoofing of multiple methods on each class has already been
105
- split up into Map elements, so this code can use those naively. */
106
-
107
- let types = this.#spoofsByClass.keys();
108
-
109
- // For each class.
110
- for (let type of types) {
111
- let originalsByTarget = this.#supplyMemberMap(this.#originalsByClass, type);
112
-
113
- let spoofsByTarget = this.#spoofsByClass.get(type);
114
- let names = spoofsByTarget.keys();
115
-
116
- // Saving originals in the Map for later.
117
- for (let name of names) {
118
- let original = type.prototype[name];
119
- originalsByTarget.set(name, original);
120
- }
121
- }
122
- }
123
-
124
- /* Dependency of #retainSpoofsByClass()
125
- and #reserveOriginalsByClass(). */
126
- #supplyMemberMap(source, target) {
127
- let mapForType = source.get(target);
128
-
129
- if (!mapForType) {
130
- mapForType = new Map();
131
- source.set(target, mapForType);
132
- }
133
-
134
- return mapForType;
135
- }
136
-
137
- #spoofMembersByClass() {
138
- /* Any spoofing of multiple methods on each class has already been
139
- split up into Map elements, so this code can use those naively. */
140
-
141
- let types = this.#spoofsByClass.keys();
142
-
143
- // For each class.
144
- for (let type of types) {
145
- let spoofsByTarget = this.#spoofsByClass.get(type);
146
- let names = spoofsByTarget.keys();
147
-
148
- // Actually spoofing, one by one.
149
- for (let name of names) {
150
- let spoofSource = spoofsByTarget.get(name);
151
- let spoof = super.spoofMethod(spoofSource);
152
- type.prototype[name] = spoof;
153
- }
154
- }
155
- }
156
-
157
- // endregion Dependencies of spoof()
158
-
159
- // Spoofed methods on any targeted classes
160
- // are restored to their original forms.
161
- unspoof() {
162
- let types = this.#originalsByClass.keys();
163
-
164
- // For each class.
165
- for (let target of types) {
166
- let prototype = target.prototype;
167
-
168
- let originalsByTarget = this.#originalsByClass.get(target);
169
- let names = originalsByTarget.keys();
170
-
171
- // Actually restoring, one by one.
172
- for (let name of names) {
173
- let original = originalsByTarget.get(name);
174
- target.prototype[name] = original;
175
- }
176
- }
177
- }
178
-
179
- // Removes definitions, useful if this instance is reused,
180
- // or else they might be applied when they shouldn't be.
181
- removeDefinitions() {
182
- this.#spoofsByClass.clear();
183
- this.#originalsByClass.clear();
184
- }
185
- }
@@ -1,58 +0,0 @@
1
- /* */
2
-
3
- import { ASpoofingFixture } from "./ASpoofingFixture.js";
4
- import { SpoofDefinition } from "./SpoofDefinition.js";
5
-
6
- export class ObjectMethodSpoofer extends ASpoofingFixture {
7
- /* Algorithm: Forward method spoof() looks at a test's .with and .in, and replaces entire objects
8
- in each with spoofed object trees, if the originals are spoof definitions.
9
- No reverse unspoofing method is needed, since objects are nonces tossed after tests.
10
- Fundamentally different from much of what ClassMethodSpoofer does. */
11
-
12
- constructor() {
13
- super("ObjectMethodSpoofer", "Construction");
14
- }
15
-
16
- /* Spoofs methods of any objects in test.with and test.in
17
- for which nonce spoof-tuple definitions are provided. */
18
- spoof(test) {
19
- // These array test aspects may contain object-spoof definitions.
20
- let topics = [ test.with, test.in ];
21
-
22
- // Spoofing each array of test-aspect elements.
23
- for (let topic of topics) {
24
- // Replacing whole element with spoof or with unchanged self.
25
- for (let at = 0; at < topic.length; at++) {
26
- let target = topic[at];
27
- topic[at] = this.spoofTarget(target);
28
- }
29
- }
30
- }
31
-
32
- spoofTarget(target) {
33
- // Non-spoof targets are returned unchanged.
34
- if (SpoofDefinition.isNotASpoof(target)) {
35
- return target;
36
- }
37
-
38
- // Spoof definition targets are converted.
39
- let tuple = SpoofDefinition.fromNonceTuple(target);
40
- let ofAsPairs = this.#supplySpoofPairs(tuple);
41
-
42
- // Returning object with one or more spoofed members.
43
- let spoofedTarget = super.spoofObjectTree(ofAsPairs);
44
- return spoofedTarget;
45
- }
46
-
47
- #supplySpoofPairs(tuple) {
48
- // Single-spoof output.
49
- let ofAsPairs = [{ of: tuple.method, as: tuple.output }];
50
-
51
- // Poly-spoof output.
52
- if (!tuple.method) {
53
- ofAsPairs = tuple.output;
54
- }
55
-
56
- return ofAsPairs;
57
- }
58
- }
@@ -1,136 +0,0 @@
1
- /**/
2
-
3
- import { ASpoofingFixture } from "./ASpoofingFixture.js";
4
- import { SpoofDefinition } from "./SpoofDefinition.js";
5
- import { TypeAnalyzer } from "./TypeAnalyzer.js";
6
-
7
- export class ObjectPropertySpoofer extends ASpoofingFixture {
8
- /* Algorithm: Forward method spoof() looks at property spoof definitions in .plus
9
- and first saves the original values, then applies the spoofed ones.
10
- Reverse method unspoof() restores each original property value.
11
- Fundamentally different from what ObjectMethodSpoofer does. */
12
-
13
- // region Private fields
14
-
15
- // Spoofed and original property values.
16
- #settables = [ ];
17
- #unsettables = [ ];
18
-
19
- // endregion Private fields
20
-
21
- // region Properties
22
-
23
- get settables() {
24
- return this.#settables;
25
- }
26
-
27
- set settables(value) {
28
- this.#settables = value;
29
- }
30
-
31
- get unsettables() {
32
- return this.#unsettables;
33
- }
34
-
35
- set unsettables(value) {
36
- this.#unsettables = value;
37
- }
38
-
39
- // endregion Properties
40
-
41
- constructor() {
42
- super("ObjectPropertySpoofer", "Construction");
43
- }
44
-
45
- /* Spoofs properties of test.target as defined in any test.plus. */
46
- spoof(test) {
47
- // Localizing.
48
- let target = test.target;
49
- let spoofNonces = test.plus;
50
-
51
- // Spoofing definitions are always in an array.
52
- if (!Array.isArray(spoofNonces)) {
53
- return;
54
- }
55
-
56
- // Converting to scope object type.
57
- let spoofDefinitions = SpoofDefinition.fromNonceTuples(spoofNonces);
58
-
59
- // Working only with property spoofs.
60
- let propertySpoofs = Array.from(spoofDefinitions)
61
- .filter(spoof => TypeAnalyzer.memberIsProperty(test.on, spoof.of));
62
-
63
- // Storing new values for setting.
64
- this.#settables = propertySpoofs;
65
-
66
- // Storing original values for restoring later.
67
- this.#unsettables = this.#anyOriginalPropertyGetting(target, this.#settables);
68
-
69
- // Actually spoofing with new values.
70
- this.#anyPropertySetting(target, this.#settables);
71
- }
72
-
73
- // Spoofed methods on any targeted classes
74
- // are restored to their original forms.
75
- unspoof() {
76
- this.#anyPropertyUnsetting(this.target, this.#unsettables);
77
- }
78
-
79
- // region Dependencies of spoof()
80
-
81
- #anyOriginalPropertyGetting(target, settables) {
82
- if (!Array.isArray(settables)) {
83
- return;
84
- }
85
-
86
- let unsettables = [ ];
87
-
88
- for (let settable of settables) {
89
- // Not a setter tuple if no settable value.
90
- if (settable.of === undefined) {
91
- continue;
92
- }
93
-
94
- // Retaining original.
95
- let original = target[settable.of];
96
- let unsettable = { of: settable.of, as: original };
97
-
98
- unsettables.push(unsettable);
99
- }
100
-
101
- return unsettables;
102
- }
103
-
104
- // endregion Dependencies of spoof()
105
-
106
- // region Dependencies of unspoof()
107
-
108
- #anyPropertyUnsetting(target, unsettables) {
109
- // Unsetting is the same as setting,
110
- // but with tuples of original values.
111
- return this.#anyPropertySetting(target, unsettables);
112
- }
113
-
114
- // endregion Dependencies of unspoof()
115
-
116
- // region Dependencies of both spoof() and unspoof()
117
-
118
- #anyPropertySetting(target, settables) {
119
- // No properties to set.
120
- if (!Array.isArray(settables)) {
121
- return;
122
- }
123
-
124
- for (let settable of settables) {
125
- // Not a setter tuple if no settable value.
126
- if (settable.of === undefined) {
127
- continue;
128
- }
129
-
130
- // Actually setting property.
131
- target[settable.of] = settable.as;
132
- }
133
- }
134
-
135
- // endregion Dependencies of both spoof() and unspoof()
136
- }
@@ -1,243 +0,0 @@
1
- /**/
2
-
3
- import { TypeAnalyzer } from "./TypeAnalyzer.js";
4
-
5
- /* Defines what is found in a spoof-definition tuple (SDT). Actual SDTs don't need to be instances of this class. */
6
-
7
- export class SpoofDefinition {
8
- // region Static fields
9
-
10
- /* Properties can have short or long names. */
11
- static #longsByShort = new Map([
12
- [ "on", "target" ],
13
- [ "of", "method" ],
14
- [ "as", "output" ],
15
- ]);
16
-
17
- /* Objects with either of these property names aren't
18
- converted to SpoofDefinitions by from-nonce methods. */
19
- static skipNames = [ "not", "skip" ];
20
-
21
- // endregion Static fields
22
-
23
- // region Public fields (long names)
24
-
25
- /* These long names are clearer and match the constructor's parameter names. */
26
-
27
- /* The test-definition field names use the longer, possibly clearer forms.
28
- Equivalent short-name and long-name properties use the same fields. */
29
-
30
- target;
31
- method;
32
- output;
33
-
34
- // endregion Public fields (long names)
35
-
36
- // region Properties
37
-
38
- // region Spoof definition, short names
39
-
40
- /* These short names make JSON-like definitions easier. */
41
-
42
- get on() {
43
- return this.target;
44
- }
45
-
46
- set on(value) {
47
- this.target = value;
48
- }
49
-
50
- get of() {
51
- return this.method;
52
- }
53
-
54
- set of(value) {
55
- this.method = value;
56
- }
57
-
58
- get as() {
59
- return this.output;
60
- }
61
-
62
- set as(value) {
63
- this.output = value;
64
- }
65
-
66
- // endregion Spoof definition, short names
67
-
68
- // region Tuple state
69
-
70
- /* Returns true if instance provides enough to spoof with.
71
- A spoof must define at least either a method to spoof, or an output
72
- containing an array of methods to spoof, with optional outputs.
73
- See .notASpoof() for a contrasting condition. */
74
- isSpoofable() /* passed */ {
75
- let isSpoofable
76
- = this.method !== undefined
77
- || this.output !== undefined;
78
-
79
- return isSpoofable;
80
- }
81
-
82
- isPropertySpoof() /* passed */ {
83
- return TypeAnalyzer.memberIsProperty(this.target, this.method);
84
- }
85
-
86
- // endregion Tuple state
87
-
88
- // endregion Properties
89
-
90
- // region Initing, including constructor()
91
-
92
- /* Constructor can't use param names like `of`, because when not .-prefixed, they are keywords. */
93
-
94
- constructor(target, method, output) /* passed */ {
95
- this.target = target;
96
- this.method = method;
97
- this.output = output;
98
- }
99
-
100
- static fromNonceTuples(nonces) {
101
- // Throughput and output.
102
- let full = new SpoofDefinition();
103
- let output = [];
104
-
105
- // Looping over all.
106
- for (let nonce of nonces) {
107
- // Don't convert non-tuples, but output
108
- // them unchanged for the caller.
109
- if (SpoofDefinition.isNotASpoof(nonce)) {
110
- output.push(nonce);
111
- continue;
112
- }
113
-
114
- // Get latest spoof definition.
115
- let latest = SpoofDefinition.fromNonceTuple(nonce);
116
-
117
- // Restarting spoof definitions when desired.
118
- full = SpoofDefinition.maybeRestartFull(full, latest);
119
-
120
- // Merge any previous
121
- // values into latest.
122
- latest.combineWith(full);
123
-
124
- // Make latest the tuple for
125
- // combining with next time.
126
- full = latest;
127
-
128
- // Add latest only if it's
129
- // ready to use to spoof.
130
- if (latest.isSpoofable) {
131
- output.push(latest);
132
- }
133
- }
134
-
135
- // Back to caller.
136
- return output;
137
- }
138
-
139
- /* Returns true if arg should not be used for spoofing.
140
- See isSpoofable() for a contrasting condition. */
141
- static isNotASpoof(nonce) /* passed */ {
142
- /* Any nonce that is null or undefined is not a SpoofDefinition. */
143
- if (nonce === undefined || nonce === null) {
144
- return true;
145
- }
146
-
147
- /* Any nonce with .not or .skip isn't a SpoofDefinition, even if it has SpoofDefinition properties. */
148
- for (let non of SpoofDefinition.skipNames) {
149
- if (nonce[non] !== undefined) {
150
- return true;
151
- }
152
- }
153
-
154
- /* Any other nonce with any SpoofDefinition properties is a full or partial SpoofDefinition. */
155
- for (let key of SpoofDefinition.#longsByShort.keys()) {
156
- let value = SpoofDefinition.#longsByShort.get(key);
157
-
158
- if (nonce[key] !== undefined) {
159
- return false;
160
- }
161
-
162
- if (nonce[value] !== undefined) {
163
- return false;
164
- }
165
- }
166
-
167
- /* Any nonce without SpoofDefinition properties is not a spoof. */
168
- return true;
169
- }
170
-
171
- static isASpoof(nonce) {
172
- return !this.isNotASpoof(nonce);
173
- }
174
-
175
- static fromNonceTuple(nonce) /* passed */ {
176
- // Empty, since properties can be set
177
- // by either of two nonce naming styles.
178
- let tuple = new SpoofDefinition();
179
-
180
- let shortNames = SpoofDefinition.#longsByShort.keys();
181
-
182
- // Traversing matching pairs of names and applying
183
- // whichever one is present as the tuple property;
184
- // if neither is present, the property is undefined.
185
- for (let shortName of shortNames) {
186
- let longName = SpoofDefinition.#longsByShort.get(shortName);
187
- tuple[shortName] = shortName in nonce ? nonce[shortName] : nonce[longName];
188
- }
189
-
190
- // Back to caller.
191
- return tuple;
192
- }
193
-
194
- // region Dependencies of nonce-tuple initing methods
195
-
196
- static maybeRestartFull(full, latest) /* passed */ {
197
- // When a (new) spoof target is named, return the new
198
- // SpoofDefinition to wipe out all reused spoof values.
199
- if (latest.target !== undefined) {
200
- full = latest;
201
- }
202
-
203
- return full;
204
- }
205
-
206
- combineWith(other) {
207
- let shortNames = SpoofDefinition.#longsByShort.keys();
208
-
209
- for (let shortName of shortNames) {
210
- SpoofDefinition.combineValues(this, other, shortName);
211
- }
212
- }
213
-
214
- static combineValues(self, other, name) /* passed */ {
215
- // Property may still end up undefined.
216
- if (self[name] === undefined) {
217
- self[name] = other[name];
218
- }
219
- }
220
-
221
- // endregion Dependencies of nonce-tuple initing methods
222
-
223
- // endregion Initing, including constructor()
224
-
225
- // region Overrides and dependencies
226
-
227
- toString() /* passed */ {
228
- let text = `SpoofDefinition:{ target:${ this.#asRawOrString(this.target) }, `
229
- + `method:${ this.#asRawOrString(this.method) }, `
230
- + `output:${ this.#asRawOrString(this.output) } }`;
231
- return text;
232
- }
233
-
234
- #asRawOrString(value) /* verified */ {
235
- if (typeof value === "string") {
236
- return `"${ value }"`;
237
- }
238
-
239
- return value;
240
- }
241
-
242
- // endregion Overrides and dependencies
243
- }