@forgehive/task 0.1.12 → 0.2.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/dist/index.d.ts +33 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +173 -16
- package/dist/index.js.map +1 -1
- package/dist/test/add-listener-with-boundaries.test.js +56 -26
- package/dist/test/add-listener-with-boundaries.test.js.map +1 -1
- package/dist/test/safe-replay-complex-boundary.test.js +36 -27
- package/dist/test/safe-replay-complex-boundary.test.js.map +1 -1
- package/dist/test/safe-replay.test.js +23 -14
- package/dist/test/safe-replay.test.js.map +1 -1
- package/dist/test/safe-run.test.js +41 -16
- package/dist/test/safe-run.test.js.map +1 -1
- package/dist/test/task-boundary-mocking.test.js +17 -7
- package/dist/test/task-boundary-mocking.test.js.map +1 -1
- package/dist/test/task-execution-log.test.d.ts +2 -0
- package/dist/test/task-execution-log.test.d.ts.map +1 -0
- package/dist/test/task-execution-log.test.js +207 -0
- package/dist/test/task-execution-log.test.js.map +1 -0
- package/dist/test/task-with-boundaries.test.js +56 -24
- package/dist/test/task-with-boundaries.test.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +236 -23
- package/src/test/add-listener-with-boundaries.test.ts +24 -18
- package/src/test/safe-replay-complex-boundary.test.ts +18 -10
- package/src/test/safe-replay.test.ts +21 -12
- package/src/test/safe-run.test.ts +20 -15
- package/src/test/task-boundary-mocking.test.ts +8 -6
- package/src/test/task-execution-log.test.ts +246 -0
- package/src/test/task-with-boundaries.test.ts +42 -41
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { Schema } from '@forgehive/schema'
|
|
2
|
-
import { createTask, ExecutionRecord } from '../index'
|
|
2
|
+
import { createTask, ExecutionRecord, getExecutionRecordType } from '../index'
|
|
3
3
|
|
|
4
4
|
describe('safeReplay functionality tests', () => {
|
|
5
|
+
// Helper function to create ExecutionRecord with computed type
|
|
6
|
+
function createExecutionRecord<T, U>(partial: Omit<ExecutionRecord<T, U>, 'type'>): ExecutionRecord<T, U> {
|
|
7
|
+
return {
|
|
8
|
+
...partial,
|
|
9
|
+
type: getExecutionRecordType(partial)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
5
13
|
// Common variables
|
|
6
14
|
let prices: Record<string, number>
|
|
7
15
|
let boundaries: {
|
|
@@ -38,22 +46,23 @@ describe('safeReplay functionality tests', () => {
|
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
// Create the task using createTask
|
|
41
|
-
getTickerPrice = createTask(
|
|
49
|
+
getTickerPrice = createTask({
|
|
50
|
+
name: 'getTickerPrice',
|
|
42
51
|
schema,
|
|
43
52
|
boundaries,
|
|
44
|
-
async ({ ticker }, { fetchData }) => {
|
|
53
|
+
fn: async ({ ticker }, { fetchData }) => {
|
|
45
54
|
const price = await fetchData(ticker)
|
|
46
55
|
return {
|
|
47
56
|
ticker,
|
|
48
57
|
price
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
|
-
)
|
|
60
|
+
})
|
|
52
61
|
})
|
|
53
62
|
|
|
54
63
|
it('Should replay a previous execution using the execution log and replay the fetchData boundary', async () => {
|
|
55
64
|
// Create a manual execution log
|
|
56
|
-
const executionLog: ExecutionRecord = {
|
|
65
|
+
const executionLog: ExecutionRecord = createExecutionRecord({
|
|
57
66
|
input: { ticker: 'AAPL' },
|
|
58
67
|
output: {
|
|
59
68
|
ticker: 'AAPL',
|
|
@@ -67,7 +76,7 @@ describe('safeReplay functionality tests', () => {
|
|
|
67
76
|
}
|
|
68
77
|
]
|
|
69
78
|
}
|
|
70
|
-
}
|
|
79
|
+
})
|
|
71
80
|
|
|
72
81
|
// No safeReplay method yet, this will be implemented later
|
|
73
82
|
// This will be our test for that functionality
|
|
@@ -101,7 +110,7 @@ describe('safeReplay functionality tests', () => {
|
|
|
101
110
|
|
|
102
111
|
it('Should execute with mixed boundaries modes', async () => {
|
|
103
112
|
// Create a manual execution log for testing
|
|
104
|
-
const executionLog: ExecutionRecord = {
|
|
113
|
+
const executionLog: ExecutionRecord = createExecutionRecord({
|
|
105
114
|
input: { ticker: 'AAPL' },
|
|
106
115
|
output: {
|
|
107
116
|
ticker: 'AAPL',
|
|
@@ -115,7 +124,7 @@ describe('safeReplay functionality tests', () => {
|
|
|
115
124
|
}
|
|
116
125
|
]
|
|
117
126
|
}
|
|
118
|
-
}
|
|
127
|
+
})
|
|
119
128
|
|
|
120
129
|
// Use mixed mode - replay for fetchData but execute logAccess
|
|
121
130
|
const [replayResult, replayError, replayLog] = await getTickerPrice.safeReplay(
|
|
@@ -153,7 +162,7 @@ describe('safeReplay functionality tests', () => {
|
|
|
153
162
|
|
|
154
163
|
it('Should properly handle errors in boundary replay mode', async () => {
|
|
155
164
|
// Create a manual execution log with an error in the boundary
|
|
156
|
-
const executionLog: ExecutionRecord = {
|
|
165
|
+
const executionLog: ExecutionRecord = createExecutionRecord({
|
|
157
166
|
input: { ticker: 'AAPL' },
|
|
158
167
|
output: null,
|
|
159
168
|
error: 'API error: Rate limit exceeded',
|
|
@@ -165,7 +174,7 @@ describe('safeReplay functionality tests', () => {
|
|
|
165
174
|
}
|
|
166
175
|
]
|
|
167
176
|
}
|
|
168
|
-
}
|
|
177
|
+
})
|
|
169
178
|
|
|
170
179
|
// Use replay mode for fetchData
|
|
171
180
|
const [replayResult, replayError, replayLog] = await getTickerPrice.safeReplay(
|
|
@@ -189,7 +198,7 @@ describe('safeReplay functionality tests', () => {
|
|
|
189
198
|
|
|
190
199
|
it('Should handle boundaries with both output and error as null', async () => {
|
|
191
200
|
// Create a manual execution log with null output and error in the boundary
|
|
192
|
-
const executionLog: ExecutionRecord = {
|
|
201
|
+
const executionLog: ExecutionRecord = createExecutionRecord({
|
|
193
202
|
input: { ticker: 'AAPL' },
|
|
194
203
|
output: { ticker: 'AAPL', price: 160.23 },
|
|
195
204
|
boundaries: {
|
|
@@ -201,7 +210,7 @@ describe('safeReplay functionality tests', () => {
|
|
|
201
210
|
}
|
|
202
211
|
]
|
|
203
212
|
}
|
|
204
|
-
}
|
|
213
|
+
})
|
|
205
214
|
|
|
206
215
|
// Use replay mode for fetchData
|
|
207
216
|
const [replayResult, replayError, replayLog] = await getTickerPrice.safeReplay(
|
|
@@ -15,14 +15,15 @@ describe('Task safeRun tests', () => {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
// Create the task
|
|
18
|
-
const successTask = createTask(
|
|
18
|
+
const successTask = createTask({
|
|
19
|
+
name: 'successTask',
|
|
19
20
|
schema,
|
|
20
21
|
boundaries,
|
|
21
|
-
async function ({ value }, { fetchData }) {
|
|
22
|
+
fn: async function ({ value }, { fetchData }) {
|
|
22
23
|
const result = await fetchData(value)
|
|
23
24
|
return { result, success: true }
|
|
24
25
|
}
|
|
25
|
-
)
|
|
26
|
+
})
|
|
26
27
|
|
|
27
28
|
// Call safeRun with valid input
|
|
28
29
|
const [result, error, record] = await successTask.safeRun({ value: 5 })
|
|
@@ -58,14 +59,15 @@ describe('Task safeRun tests', () => {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
// Create the task
|
|
61
|
-
const errorTask = createTask(
|
|
62
|
+
const errorTask = createTask({
|
|
63
|
+
name: 'errorTask',
|
|
62
64
|
schema,
|
|
63
65
|
boundaries,
|
|
64
|
-
async function ({ value }, { fetchData }) {
|
|
66
|
+
fn: async function ({ value }, { fetchData }) {
|
|
65
67
|
const result = await fetchData(value)
|
|
66
68
|
return { result, success: true }
|
|
67
69
|
}
|
|
68
|
-
)
|
|
70
|
+
})
|
|
69
71
|
|
|
70
72
|
// Call safeRun with problematic input that will cause an error
|
|
71
73
|
const [result, error, record] = await errorTask.safeRun({ value: -5 })
|
|
@@ -101,14 +103,15 @@ describe('Task safeRun tests', () => {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
// Create the task
|
|
104
|
-
const validationTask = createTask(
|
|
106
|
+
const validationTask = createTask({
|
|
107
|
+
name: 'validationTask',
|
|
105
108
|
schema,
|
|
106
109
|
boundaries,
|
|
107
|
-
async function ({ value }, { fetchData }) {
|
|
110
|
+
fn: async function ({ value }, { fetchData }) {
|
|
108
111
|
const result = await fetchData(value)
|
|
109
112
|
return { result, success: true }
|
|
110
113
|
}
|
|
111
|
-
)
|
|
114
|
+
})
|
|
112
115
|
|
|
113
116
|
// Call safeRun with invalid input that will fail schema validation
|
|
114
117
|
const [result, error, record] = await validationTask.safeRun({ value: 0 })
|
|
@@ -142,14 +145,15 @@ describe('Task safeRun tests', () => {
|
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
// Create the task
|
|
145
|
-
const listenerTask = createTask(
|
|
148
|
+
const listenerTask = createTask({
|
|
149
|
+
name: 'listenerTask',
|
|
146
150
|
schema,
|
|
147
151
|
boundaries,
|
|
148
|
-
async function ({ value }, { fetchData }) {
|
|
152
|
+
fn: async function ({ value }, { fetchData }) {
|
|
149
153
|
const result = await fetchData(value)
|
|
150
154
|
return result
|
|
151
155
|
}
|
|
152
|
-
)
|
|
156
|
+
})
|
|
153
157
|
|
|
154
158
|
// Create a mock listener
|
|
155
159
|
const originalListener = jest.fn()
|
|
@@ -206,15 +210,16 @@ describe('Task safeRun tests', () => {
|
|
|
206
210
|
}
|
|
207
211
|
|
|
208
212
|
// Create a task that uses multiple boundaries
|
|
209
|
-
const multiBoundaryTask = createTask(
|
|
213
|
+
const multiBoundaryTask = createTask({
|
|
214
|
+
name: 'multiBoundaryTask',
|
|
210
215
|
schema,
|
|
211
216
|
boundaries,
|
|
212
|
-
async function ({ values }, { doubleValue, sumValues }) {
|
|
217
|
+
fn: async function ({ values }, { doubleValue, sumValues }) {
|
|
213
218
|
const doubled = await Promise.all(values.map(value => doubleValue(value)))
|
|
214
219
|
const total = await sumValues(doubled)
|
|
215
220
|
return { doubled, total }
|
|
216
221
|
}
|
|
217
|
-
)
|
|
222
|
+
})
|
|
218
223
|
|
|
219
224
|
// Call safeRun
|
|
220
225
|
const [result, error, record] = await multiBoundaryTask.safeRun({ values: [1, 2, 3] })
|
|
@@ -17,14 +17,15 @@ describe('Task boundary mocking', () => {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// Create the task using createTask
|
|
20
|
-
const multiplyTask = createTask(
|
|
20
|
+
const multiplyTask = createTask({
|
|
21
|
+
name: 'multiplyTask',
|
|
21
22
|
schema,
|
|
22
23
|
boundaries,
|
|
23
|
-
async function ({ value }, { fetchExternalData }) {
|
|
24
|
+
fn: async function ({ value }, { fetchExternalData }) {
|
|
24
25
|
const result = value * await fetchExternalData(value)
|
|
25
26
|
return result
|
|
26
27
|
}
|
|
27
|
-
)
|
|
28
|
+
})
|
|
28
29
|
|
|
29
30
|
// Create mock for fetchExternalData boundary that returns a specific value
|
|
30
31
|
const mockFetchData = jest.fn().mockResolvedValue(5)
|
|
@@ -71,15 +72,16 @@ describe('Task boundary mocking', () => {
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
// Create the task
|
|
74
|
-
const calculateTask = createTask(
|
|
75
|
+
const calculateTask = createTask({
|
|
76
|
+
name: 'calculateTask',
|
|
75
77
|
schema,
|
|
76
78
|
boundaries,
|
|
77
|
-
async function ({ value }, { doubleValue, tripleValue }) {
|
|
79
|
+
fn: async function ({ value }, { doubleValue, tripleValue }) {
|
|
78
80
|
const doubled = await doubleValue(value)
|
|
79
81
|
const tripled = await tripleValue(value)
|
|
80
82
|
return doubled + tripled
|
|
81
83
|
}
|
|
82
|
-
)
|
|
84
|
+
})
|
|
83
85
|
|
|
84
86
|
// Create wrapped mock functions
|
|
85
87
|
const mockDoubleValue = jest.fn().mockResolvedValue(10)
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { createTask, Schema, getExecutionRecordType } from '../index'
|
|
2
|
+
|
|
3
|
+
describe('Task execution log record', () => {
|
|
4
|
+
describe('Task name in execution record', () => {
|
|
5
|
+
it('should include task name in safeRun execution record when task has a name', async () => {
|
|
6
|
+
// Create a schema
|
|
7
|
+
const schema = new Schema({
|
|
8
|
+
value: Schema.number()
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
// Create a task with a name
|
|
12
|
+
const task = createTask({
|
|
13
|
+
name: 'test-multiplication-task',
|
|
14
|
+
description: 'A task that multiplies input by 2',
|
|
15
|
+
schema,
|
|
16
|
+
boundaries: {
|
|
17
|
+
multiply: async (value: number) => value * 2
|
|
18
|
+
},
|
|
19
|
+
fn: async ({ value }, { multiply }) => {
|
|
20
|
+
const result = await multiply(value)
|
|
21
|
+
return { result }
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// Run the task with safeRun
|
|
26
|
+
const [result, error, record] = await task.safeRun({ value: 5 })
|
|
27
|
+
|
|
28
|
+
// Verify the execution was successful
|
|
29
|
+
expect(error).toBeNull()
|
|
30
|
+
expect(result).toEqual({ result: 10 })
|
|
31
|
+
|
|
32
|
+
// Verify the task name is included in the record
|
|
33
|
+
expect(record.taskName).toBe('test-multiplication-task')
|
|
34
|
+
expect(record.input).toEqual({ value: 5 })
|
|
35
|
+
expect(record.output).toEqual({ result: 10 })
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('should include undefined task name when task has no name', async () => {
|
|
39
|
+
// Create a schema
|
|
40
|
+
const schema = new Schema({
|
|
41
|
+
value: Schema.number()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// Create a task without a name
|
|
45
|
+
const task = createTask({
|
|
46
|
+
schema,
|
|
47
|
+
boundaries: {},
|
|
48
|
+
fn: async ({ value }) => {
|
|
49
|
+
return { result: value * 3 }
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// Run the task with safeRun
|
|
54
|
+
const [result, error, record] = await task.safeRun({ value: 4 })
|
|
55
|
+
|
|
56
|
+
// Verify the execution was successful
|
|
57
|
+
expect(error).toBeNull()
|
|
58
|
+
expect(result).toEqual({ result: 12 })
|
|
59
|
+
|
|
60
|
+
// Verify the task name is undefined in the record
|
|
61
|
+
expect(record.taskName).toBeUndefined()
|
|
62
|
+
expect(record.input).toEqual({ value: 4 })
|
|
63
|
+
expect(record.output).toEqual({ result: 12 })
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('should include task name in error execution records', async () => {
|
|
67
|
+
// Create a schema
|
|
68
|
+
const schema = new Schema({
|
|
69
|
+
value: Schema.number()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// Create a task that will throw an error
|
|
73
|
+
const task = createTask({
|
|
74
|
+
name: 'error-task',
|
|
75
|
+
schema,
|
|
76
|
+
boundaries: {},
|
|
77
|
+
fn: async ({ value }) => {
|
|
78
|
+
if (value < 0) {
|
|
79
|
+
throw new Error('Value cannot be negative')
|
|
80
|
+
}
|
|
81
|
+
return { result: value }
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// Run the task with a value that will cause an error
|
|
86
|
+
const [result, error, record] = await task.safeRun({ value: -1 })
|
|
87
|
+
|
|
88
|
+
// Verify the execution failed as expected
|
|
89
|
+
expect(result).toBeNull()
|
|
90
|
+
expect(error).not.toBeNull()
|
|
91
|
+
expect(error?.message).toBe('Value cannot be negative')
|
|
92
|
+
|
|
93
|
+
// Verify the task name is included in the error record
|
|
94
|
+
expect(record.taskName).toBe('error-task')
|
|
95
|
+
expect(record.input).toEqual({ value: -1 })
|
|
96
|
+
expect(record.error).toBe('Value cannot be negative')
|
|
97
|
+
expect(record.output).toBeUndefined()
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('should include task name in safeReplay execution record', async () => {
|
|
101
|
+
// Create a schema
|
|
102
|
+
const schema = new Schema({
|
|
103
|
+
value: Schema.number()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
// Create a task with boundaries
|
|
107
|
+
const task = createTask({
|
|
108
|
+
name: 'replay-test-task',
|
|
109
|
+
schema,
|
|
110
|
+
boundaries: {
|
|
111
|
+
fetchData: async (value: number) => value * 2
|
|
112
|
+
},
|
|
113
|
+
fn: async ({ value }, { fetchData }) => {
|
|
114
|
+
const result = await fetchData(value)
|
|
115
|
+
return { result }
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
// First, run the task normally to get an execution record
|
|
120
|
+
const [, , originalRecord] = await task.safeRun({ value: 3 })
|
|
121
|
+
|
|
122
|
+
// Now replay the task
|
|
123
|
+
const [replayResult, replayError, replayRecord] = await task.safeReplay(
|
|
124
|
+
originalRecord,
|
|
125
|
+
{ boundaries: { fetchData: 'replay' } }
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
// Verify the replay was successful
|
|
129
|
+
expect(replayError).toBeNull()
|
|
130
|
+
expect(replayResult).toEqual({ result: 6 })
|
|
131
|
+
|
|
132
|
+
// Verify the task name is included in the replay record
|
|
133
|
+
expect(replayRecord.taskName).toBe('replay-test-task')
|
|
134
|
+
expect(replayRecord.input).toEqual({ value: 3 })
|
|
135
|
+
expect(replayRecord.output).toEqual({ result: 6 })
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
describe('Type computation in execution record', () => {
|
|
140
|
+
it('should have type "success" when task completes successfully', async () => {
|
|
141
|
+
const schema = new Schema({
|
|
142
|
+
value: Schema.number()
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const task = createTask({
|
|
146
|
+
name: 'success-task',
|
|
147
|
+
schema,
|
|
148
|
+
boundaries: {},
|
|
149
|
+
fn: async ({ value }) => {
|
|
150
|
+
return { result: value * 2 }
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
const [result, error, record] = await task.safeRun({ value: 5 })
|
|
155
|
+
|
|
156
|
+
expect(error).toBeNull()
|
|
157
|
+
expect(result).toEqual({ result: 10 })
|
|
158
|
+
expect(record.type).toBe('success')
|
|
159
|
+
expect(record.output).toEqual({ result: 10 })
|
|
160
|
+
expect(record.error).toBeUndefined()
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
it('should have type "error" when task throws an error', async () => {
|
|
164
|
+
const schema = new Schema({
|
|
165
|
+
value: Schema.number()
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
const task = createTask({
|
|
169
|
+
name: 'error-task',
|
|
170
|
+
schema,
|
|
171
|
+
boundaries: {},
|
|
172
|
+
fn: async ({ value }) => {
|
|
173
|
+
if (value < 0) {
|
|
174
|
+
throw new Error('Value cannot be negative')
|
|
175
|
+
}
|
|
176
|
+
return { result: value }
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
const [result, error, record] = await task.safeRun({ value: -1 })
|
|
181
|
+
|
|
182
|
+
expect(result).toBeNull()
|
|
183
|
+
expect(error).not.toBeNull()
|
|
184
|
+
expect(record.type).toBe('error')
|
|
185
|
+
expect(record.error).toBe('Value cannot be negative')
|
|
186
|
+
expect(record.output).toBeUndefined()
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
it('should have type "pending" when neither output nor error is set', async () => {
|
|
190
|
+
// This tests the getExecutionRecordType utility function directly
|
|
191
|
+
const partialRecord = {
|
|
192
|
+
input: { value: 1 },
|
|
193
|
+
boundaries: {},
|
|
194
|
+
taskName: 'test'
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const type = getExecutionRecordType(partialRecord)
|
|
198
|
+
expect(type).toBe('pending')
|
|
199
|
+
})
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
describe('Context in execution record', () => {
|
|
203
|
+
it('should include context when provided to safeRun', async () => {
|
|
204
|
+
const schema = new Schema({
|
|
205
|
+
value: Schema.number()
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
const task = createTask({
|
|
209
|
+
name: 'context-task',
|
|
210
|
+
schema,
|
|
211
|
+
boundaries: {},
|
|
212
|
+
fn: async ({ value }) => {
|
|
213
|
+
return { result: value * 2 }
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
const [result, error, record] = await task.safeRun({ value: 5 })
|
|
218
|
+
|
|
219
|
+
expect(error).toBeNull()
|
|
220
|
+
expect(result).toEqual({ result: 10 })
|
|
221
|
+
expect(record.metadata).toEqual({})
|
|
222
|
+
expect(record.taskName).toBe('context-task')
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
it('should handle undefined context gracefully', async () => {
|
|
226
|
+
const schema = new Schema({
|
|
227
|
+
value: Schema.number()
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
const task = createTask({
|
|
231
|
+
name: 'no-context-task',
|
|
232
|
+
schema,
|
|
233
|
+
boundaries: {},
|
|
234
|
+
fn: async ({ value }) => {
|
|
235
|
+
return { result: value * 2 }
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
const [result, error, record] = await task.safeRun({ value: 5 })
|
|
240
|
+
|
|
241
|
+
expect(error).toBeNull()
|
|
242
|
+
expect(result).toEqual({ result: 10 })
|
|
243
|
+
expect(record.metadata).toEqual({})
|
|
244
|
+
})
|
|
245
|
+
})
|
|
246
|
+
})
|
|
@@ -14,14 +14,15 @@ describe('Boundaries tasks tests', () => {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// Create the task using createTask
|
|
17
|
-
const indentity = createTask(
|
|
17
|
+
const indentity = createTask({
|
|
18
|
+
name: 'indentity',
|
|
18
19
|
schema,
|
|
19
20
|
boundaries,
|
|
20
|
-
async (argv, boundaries) => {
|
|
21
|
+
fn: async (argv, boundaries) => {
|
|
21
22
|
const externalData = await boundaries.fetchExternalData()
|
|
22
23
|
return { ...externalData, ...argv }
|
|
23
24
|
}
|
|
24
|
-
)
|
|
25
|
+
})
|
|
25
26
|
|
|
26
27
|
const object = await indentity.run({ bar: true })
|
|
27
28
|
const { foo } = await indentity.run({ foo: true })
|
|
@@ -43,22 +44,21 @@ describe('Boundaries tasks tests', () => {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
// Create the task using createTask with boundariesData
|
|
46
|
-
const indentity = createTask(
|
|
47
|
+
const indentity = createTask({
|
|
48
|
+
name: 'indentity',
|
|
47
49
|
schema,
|
|
48
50
|
boundaries,
|
|
49
|
-
async (argv, boundaries) => {
|
|
51
|
+
fn: async (argv, boundaries) => {
|
|
50
52
|
const externalData = await boundaries.fetchExternalData()
|
|
51
53
|
return { ...externalData, ...argv }
|
|
52
54
|
},
|
|
53
|
-
{
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
)
|
|
55
|
+
boundariesData: {
|
|
56
|
+
fetchExternalData: [
|
|
57
|
+
{ input: [], output: { foo: false } }
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
mode: 'proxy-pass'
|
|
61
|
+
})
|
|
62
62
|
|
|
63
63
|
const object = await indentity.run({ bar: true })
|
|
64
64
|
const { foo } = await indentity.run({ foo: true })
|
|
@@ -81,14 +81,15 @@ describe('Boundaries tasks tests', () => {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// Create the task using createTask
|
|
84
|
-
const add = createTask(
|
|
84
|
+
const add = createTask({
|
|
85
|
+
name: 'add',
|
|
85
86
|
schema,
|
|
86
87
|
boundaries,
|
|
87
|
-
async function (argv, boundaries) {
|
|
88
|
+
fn: async function (argv, boundaries) {
|
|
88
89
|
const externalData: number = await boundaries.fetchExternalData(1)
|
|
89
90
|
return argv.value + externalData
|
|
90
91
|
}
|
|
91
|
-
)
|
|
92
|
+
})
|
|
92
93
|
|
|
93
94
|
const six = await add.run({ value: 4 })
|
|
94
95
|
const seven = await add.run({ value: 5 })
|
|
@@ -111,22 +112,21 @@ describe('Boundaries tasks tests', () => {
|
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
// Create the task using createTask with boundariesData
|
|
114
|
-
const add = createTask(
|
|
115
|
+
const add = createTask({
|
|
116
|
+
name: 'add',
|
|
115
117
|
schema,
|
|
116
118
|
boundaries,
|
|
117
|
-
async function (argv, boundaries) {
|
|
119
|
+
fn: async function (argv, boundaries) {
|
|
118
120
|
const externalData: number = await boundaries.fetchExternalData(argv.value)
|
|
119
121
|
return argv.value + externalData
|
|
120
122
|
},
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
)
|
|
123
|
+
boundariesData: {
|
|
124
|
+
fetchExternalData: [
|
|
125
|
+
{ input: [4], output: 2 }
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
mode: 'proxy-pass'
|
|
129
|
+
})
|
|
130
130
|
|
|
131
131
|
const six = await add.run({ value: 4 }) // From tape data
|
|
132
132
|
const fifteen = await add.run({ value: 5 })
|
|
@@ -163,14 +163,15 @@ describe('Boundaries tasks tests', () => {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
// Create the task using createTask
|
|
166
|
-
const multiplyTask = createTask(
|
|
166
|
+
const multiplyTask = createTask({
|
|
167
|
+
name: 'multiplyTask',
|
|
167
168
|
schema,
|
|
168
169
|
boundaries,
|
|
169
|
-
async function ({ value }, { fetchExternalData}) {
|
|
170
|
+
fn: async function ({ value }, { fetchExternalData}) {
|
|
170
171
|
const externalData: number = await fetchExternalData(value)
|
|
171
172
|
return value * externalData
|
|
172
173
|
}
|
|
173
|
-
)
|
|
174
|
+
})
|
|
174
175
|
|
|
175
176
|
multiplyTask.addListener((record) => {
|
|
176
177
|
records.push(record)
|
|
@@ -238,14 +239,15 @@ describe('Boundaries tasks tests', () => {
|
|
|
238
239
|
}
|
|
239
240
|
|
|
240
241
|
// Create the task using createTask
|
|
241
|
-
const multiplyTask = createTask(
|
|
242
|
+
const multiplyTask = createTask({
|
|
243
|
+
name: 'multiplyTask',
|
|
242
244
|
schema,
|
|
243
245
|
boundaries,
|
|
244
|
-
async function ({ value }, { fetchExternalData }) {
|
|
246
|
+
fn: async function ({ value }, { fetchExternalData }) {
|
|
245
247
|
const externalData: number = await fetchExternalData(value)
|
|
246
248
|
return value * externalData
|
|
247
249
|
}
|
|
248
|
-
)
|
|
250
|
+
})
|
|
249
251
|
|
|
250
252
|
// Run task with value 2
|
|
251
253
|
await multiplyTask.run({ value: 2 })
|
|
@@ -308,18 +310,17 @@ describe('Boundaries tasks tests', () => {
|
|
|
308
310
|
expect(finalSortedTape[2].output).toBe(8)
|
|
309
311
|
|
|
310
312
|
// Verify tape can be used for replay in proxy-pass mode
|
|
311
|
-
const replayTask = createTask(
|
|
313
|
+
const replayTask = createTask({
|
|
314
|
+
name: 'replayTask',
|
|
312
315
|
schema,
|
|
313
316
|
boundaries,
|
|
314
|
-
async function ({ value }, { fetchExternalData }) {
|
|
317
|
+
fn: async function ({ value }, { fetchExternalData }) {
|
|
315
318
|
const externalData: number = await fetchExternalData(value)
|
|
316
319
|
return value * externalData
|
|
317
320
|
},
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
)
|
|
321
|
+
boundariesData: boundariesData3 as BoundaryTapeData,
|
|
322
|
+
mode: 'proxy-pass'
|
|
323
|
+
})
|
|
323
324
|
|
|
324
325
|
// Run task with all three values from the tape
|
|
325
326
|
const result2 = await replayTask.run({ value: 2 })
|