jspsych 8.0.3 → 8.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/dist/index.browser.js +8 -9
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.min.js +3 -3
- package/dist/index.browser.min.js.map +1 -1
- package/dist/index.cjs +7 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/timeline/Timeline.spec.ts +105 -5
- package/src/timeline/Timeline.ts +12 -9
package/package.json
CHANGED
|
@@ -58,6 +58,109 @@ describe("Timeline", () => {
|
|
|
58
58
|
expect((children[1] as Timeline).children.map((child) => child.index)).toEqual([1, 2]);
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
it("respects dynamically added child node descriptions", async () => {
|
|
62
|
+
TestPlugin.setManualFinishTrialMode();
|
|
63
|
+
|
|
64
|
+
const timelineDescription: TimelineArray = [{ type: TestPlugin }];
|
|
65
|
+
const timeline = createTimeline(timelineDescription);
|
|
66
|
+
|
|
67
|
+
const runPromise = timeline.run();
|
|
68
|
+
expect(timeline.children.length).toEqual(1);
|
|
69
|
+
|
|
70
|
+
timelineDescription.push({ timeline: [{ type: TestPlugin }] });
|
|
71
|
+
await TestPlugin.finishTrial();
|
|
72
|
+
await TestPlugin.finishTrial();
|
|
73
|
+
await runPromise;
|
|
74
|
+
|
|
75
|
+
expect(timeline.children.length).toEqual(2);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("dynamically added child node descriptions before a node after it has been run", async () => {
|
|
79
|
+
TestPlugin.setManualFinishTrialMode();
|
|
80
|
+
|
|
81
|
+
const timelineDescription: TimelineArray = [{ type: TestPlugin }];
|
|
82
|
+
const timeline = createTimeline(timelineDescription);
|
|
83
|
+
|
|
84
|
+
const runPromise = timeline.run();
|
|
85
|
+
expect(timeline.children.length).toEqual(1);
|
|
86
|
+
|
|
87
|
+
await TestPlugin.finishTrial();
|
|
88
|
+
timelineDescription.splice(0, 0, { timeline: [{ type: TestPlugin }] });
|
|
89
|
+
await TestPlugin.finishTrial();
|
|
90
|
+
await runPromise;
|
|
91
|
+
|
|
92
|
+
expect(timeline.children.length).toEqual(1);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("respects dynamically removed end child node descriptions", async () => {
|
|
96
|
+
TestPlugin.setManualFinishTrialMode();
|
|
97
|
+
|
|
98
|
+
const timelineDescription: TimelineArray = [
|
|
99
|
+
{ type: TestPlugin },
|
|
100
|
+
{ timeline: [{ type: TestPlugin }] },
|
|
101
|
+
{ type: TestPlugin },
|
|
102
|
+
];
|
|
103
|
+
const timeline = createTimeline(timelineDescription);
|
|
104
|
+
|
|
105
|
+
const runPromise = timeline.run();
|
|
106
|
+
expect(timeline.children.length).toEqual(1); // Only the first child is instantiated because they are incrementally instantiated now
|
|
107
|
+
|
|
108
|
+
timelineDescription.pop();
|
|
109
|
+
await TestPlugin.finishTrial();
|
|
110
|
+
await TestPlugin.finishTrial();
|
|
111
|
+
await runPromise;
|
|
112
|
+
|
|
113
|
+
expect(timeline.children.length).toEqual(2);
|
|
114
|
+
expect(timeline.children).toEqual([expect.any(Trial), expect.any(Timeline)]);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("respects dynamically removed middle child node descriptions", async () => {
|
|
118
|
+
TestPlugin.setManualFinishTrialMode();
|
|
119
|
+
|
|
120
|
+
const timelineDescription: TimelineArray = [
|
|
121
|
+
{ type: TestPlugin },
|
|
122
|
+
{ timeline: [{ type: TestPlugin }] },
|
|
123
|
+
{ type: TestPlugin },
|
|
124
|
+
];
|
|
125
|
+
const timeline = createTimeline(timelineDescription);
|
|
126
|
+
|
|
127
|
+
const runPromise = timeline.run();
|
|
128
|
+
expect(timeline.children.length).toEqual(1);
|
|
129
|
+
|
|
130
|
+
timelineDescription.splice(1, 1);
|
|
131
|
+
await TestPlugin.finishTrial();
|
|
132
|
+
await TestPlugin.finishTrial();
|
|
133
|
+
await runPromise;
|
|
134
|
+
|
|
135
|
+
expect(timeline.children.length).toEqual(2);
|
|
136
|
+
expect(timeline.children).toEqual([expect.any(Trial), expect.any(Trial)]);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("dynamically remove first node after running it", async () => {
|
|
140
|
+
TestPlugin.setManualFinishTrialMode();
|
|
141
|
+
|
|
142
|
+
const timelineDescription: TimelineArray = [
|
|
143
|
+
{ type: TestPlugin, data: { I: 0 } },
|
|
144
|
+
{ timeline: [{ type: TestPlugin, data: { I: 1 } }] },
|
|
145
|
+
{ type: TestPlugin, data: { I: 2 } },
|
|
146
|
+
{ type: TestPlugin, data: { I: 3 } },
|
|
147
|
+
];
|
|
148
|
+
const timeline = createTimeline(timelineDescription);
|
|
149
|
+
|
|
150
|
+
const runPromise = timeline.run();
|
|
151
|
+
await TestPlugin.finishTrial();
|
|
152
|
+
timelineDescription.shift();
|
|
153
|
+
await TestPlugin.finishTrial();
|
|
154
|
+
await TestPlugin.finishTrial();
|
|
155
|
+
await runPromise;
|
|
156
|
+
|
|
157
|
+
expect(timeline.children.length).toEqual(3);
|
|
158
|
+
expect(timeline.children[0].getDataParameter().I).toEqual(0);
|
|
159
|
+
const secondChildDescription = timeline.children[1].description as TimelineDescription;
|
|
160
|
+
expect(secondChildDescription["timeline"][0]).toHaveProperty("data.I", 1);
|
|
161
|
+
expect(timeline.children[2].getDataParameter().I).toEqual(3);
|
|
162
|
+
});
|
|
163
|
+
|
|
61
164
|
describe("with `pause()` and `resume()` calls`", () => {
|
|
62
165
|
beforeEach(() => {
|
|
63
166
|
TestPlugin.setManualFinishTrialMode();
|
|
@@ -84,12 +187,9 @@ describe("Timeline", () => {
|
|
|
84
187
|
|
|
85
188
|
await TestPlugin.finishTrial();
|
|
86
189
|
expect(timeline.children[1].getStatus()).toBe(TimelineNodeStatus.COMPLETED);
|
|
87
|
-
expect(timeline.children[2].getStatus()).toBe(TimelineNodeStatus.PENDING);
|
|
88
|
-
|
|
89
|
-
// Resolving the next trial promise shouldn't continue the experiment since no trial should be running.
|
|
90
|
-
await TestPlugin.finishTrial();
|
|
91
190
|
|
|
92
|
-
|
|
191
|
+
// The timeline is paused, so it shouldn't have instantiated the next child node yet.
|
|
192
|
+
expect(timeline.children.length).toEqual(2);
|
|
93
193
|
|
|
94
194
|
timeline.resume();
|
|
95
195
|
await flushPromises();
|
package/src/timeline/Timeline.ts
CHANGED
|
@@ -75,7 +75,9 @@ export class Timeline extends TimelineNode {
|
|
|
75
75
|
for (const timelineVariableIndex of timelineVariableOrder) {
|
|
76
76
|
this.setCurrentTimelineVariablesByIndex(timelineVariableIndex);
|
|
77
77
|
|
|
78
|
-
for (const
|
|
78
|
+
for (const childNodeDescription of this.description.timeline) {
|
|
79
|
+
const childNode = this.instantiateChildNode(childNodeDescription);
|
|
80
|
+
|
|
79
81
|
const previousChild = this.currentChild;
|
|
80
82
|
this.currentChild = childNode;
|
|
81
83
|
childNode.index = previousChild
|
|
@@ -151,14 +153,15 @@ export class Timeline extends TimelineNode {
|
|
|
151
153
|
}
|
|
152
154
|
}
|
|
153
155
|
|
|
154
|
-
private
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
private instantiateChildNode(
|
|
157
|
+
childDescription: TimelineDescription | TimelineArray | TrialDescription
|
|
158
|
+
) {
|
|
159
|
+
const newChildNode = isTimelineDescription(childDescription)
|
|
160
|
+
? new Timeline(this.dependencies, childDescription, this)
|
|
161
|
+
: new Trial(this.dependencies, childDescription, this);
|
|
162
|
+
|
|
163
|
+
this.children.push(newChildNode);
|
|
164
|
+
return newChildNode;
|
|
162
165
|
}
|
|
163
166
|
|
|
164
167
|
private currentTimelineVariables: Record<string, any>;
|