@griffin-app/griffin-ts 0.1.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/ASSERTIONS_QUICK_REF.md +161 -0
- package/README.md +297 -0
- package/dist/assertions.d.ts +136 -0
- package/dist/assertions.d.ts.map +1 -0
- package/dist/assertions.js +230 -0
- package/dist/assertions.js.map +1 -0
- package/dist/builder.d.ts +168 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +165 -0
- package/dist/builder.js.map +1 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +6 -0
- package/dist/constants.js.map +1 -0
- package/dist/example-sequential.d.ts +11 -0
- package/dist/example-sequential.d.ts.map +1 -0
- package/dist/example-sequential.js +160 -0
- package/dist/example-sequential.js.map +1 -0
- package/dist/example.d.ts +9 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/example.js +36 -0
- package/dist/example.js.map +1 -0
- package/dist/frequency.d.ts +15 -0
- package/dist/frequency.d.ts.map +1 -0
- package/dist/frequency.js +34 -0
- package/dist/frequency.js.map +1 -0
- package/dist/http-methods.d.ts +6 -0
- package/dist/http-methods.d.ts.map +1 -0
- package/dist/http-methods.js +9 -0
- package/dist/http-methods.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/response-formats.d.ts +4 -0
- package/dist/response-formats.d.ts.map +1 -0
- package/dist/response-formats.js +7 -0
- package/dist/response-formats.js.map +1 -0
- package/dist/schema-exports.d.ts +6 -0
- package/dist/schema-exports.d.ts.map +1 -0
- package/dist/schema-exports.js +43 -0
- package/dist/schema-exports.js.map +1 -0
- package/dist/schema.d.ts +311 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +214 -0
- package/dist/schema.js.map +1 -0
- package/dist/secrets.d.ts +56 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +74 -0
- package/dist/secrets.js.map +1 -0
- package/dist/sequential-builder.d.ts +127 -0
- package/dist/sequential-builder.d.ts.map +1 -0
- package/dist/sequential-builder.js +128 -0
- package/dist/sequential-builder.js.map +1 -0
- package/dist/shared.d.ts +8 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +36 -0
- package/dist/shared.js.map +1 -0
- package/dist/target.d.ts +33 -0
- package/dist/target.d.ts.map +1 -0
- package/dist/target.js +53 -0
- package/dist/target.js.map +1 -0
- package/dist/type-exports.d.ts +6 -0
- package/dist/type-exports.d.ts.map +1 -0
- package/dist/type-exports.js +7 -0
- package/dist/type-exports.js.map +1 -0
- package/dist/wait.d.ts +9 -0
- package/dist/wait.d.ts.map +1 -0
- package/dist/wait.js +8 -0
- package/dist/wait.js.map +1 -0
- package/package.json +43 -0
- package/src/assertions.ts +327 -0
- package/src/builder.ts +336 -0
- package/src/constants.ts +5 -0
- package/src/example-sequential.ts +191 -0
- package/src/example.ts +55 -0
- package/src/frequency.ts +38 -0
- package/src/http-methods.ts +5 -0
- package/src/index.ts +70 -0
- package/src/response-formats.ts +3 -0
- package/src/schema-exports.ts +43 -0
- package/src/schema.ts +289 -0
- package/src/secrets.ts +112 -0
- package/src/sequential-builder.ts +254 -0
- package/src/shared.ts +46 -0
- package/src/target.ts +55 -0
- package/src/type-exports.ts +20 -0
- package/src/wait.ts +4 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rich assertion DSL for constructing type-safe test assertions with JSONPath support.
|
|
4
|
+
*
|
|
5
|
+
* This module provides:
|
|
6
|
+
* - StateProxy: Tracks node access patterns and converts them to JSONPath
|
|
7
|
+
* - Assert: Builder for creating assertions with fluent API
|
|
8
|
+
* - Support for unary and binary predicates with negation
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.AssertBuilder = exports.BinaryPredicateOperator = exports.UnaryPredicate = void 0;
|
|
12
|
+
exports.createStateProxy = createStateProxy;
|
|
13
|
+
exports.Assert = Assert;
|
|
14
|
+
/**
|
|
15
|
+
* Unary predicates that check a property without comparing to a value
|
|
16
|
+
*/
|
|
17
|
+
var UnaryPredicate;
|
|
18
|
+
(function (UnaryPredicate) {
|
|
19
|
+
UnaryPredicate["IS_NULL"] = "IS_NULL";
|
|
20
|
+
UnaryPredicate["IS_NOT_NULL"] = "IS_NOT_NULL";
|
|
21
|
+
UnaryPredicate["IS_TRUE"] = "IS_TRUE";
|
|
22
|
+
UnaryPredicate["IS_FALSE"] = "IS_FALSE";
|
|
23
|
+
UnaryPredicate["IS_EMPTY"] = "IS_EMPTY";
|
|
24
|
+
UnaryPredicate["IS_NOT_EMPTY"] = "IS_NOT_EMPTY";
|
|
25
|
+
})(UnaryPredicate || (exports.UnaryPredicate = UnaryPredicate = {}));
|
|
26
|
+
/**
|
|
27
|
+
* Binary predicate operators that compare against an expected value
|
|
28
|
+
*/
|
|
29
|
+
var BinaryPredicateOperator;
|
|
30
|
+
(function (BinaryPredicateOperator) {
|
|
31
|
+
BinaryPredicateOperator["EQUAL"] = "EQUAL";
|
|
32
|
+
BinaryPredicateOperator["NOT_EQUAL"] = "NOT_EQUAL";
|
|
33
|
+
BinaryPredicateOperator["GREATER_THAN"] = "GREATER_THAN";
|
|
34
|
+
BinaryPredicateOperator["LESS_THAN"] = "LESS_THAN";
|
|
35
|
+
BinaryPredicateOperator["GREATER_THAN_OR_EQUAL"] = "GREATER_THAN_OR_EQUAL";
|
|
36
|
+
BinaryPredicateOperator["LESS_THAN_OR_EQUAL"] = "LESS_THAN_OR_EQUAL";
|
|
37
|
+
BinaryPredicateOperator["CONTAINS"] = "CONTAINS";
|
|
38
|
+
BinaryPredicateOperator["NOT_CONTAINS"] = "NOT_CONTAINS";
|
|
39
|
+
BinaryPredicateOperator["STARTS_WITH"] = "STARTS_WITH";
|
|
40
|
+
BinaryPredicateOperator["NOT_STARTS_WITH"] = "NOT_STARTS_WITH";
|
|
41
|
+
BinaryPredicateOperator["ENDS_WITH"] = "ENDS_WITH";
|
|
42
|
+
BinaryPredicateOperator["NOT_ENDS_WITH"] = "NOT_ENDS_WITH";
|
|
43
|
+
})(BinaryPredicateOperator || (exports.BinaryPredicateOperator = BinaryPredicateOperator = {}));
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// State Proxy
|
|
46
|
+
// ============================================================================
|
|
47
|
+
/**
|
|
48
|
+
* Symbol used to store path metadata in proxy objects
|
|
49
|
+
*/
|
|
50
|
+
const PATH_SYMBOL = Symbol("__path__");
|
|
51
|
+
/**
|
|
52
|
+
* Creates a nested proxy that accumulates path segments
|
|
53
|
+
*/
|
|
54
|
+
function createNestedProxy(descriptor) {
|
|
55
|
+
return new Proxy({}, {
|
|
56
|
+
get(_, prop) {
|
|
57
|
+
if (prop === PATH_SYMBOL) {
|
|
58
|
+
return descriptor;
|
|
59
|
+
}
|
|
60
|
+
if (prop === "at") {
|
|
61
|
+
return (index) => {
|
|
62
|
+
return createNestedProxy({
|
|
63
|
+
...descriptor,
|
|
64
|
+
path: [...descriptor.path, String(index)],
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// Accumulate string property access
|
|
69
|
+
return createNestedProxy({
|
|
70
|
+
...descriptor,
|
|
71
|
+
path: [...descriptor.path, String(prop)],
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Creates a proxy for a node result with body, headers, and status accessors
|
|
78
|
+
*/
|
|
79
|
+
function createNodeResultProxy(nodeId) {
|
|
80
|
+
return {
|
|
81
|
+
body: createNestedProxy({ nodeId, accessor: "body", path: [] }),
|
|
82
|
+
headers: createNestedProxy({ nodeId, accessor: "headers", path: [] }),
|
|
83
|
+
status: createNestedProxy({ nodeId, accessor: "status", path: [] }),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates a state proxy for the given node names
|
|
88
|
+
*/
|
|
89
|
+
function createStateProxy(nodeNames) {
|
|
90
|
+
const proxy = new Proxy({}, {
|
|
91
|
+
get(_, nodeName) {
|
|
92
|
+
if (typeof nodeName === "symbol") {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
return createNodeResultProxy(nodeName);
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
return proxy;
|
|
99
|
+
}
|
|
100
|
+
// ============================================================================
|
|
101
|
+
// Assert Builder
|
|
102
|
+
// ============================================================================
|
|
103
|
+
class AssertBuilder {
|
|
104
|
+
descriptor;
|
|
105
|
+
negated = false;
|
|
106
|
+
constructor(descriptor) {
|
|
107
|
+
this.descriptor = descriptor;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Negation modifier - flips the meaning of the subsequent predicate
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* Assert(state["node"].body["id"]).not.isNull() // IS_NOT_NULL
|
|
114
|
+
* Assert(state["node"].body["name"]).not.equals("") // NOT_EQUAL
|
|
115
|
+
*/
|
|
116
|
+
get not() {
|
|
117
|
+
const negatedBuilder = new AssertBuilder(this.descriptor);
|
|
118
|
+
negatedBuilder.negated = !this.negated;
|
|
119
|
+
return negatedBuilder;
|
|
120
|
+
}
|
|
121
|
+
// Unary predicates
|
|
122
|
+
isNull() {
|
|
123
|
+
return this.createAssertion(this.negated ? UnaryPredicate.IS_NOT_NULL : UnaryPredicate.IS_NULL);
|
|
124
|
+
}
|
|
125
|
+
isDefined() {
|
|
126
|
+
return this.createAssertion(this.negated ? UnaryPredicate.IS_NULL : UnaryPredicate.IS_NOT_NULL);
|
|
127
|
+
}
|
|
128
|
+
isTrue() {
|
|
129
|
+
return this.createAssertion(this.negated ? UnaryPredicate.IS_FALSE : UnaryPredicate.IS_TRUE);
|
|
130
|
+
}
|
|
131
|
+
isFalse() {
|
|
132
|
+
return this.createAssertion(this.negated ? UnaryPredicate.IS_TRUE : UnaryPredicate.IS_FALSE);
|
|
133
|
+
}
|
|
134
|
+
isEmpty() {
|
|
135
|
+
return this.createAssertion(this.negated ? UnaryPredicate.IS_NOT_EMPTY : UnaryPredicate.IS_EMPTY);
|
|
136
|
+
}
|
|
137
|
+
// Binary predicates
|
|
138
|
+
equals(expected) {
|
|
139
|
+
return this.createAssertion({
|
|
140
|
+
operator: this.negated
|
|
141
|
+
? BinaryPredicateOperator.NOT_EQUAL
|
|
142
|
+
: BinaryPredicateOperator.EQUAL,
|
|
143
|
+
expected,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
greaterThan(expected) {
|
|
147
|
+
return this.createAssertion({
|
|
148
|
+
operator: this.negated
|
|
149
|
+
? BinaryPredicateOperator.LESS_THAN_OR_EQUAL
|
|
150
|
+
: BinaryPredicateOperator.GREATER_THAN,
|
|
151
|
+
expected,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
lessThan(expected) {
|
|
155
|
+
return this.createAssertion({
|
|
156
|
+
operator: this.negated
|
|
157
|
+
? BinaryPredicateOperator.GREATER_THAN_OR_EQUAL
|
|
158
|
+
: BinaryPredicateOperator.LESS_THAN,
|
|
159
|
+
expected,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
greaterThanOrEqual(expected) {
|
|
163
|
+
return this.createAssertion({
|
|
164
|
+
operator: this.negated
|
|
165
|
+
? BinaryPredicateOperator.LESS_THAN
|
|
166
|
+
: BinaryPredicateOperator.GREATER_THAN_OR_EQUAL,
|
|
167
|
+
expected,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
lessThanOrEqual(expected) {
|
|
171
|
+
return this.createAssertion({
|
|
172
|
+
operator: this.negated
|
|
173
|
+
? BinaryPredicateOperator.GREATER_THAN
|
|
174
|
+
: BinaryPredicateOperator.LESS_THAN_OR_EQUAL,
|
|
175
|
+
expected,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
contains(expected) {
|
|
179
|
+
return this.createAssertion({
|
|
180
|
+
operator: this.negated
|
|
181
|
+
? BinaryPredicateOperator.NOT_CONTAINS
|
|
182
|
+
: BinaryPredicateOperator.CONTAINS,
|
|
183
|
+
expected,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
startsWith(expected) {
|
|
187
|
+
return this.createAssertion({
|
|
188
|
+
operator: this.negated
|
|
189
|
+
? BinaryPredicateOperator.NOT_STARTS_WITH
|
|
190
|
+
: BinaryPredicateOperator.STARTS_WITH,
|
|
191
|
+
expected,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
endsWith(expected) {
|
|
195
|
+
return this.createAssertion({
|
|
196
|
+
operator: this.negated
|
|
197
|
+
? BinaryPredicateOperator.NOT_ENDS_WITH
|
|
198
|
+
: BinaryPredicateOperator.ENDS_WITH,
|
|
199
|
+
expected,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
createAssertion(predicate) {
|
|
203
|
+
return {
|
|
204
|
+
nodeId: this.descriptor.nodeId,
|
|
205
|
+
accessor: this.descriptor.accessor,
|
|
206
|
+
path: this.descriptor.path,
|
|
207
|
+
predicate,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
exports.AssertBuilder = AssertBuilder;
|
|
212
|
+
/**
|
|
213
|
+
* Creates an assertion builder from a state proxy reference
|
|
214
|
+
*
|
|
215
|
+
* @param proxyRef - A reference obtained from the state proxy (e.g., state["node"].body["id"])
|
|
216
|
+
* @returns An AssertBuilder for constructing the assertion
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* Assert(state["create_user"].body["data"]["id"]).not.isNull()
|
|
220
|
+
* Assert(state["create_user"].status).equals(201)
|
|
221
|
+
* Assert(state["create_user"].headers["content-type"]).contains("application/json")
|
|
222
|
+
*/
|
|
223
|
+
function Assert(proxyRef) {
|
|
224
|
+
const descriptor = proxyRef[PATH_SYMBOL];
|
|
225
|
+
if (!descriptor) {
|
|
226
|
+
throw new Error("Assert() must be called with a reference from the state proxy");
|
|
227
|
+
}
|
|
228
|
+
return new AssertBuilder(descriptor);
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=assertions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { TestPlanV1, Node, Frequency, Endpoint, Wait, Assertions, JSONAssertion } from "./schema.js";
|
|
2
|
+
import { type START as StartType, type END as EndType } from "./constants";
|
|
3
|
+
/**
|
|
4
|
+
* A node definition without the id field.
|
|
5
|
+
* The id is provided separately to addNode for cleaner separation of concerns.
|
|
6
|
+
*/
|
|
7
|
+
export type NodeWithoutId = Omit<Node, "id">;
|
|
8
|
+
/**
|
|
9
|
+
* TestBuilder provides a type-safe DSL for constructing test plans with compile-time graph validation.
|
|
10
|
+
*
|
|
11
|
+
* Type parameters track the state of the graph during construction:
|
|
12
|
+
* @template NodeName - Union of all registered node names
|
|
13
|
+
* @template HasOutput - Union of nodes that have outgoing edges
|
|
14
|
+
* @template HasInput - Union of nodes that have incoming edges
|
|
15
|
+
*/
|
|
16
|
+
export interface TestBuilder<NodeName extends string = never, HasOutput extends string = never, HasInput extends string = never> {
|
|
17
|
+
/**
|
|
18
|
+
* Adds a node to the test graph.
|
|
19
|
+
*
|
|
20
|
+
* @param name - Unique identifier for this node in the graph
|
|
21
|
+
* @param node - Node definition (Endpoint, WaitNode, Assertion)
|
|
22
|
+
* @returns Updated builder with the node registered in NodeName
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* builder.addNode("health", Endpoint({ method: GET, path: "/health", response_format: JSON }))
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
addNode<Name extends string>(name: Name, node: NodeWithoutId): TestBuilder<NodeName | Name, HasOutput, HasInput>;
|
|
30
|
+
/**
|
|
31
|
+
* Adds a directed edge between two nodes in the graph.
|
|
32
|
+
*
|
|
33
|
+
* Compile-time constraints:
|
|
34
|
+
* - `from` must be START or a node that doesn't already have an outgoing edge
|
|
35
|
+
* - `to` must be END or a node that isn't the same as `from`
|
|
36
|
+
* - Both nodes must exist (be registered via addNode)
|
|
37
|
+
*
|
|
38
|
+
* @param from - Source node name or START constant
|
|
39
|
+
* @param to - Target node name or END constant
|
|
40
|
+
* @returns Updated builder with edge tracking updated
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* builder
|
|
45
|
+
* .addEdge(START, "health")
|
|
46
|
+
* .addEdge("health", "wait")
|
|
47
|
+
* .addEdge("wait", END)
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
addEdge<From extends StartType | Exclude<NodeName, HasOutput>, To extends EndType | Exclude<NodeName, From>>(from: From, to: To): TestBuilder<NodeName, From extends StartType ? HasOutput : HasOutput | From, To extends EndType ? HasInput : HasInput | To>;
|
|
51
|
+
/**
|
|
52
|
+
* Builds the final test plan.
|
|
53
|
+
*
|
|
54
|
+
* This method is only callable when all graph constraints are satisfied:
|
|
55
|
+
* - All nodes must have at least one outgoing edge
|
|
56
|
+
* - All nodes must have at least one incoming edge
|
|
57
|
+
*
|
|
58
|
+
* If constraints aren't met, the return type becomes `never`, causing a compile error.
|
|
59
|
+
*/
|
|
60
|
+
build: [Exclude<NodeName, HasOutput>] extends [never] ? [Exclude<NodeName, HasInput>] extends [never] ? () => TestPlanV1 : {
|
|
61
|
+
error: "Some nodes have no incoming edges";
|
|
62
|
+
unconnected: Exclude<NodeName, HasInput>;
|
|
63
|
+
} : {
|
|
64
|
+
error: "Some nodes have no outgoing edges";
|
|
65
|
+
unconnected: Exclude<NodeName, HasOutput>;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Creates a new test builder for constructing a test plan.
|
|
70
|
+
*
|
|
71
|
+
* @param config - Configuration for the test plan
|
|
72
|
+
* @param config.name - Name of the test
|
|
73
|
+
* @param config.frequency - Optional frequency for scheduled execution
|
|
74
|
+
* @param config.locations - Optional array of location identifiers where this test should run
|
|
75
|
+
* @returns A new TestBuilder instance
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const plan = createGraphBuilder({
|
|
80
|
+
* name: "health-check",
|
|
81
|
+
* frequency: Frequency.every(5).minute(),
|
|
82
|
+
* locations: ["us-east-1", "eu-west-1"]
|
|
83
|
+
* })
|
|
84
|
+
* .addNode("health", Endpoint({ method: GET, path: "/health", response_format: JSON }))
|
|
85
|
+
* .addEdge(START, "health")
|
|
86
|
+
* .addEdge("health", END)
|
|
87
|
+
* .build();
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function createGraphBuilder(config: {
|
|
91
|
+
name: string;
|
|
92
|
+
frequency?: Frequency;
|
|
93
|
+
locations?: string[];
|
|
94
|
+
}): TestBuilder;
|
|
95
|
+
/**
|
|
96
|
+
* Configuration for an Endpoint node
|
|
97
|
+
* Accepts DSL-friendly literal types which are converted to schema enums internally
|
|
98
|
+
*/
|
|
99
|
+
export interface EndpointConfig {
|
|
100
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | "CONNECT" | "TRACE";
|
|
101
|
+
path: string;
|
|
102
|
+
base: Endpoint["base"];
|
|
103
|
+
response_format: "JSON" | "XML" | "TEXT";
|
|
104
|
+
headers?: Record<string, any>;
|
|
105
|
+
body?: any;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Creates an Endpoint node for making HTTP requests.
|
|
109
|
+
*
|
|
110
|
+
* @param config - Endpoint configuration (method, path, base, headers, etc.)
|
|
111
|
+
* @returns An Endpoint node (without id) ready to be added to a TestBuilder
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* import { target } from './target';
|
|
116
|
+
*
|
|
117
|
+
* builder.addNode("health", Endpoint({
|
|
118
|
+
* method: GET,
|
|
119
|
+
* path: "/health",
|
|
120
|
+
* base: target("api-gateway"),
|
|
121
|
+
* response_format: JSON
|
|
122
|
+
* }));
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export declare function Endpoint(config: EndpointConfig): Omit<Endpoint, "id">;
|
|
126
|
+
/**
|
|
127
|
+
* Duration specification for Wait nodes.
|
|
128
|
+
* Accepts either milliseconds directly or an object with seconds/minutes.
|
|
129
|
+
*/
|
|
130
|
+
export type WaitDuration = number | {
|
|
131
|
+
seconds: number;
|
|
132
|
+
} | {
|
|
133
|
+
minutes: number;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Creates a Wait node that pauses execution for a specified duration.
|
|
137
|
+
*
|
|
138
|
+
* @param duration - Duration to wait (milliseconds, or {seconds: n}, or {minutes: n})
|
|
139
|
+
* @returns A Wait node (without id) ready to be added to a TestBuilder
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* import { Wait, WaitDuration } from './index';
|
|
144
|
+
*
|
|
145
|
+
* builder.addNode("pause", Wait(WaitDuration.seconds(2)));
|
|
146
|
+
* // or with raw milliseconds:
|
|
147
|
+
* builder.addNode("pause", Wait(2000));
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export declare function Wait(duration: WaitDuration): Omit<Wait, "id">;
|
|
151
|
+
/**
|
|
152
|
+
* Creates an Assertion node that validates test conditions.
|
|
153
|
+
*
|
|
154
|
+
* @param assertions - Array of SerializedAssertions to evaluate
|
|
155
|
+
* @returns An Assertion node (without id) ready to be added to a TestBuilder
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* import { Assert } from './assertions';
|
|
160
|
+
*
|
|
161
|
+
* builder.addNode("checks", Assertion([
|
|
162
|
+
* Assert(state["node"].status).equals(200),
|
|
163
|
+
* Assert(state["node"].body["status"]).equals("ok")
|
|
164
|
+
* ]));
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
export declare function Assertion(assertions: JSONAssertion[]): Omit<Assertions, "id">;
|
|
168
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|
package/dist/builder.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createGraphBuilder = createGraphBuilder;
|
|
4
|
+
exports.Endpoint = Endpoint;
|
|
5
|
+
exports.Wait = Wait;
|
|
6
|
+
exports.Assertion = Assertion;
|
|
7
|
+
const schema_js_1 = require("./schema.js");
|
|
8
|
+
/**
|
|
9
|
+
* Internal implementation class for TestBuilder.
|
|
10
|
+
* Uses explicit type assertions at method boundaries to maintain phantom type tracking.
|
|
11
|
+
*/
|
|
12
|
+
class TestBuilderImpl {
|
|
13
|
+
config;
|
|
14
|
+
nodes = [];
|
|
15
|
+
edges = [];
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
19
|
+
addNode(name, node) {
|
|
20
|
+
// Merge the name into the node to create a complete Node
|
|
21
|
+
// Type assertion required: spreading Omit<Node, 'id'> + id produces a valid Node at runtime
|
|
22
|
+
this.nodes.push({ ...node, id: name });
|
|
23
|
+
// Type assertion: we've added Name to NodeName union
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
addEdge(from, to) {
|
|
27
|
+
this.edges.push({ from, to });
|
|
28
|
+
// Type assertion: we've updated HasOutput and HasInput based on edge direction
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
get build() {
|
|
32
|
+
const { name, frequency, locations } = this.config;
|
|
33
|
+
const nodes = this.nodes;
|
|
34
|
+
const edges = this.edges;
|
|
35
|
+
const buildFn = () => {
|
|
36
|
+
return {
|
|
37
|
+
name,
|
|
38
|
+
version: schema_js_1.TEST_PLAN_VERSION,
|
|
39
|
+
frequency,
|
|
40
|
+
locations,
|
|
41
|
+
nodes,
|
|
42
|
+
edges,
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
// Type assertion: build is only callable when graph constraints are satisfied
|
|
46
|
+
// The conditional type in TestBuilder['build'] enforces this at the call site
|
|
47
|
+
return buildFn;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new test builder for constructing a test plan.
|
|
52
|
+
*
|
|
53
|
+
* @param config - Configuration for the test plan
|
|
54
|
+
* @param config.name - Name of the test
|
|
55
|
+
* @param config.frequency - Optional frequency for scheduled execution
|
|
56
|
+
* @param config.locations - Optional array of location identifiers where this test should run
|
|
57
|
+
* @returns A new TestBuilder instance
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const plan = createGraphBuilder({
|
|
62
|
+
* name: "health-check",
|
|
63
|
+
* frequency: Frequency.every(5).minute(),
|
|
64
|
+
* locations: ["us-east-1", "eu-west-1"]
|
|
65
|
+
* })
|
|
66
|
+
* .addNode("health", Endpoint({ method: GET, path: "/health", response_format: JSON }))
|
|
67
|
+
* .addEdge(START, "health")
|
|
68
|
+
* .addEdge("health", END)
|
|
69
|
+
* .build();
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
function createGraphBuilder(config) {
|
|
73
|
+
return new TestBuilderImpl(config);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Creates an Endpoint node for making HTTP requests.
|
|
77
|
+
*
|
|
78
|
+
* @param config - Endpoint configuration (method, path, base, headers, etc.)
|
|
79
|
+
* @returns An Endpoint node (without id) ready to be added to a TestBuilder
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* import { target } from './target';
|
|
84
|
+
*
|
|
85
|
+
* builder.addNode("health", Endpoint({
|
|
86
|
+
* method: GET,
|
|
87
|
+
* path: "/health",
|
|
88
|
+
* base: target("api-gateway"),
|
|
89
|
+
* response_format: JSON
|
|
90
|
+
* }));
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
function Endpoint(config) {
|
|
94
|
+
return {
|
|
95
|
+
type: schema_js_1.NodeType.ENDPOINT,
|
|
96
|
+
method: config.method,
|
|
97
|
+
path: config.path,
|
|
98
|
+
base: config.base,
|
|
99
|
+
response_format: config.response_format,
|
|
100
|
+
headers: config.headers,
|
|
101
|
+
body: config.body,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Converts a WaitDuration to milliseconds.
|
|
106
|
+
*/
|
|
107
|
+
function toMilliseconds(duration) {
|
|
108
|
+
if (typeof duration === "number") {
|
|
109
|
+
return duration;
|
|
110
|
+
}
|
|
111
|
+
if ("seconds" in duration) {
|
|
112
|
+
return duration.seconds * 1000;
|
|
113
|
+
}
|
|
114
|
+
if ("minutes" in duration) {
|
|
115
|
+
return duration.minutes * 60 * 1000;
|
|
116
|
+
}
|
|
117
|
+
throw new Error("Invalid duration format");
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Creates a Wait node that pauses execution for a specified duration.
|
|
121
|
+
*
|
|
122
|
+
* @param duration - Duration to wait (milliseconds, or {seconds: n}, or {minutes: n})
|
|
123
|
+
* @returns A Wait node (without id) ready to be added to a TestBuilder
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* import { Wait, WaitDuration } from './index';
|
|
128
|
+
*
|
|
129
|
+
* builder.addNode("pause", Wait(WaitDuration.seconds(2)));
|
|
130
|
+
* // or with raw milliseconds:
|
|
131
|
+
* builder.addNode("pause", Wait(2000));
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
function Wait(duration) {
|
|
135
|
+
return {
|
|
136
|
+
type: schema_js_1.NodeType.WAIT,
|
|
137
|
+
duration_ms: toMilliseconds(duration),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Creates an Assertion node that validates test conditions.
|
|
142
|
+
*
|
|
143
|
+
* @param assertions - Array of SerializedAssertions to evaluate
|
|
144
|
+
* @returns An Assertion node (without id) ready to be added to a TestBuilder
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* import { Assert } from './assertions';
|
|
149
|
+
*
|
|
150
|
+
* builder.addNode("checks", Assertion([
|
|
151
|
+
* Assert(state["node"].status).equals(200),
|
|
152
|
+
* Assert(state["node"].body["status"]).equals("ok")
|
|
153
|
+
* ]));
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
function Assertion(assertions) {
|
|
157
|
+
return {
|
|
158
|
+
type: schema_js_1.NodeType.ASSERTION,
|
|
159
|
+
assertions: assertions.map((assertion) => ({
|
|
160
|
+
assertionType: schema_js_1.ResponseFormat.JSON,
|
|
161
|
+
...assertion,
|
|
162
|
+
})),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,EAAG,WAAoB,CAAC;AAC1C,eAAO,MAAM,GAAG,EAAG,SAAkB,CAAC;AAEtC,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC;AACjC,MAAM,MAAM,GAAG,GAAG,OAAO,GAAG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,KAAK,GAAG,WAAoB,CAAC;AAC7B,QAAA,GAAG,GAAG,SAAkB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example usage of the Sequential Test Builder
|
|
3
|
+
*
|
|
4
|
+
* This demonstrates the simplified createTestBuilder API for straightforward
|
|
5
|
+
* linear test flows. Use this when you don't need complex branching.
|
|
6
|
+
*
|
|
7
|
+
* For more complex graphs with parallel execution or conditional flows,
|
|
8
|
+
* see example.ts which uses createGraphBuilder.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=example-sequential.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example-sequential.d.ts","sourceRoot":"","sources":["../src/example-sequential.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|