Merge pull request #2974 from jspsych/fix-complex-defaults

Fix defaults for COMPLEX parameter types
This commit is contained in:
Josh de Leeuw 2023-03-06 10:39:20 -05:00 committed by GitHub
commit a284ed3e1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 13 deletions

View File

@ -0,0 +1,5 @@
---
"jspsych": patch
---
This fixes an issue when a plugin has a COMPLEX parameter and there is a default value specified at the root level of the parameter, rather than for each individual nested parameter (#2972).

View File

@ -781,7 +781,14 @@ export class JsPsych {
for (const param in trial.type.info.parameters) {
// check if parameter is complex with nested defaults
if (trial.type.info.parameters[param].type === ParameterType.COMPLEX) {
if (trial.type.info.parameters[param].array === true) {
// check if parameter is undefined and has a default value
if (typeof trial[param] === "undefined" && trial.type.info.parameters[param].default) {
trial[param] = trial.type.info.parameters[param].default;
}
// if parameter is an array, iterate over each entry after confirming that there are
// entries to iterate over. this is common when some parameters in a COMPLEX type have
// default values and others do not.
if (trial.type.info.parameters[param].array === true && Array.isArray(trial[param])) {
// iterate over each entry in the array
trial[param].forEach(function (ip, i) {
// check each parameter in the plugin description
@ -789,13 +796,7 @@ export class JsPsych {
if (typeof trial[param][i][p] === "undefined" || trial[param][i][p] === null) {
if (typeof trial.type.info.parameters[param].nested[p].default === "undefined") {
console.error(
"You must specify a value for the " +
p +
" parameter (nested in the " +
param +
" parameter) in the " +
trial.type +
" plugin."
`You must specify a value for the ${p} parameter (nested in the ${param} parameter) in the ${trial.type.info.name} plugin.`
);
} else {
trial[param][i][p] = trial.type.info.parameters[param].nested[p].default;
@ -809,11 +810,7 @@ export class JsPsych {
else if (typeof trial[param] === "undefined" || trial[param] === null) {
if (typeof trial.type.info.parameters[param].default === "undefined") {
console.error(
"You must specify a value for the " +
param +
" parameter in the " +
trial.type.info.name +
" plugin."
`You must specify a value for the ${param} parameter in the ${trial.type.info.name} plugin.`
);
} else {
trial[param] = trial.type.info.parameters[param].default;

View File

@ -1,6 +1,8 @@
import surveyText from "@jspsych/plugin-survey-text";
import { startTimeline } from "@jspsych/test-utils";
import jsPsychTestComplex from "./test-complex-plugin";
describe("nested defaults", () => {
test("work in basic situation", async () => {
const { displayElement } = await startTimeline([
@ -48,3 +50,21 @@ describe("nested defaults", () => {
spy.mockRestore();
});
});
describe("defaults for COMPLEX parameters", () => {
test("default at the top level should work", async () => {
const { expectFinished, getData } = await startTimeline([
{
type: jsPsychTestComplex,
},
]);
await expectFinished();
expect(getData().values()[0].blocks).toEqual([
{ x: 10, y: 10 },
{ x: 20, y: 20 },
{ x: 30, y: 30 },
]);
});
});

View File

@ -0,0 +1,46 @@
import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from "jspsych";
const info = <const>{
name: "test-complex-plugin",
parameters: {
blocks: {
type: ParameterType.COMPLEX,
array: true,
default: [
{ x: 10, y: 10 },
{ x: 20, y: 20 },
{ x: 30, y: 30 },
],
nested: {
x: {
type: ParameterType.INT,
default: undefined,
},
y: {
type: ParameterType.INT,
default: undefined,
},
},
},
},
};
type Info = typeof info;
class TestComplexPlugin implements JsPsychPlugin<Info> {
static info = info;
constructor(private jsPsych: JsPsych) {}
trial(display_element: HTMLElement, trial: TrialType<Info>) {
// save data
var trialdata = {
blocks: trial.blocks,
};
// next trial
this.jsPsych.finishTrial(trialdata);
}
}
export default TestComplexPlugin;