Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #21 from brown-ccv/feat-defaults
Browse files Browse the repository at this point in the history
refactor: 💡 rm unnecess params, add defaults
  • Loading branch information
Rashi1997 authored Feb 11, 2021
2 parents 20dba1c + f0731b5 commit 1d2efb0
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 114 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
coverage
testapp.js
.yarn.lock
.yarn.lock
**/.DS_Store
8 changes: 2 additions & 6 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
// add a random number between 0 and offset to the base number
const jitter = (base, offset) => (
const jitterx = (base, offset) => (
base + Math.floor(Math.random() * Math.floor(offset))
)

// add a random number between 0 and 50 to the base number
const jitter50 = (base) => jitter(base, 50)

module.exports ={
jitter,
jitter50
jitterx
}
9 changes: 4 additions & 5 deletions tests/countdown.spec.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
const countdown = require("../trials/countdown.js");

describe("Countdown trial", () => {
it("counts to 10 with a text countdown", () => {
it("counts to 10 with a message countdown", () => {
const returnobject = {
type: "html_keyboard_response",
stimulus: "<h3>Countdown</h3",
stimulus: "<h3>Countdown</h3>",
trial_duration: 1000,
response_ends_trial: false,
timeline: [
{ prompt: "<h1>10</h1>" },
{ prompt: "<h1>9</h1>" },
Expand All @@ -19,13 +18,13 @@ describe("Countdown trial", () => {
{ prompt: "<h1>2</h1>" },
{ prompt: "<h1>1</h1>" },
],
response_ends_trial: false,
};
expect(
countdown({
duration: 1000,
text: "Countdown",
message: "Countdown",
time: 10,
responseEndsTrial: false,
})
).toEqual(returnobject);
});
Expand Down
26 changes: 4 additions & 22 deletions tests/fixation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ const jsPsych = require("jspsych-react");
describe("Fixation trial", () => {
it("fixation without photodiode box", () => {
const config = init({ USE_PHOTODIODE: false });
let data = { code: null };
const result = fixation(config, {
duration: 100,
});
expect(result.stimulus).toContain("fixation-dot");
expect(result.stimulus).not.toContain("photodiode-spot");
expect(result.on_load()).toEqual(null);
expect(result.on_finish()).toEqual(null);
expect(result.on_load()).toEqual(undefined);
expect(result.on_finish(data)).toEqual(1);
});

it("fixation with photodiode box and task code", () => {
Expand All @@ -24,26 +25,7 @@ describe("Fixation trial", () => {
});
expect(result.stimulus).toContain("fixation-dot");
expect(result.stimulus).toContain("photodiode-spot");
expect(result.on_load()).not.toEqual(null);
expect(result.on_load()).toEqual(undefined);
expect(result.on_finish(data)).toEqual(10);
});

it("fixation with jsPsych.NO_KEYS", () => {
const config = init({ USE_PHOTODIODE: false });
const result = fixation(config, {
duration: 100,
buttons: jsPsych.NO_KEYS,
});
expect(result.choices).toEqual(undefined);
});

it("fixation with choices", () => {
const config = init({ USE_PHOTODIODE: false });
const choices = ["p", "q"];
const result = fixation(config, {
duration: 100,
buttons: choices,
});
expect(result.choices).toEqual(choices);
});
});
29 changes: 29 additions & 0 deletions tests/showImage.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const showImage = require("../trials/showImage.js");
const { init } = require("../app.js");

describe("showImage trial", () => {
it("showImage without photodiode box", () => {
const config = init({ USE_PHOTODIODE: false });
let data = { code: null };
const result = showImage(config, "", {
duration: 100,
});
expect(result.prompt).not.toContain("photodiode-spot");
expect(result.on_load()).toEqual(undefined);
result.on_finish(data)
expect(data.code).toEqual(1);
});

it("showImage with photodiode box and task code", () => {
const config = init({ USE_PHOTODIODE: true });
let data = { code: null };
const result = showImage(config, "", {
duration: 100,
taskCode: 10,
});
expect(result.prompt).toContain("photodiode-spot");
expect(result.on_load()).toEqual(undefined);
result.on_finish(data)
expect(data.code).toEqual(10);
});
});
7 changes: 4 additions & 3 deletions tests/showMessage.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const jsPsych = require("jspsych-react");
describe("showMessage trial", () => {
it("showMessage without photodiode box", () => {
const config = init({ USE_PHOTODIODE: false });
let data = { code: null };
const message = "Experiment Start";
const result = showMessage(config, {
responseType: "html_keyboard_response",
Expand All @@ -13,8 +14,8 @@ describe("showMessage trial", () => {
});
expect(result.stimulus).toContain(message);
expect(result.stimulus).not.toContain("photodiode-spot");
expect(result.on_load()).toEqual(null);
expect(result.on_finish()).toEqual(null);
expect(result.on_load()).toEqual(undefined);
expect(result.on_finish(data)).toEqual(1);
});

it("showMessage with photodiode box and task code", () => {
Expand All @@ -30,7 +31,7 @@ describe("showMessage trial", () => {
});
expect(result.stimulus).toContain(message);
expect(result.stimulus).toContain("photodiode-spot");
expect(result.on_load()).not.toEqual(null);
expect(result.on_load()).toEqual(undefined);
expect(result.on_finish(data)).toEqual(10);
});

Expand Down
25 changes: 14 additions & 11 deletions trials/countdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,36 @@ const _ = require("lodash");

/**
* @description
* Builds a countdown transition with the given text and number of seconds.
* Builds a countdown transition with the given message and number of seconds.
*
* @module
* @param {Object} options
* @param {number} options.duration - The trial duration.
* @param {string} options.text - Optional text for the countdown. (default: "")
* @param {number} options.time - The number of seconds for the countdown. (default: 10s)
* @param {boolean} options.responseEndsTrial - True if the trial ends on response, false if the trial waits for the duration. (default: false)
* @param {number} options.duration - trial duration in milliseconds. (default: 1000)
* @param {string} options.stimulus - Onscreen stimulus in HTML to be shown in the trial. If the stimulus is not provided, message should be provided as a string. (default: "")
* @param {string} options.message - (optional) message for the countdown. (default: "")
* @param {number} options.time - start number for the countdown. (default: 3)
*/

module.exports = function (options) {
const defaults = {
text: "",
time: 10,
responseEndsTrial: false,
duration: 1000,
stimulus: "",
message: "",
time: 3,
};
const { duration, text, time, responseEndsTrial } = { defaults, ...options };
const { duration, message, stimulus, time } = { ...defaults, ...options };

const stimulusOrMessage = message !== "" ? `<h3>${message}</h3>` : stimulus;
const times = _.range(time, 0, -1);
const timeline = times.map((val) => {
return { prompt: `<h1>${val}</h1>` };
});

return {
type: "html_keyboard_response",
stimulus: `<h3>${text}</h3`,
stimulus: stimulusOrMessage,
trial_duration: duration,
response_ends_trial: responseEndsTrial,
response_ends_trial: false,
timeline: timeline,
};
};
28 changes: 13 additions & 15 deletions trials/fixation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const {
pdSpotEncode,
photodiodeGhostBox,
} = require("../lib/markup/photodiode");
const { jitter50 } = require("../lib/utils");
const { jitterx } = require("../lib/utils");

/**
* @description
Expand All @@ -15,20 +15,20 @@ const { jitter50 } = require("../lib/utils");
* @param {boolean} config.USE_ELECTRON - USE_ELECTRON flag
* @param {boolean} config.USE_MTURK - USE_MTURK flag
* @param {Object} options
* @param {number} options.duration - The trial duration in milliseconds.
* @param {boolean} options.responseEndsTrial - True if the trial ends on response,false if the trial waits for the duration, by default false value.
* @param {number} options.taskCode - Task code to be saved into data log and for pdSpotEncode, which by default is null and is passed when config has USE_PHOTODIODE set true.
* @param {number} options.numBlinks - Number of times the pulse needs to be repeated for photodiode box, when USE_PHOTODIODE is set true. If not set, by default is 1.
* @param {any} options.buttons - This array contains the keys that the subject is allowed to press in order to respond to the stimulus. Keys can be specified as their numeric key code or as characters (e.g., 'a', 'q'). The default value of jsPsych.ALL_KEYS means that all keys will be accepted as valid responses. Specifying jsPsych.NO_KEYS will mean that no responses are allowed.
* @param {number} options.duration - trial duration in milliseconds jittered with the jitter param. (default: 1000)
* @param {number} options.jitter - jitter range (0-jitter) to add from to the trial duration (default: 50)
* @param {number} options.taskCode - Task code to be saved into data log (default: 1)
* @param {number} options.numBlinks - Number of times the pulse needs to be repeated for photodiode box, when USE_PHOTODIODE is set true. (default: 1)
*/

module.exports = function (config, options) {
const defaults = {
responseEndsTrial: false,
taskCode: null,
duration: 1000,
jitter: 50,
taskCode: 1,
numBlinks: 1,
};
const { duration, responseEndsTrial, taskCode, numBlinks, buttons } = {
const { duration, jitter, taskCode, numBlinks } = {
...defaults,
...options,
};
Expand All @@ -39,12 +39,10 @@ module.exports = function (config, options) {

return {
type: "html_keyboard_response",
choices: buttons,
stimulus: stimulus,
response_ends_trial: responseEndsTrial,
trial_duration: jitter50(duration),
on_load: () =>
taskCode != null ? pdSpotEncode(taskCode, numBlinks, config) : null,
on_finish: (data) => (taskCode != null ? (data.code = taskCode) : null),
response_ends_trial: false,
trial_duration: jitterx(duration, jitter),
on_load: () => pdSpotEncode(taskCode, numBlinks, config),
on_finish: (data) => (data.code = taskCode),
};
};
47 changes: 23 additions & 24 deletions trials/showImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,61 @@ const {
pdSpotEncode,
} = require("../lib/markup/photodiode");
const $ = require("jquery");
const { jitter50 } = require("../lib/utils");
const { jitterx } = require("../lib/utils");

/**
* @description
* Builds a trial with a onscreen message, optional buttons and optional photodiode box
* Builds a trial with a onscreen message and optional photodiode box
*
* @module
* @param {Object} config - The configuration object for USE_PHOTODIODE, USE_EEG, USE_ELECTRON and USE_MTURK flags.
* @param {boolean} config.USE_PHOTODIODE - USE_PHOTODIODE flag
* @param {boolean} config.USE_EEG - USE_EEG flag
* @param {boolean} config.USE_ELECTRON - USE_ELECTRON flag
* @param {boolean} config.USE_MTURK - USE_MTURK flag
* @param {string} image - The path of the image file to be displayed.
* @param {Object} options
* @param {string} options.responseType - This tells jsPsych which plugin file to use to run the trial.
* @param {number} options.duration - The trial duration in milliseconds.
* @param {string} options.image - The path of the image file to be displayed.
* @param {number} options.imageHeight - Set the height of the image in pixels. If left null (no value specified), then the image will display at its natural height.
* @param {number} options.imageWidth - Set the width of the image in pixels. If left null (no value specified), then the image will display at its natural width.
* @param {boolean} options.responseEndsTrial - True if the trial ends on response,false if the trial waits for the duration, by default false value.
* @param {number} options.taskCode - Task code to be saved into data log and for pdSpotEncode, which by default is null and is passed when config has USE_PHOTODIODE set true.
* @param {number} options.numBlinks - Number of times the pulse needs to be repeated for photodiode box, when USE_PHOTODIODE is set true. If not set, by default is 1.
* @param {number} options.duration - trial duration in milliseconds jittered with the jitter param. (default: 1000)
* @param {number} options.jitter - jitter range (0-jitter) to add from to the trial duration (default: 50)
* @param {number} options.imageHeight - Set the height of the image in pixels. (default: 600)
* @param {number} options.imageWidth - Set the width of the image in pixels. (default: 600)
* @param {number} options.taskCode - Task code to be saved into data log (default: 1)
* @param {number} options.numBlinks - Number of times the pulse needs to be repeated for photodiode box, when USE_PHOTODIODE is set true. (default: 1)
*/

module.exports = function (config, options) {
module.exports = function (config, image, options) {
const defaults = {
responseEndsTrial: false,
taskCode: null,
duration: 1000,
jitter: 50,
imageHeight: 600,
imageWidth: 600,
taskCode: 1,
numBlinks: 1,
};
const {
responseType,
duration,
image,
jitter,
imageHeight,
imageWidth,
responseEndsTrial,
taskCode,
numBlinks,
} = { ...defaults, ...options };

return {
type: responseType,
type: "image_keyboard_response",
stimulus: image,
prompt: config.USE_PHOTODIODE ? photodiodeGhostBox() : null,
response_ends_trial: responseEndsTrial,
trial_duration: jitter50(duration),
prompt: config.USE_PHOTODIODE ? photodiodeGhostBox() : "",
response_ends_trial: false,
trial_duration: jitterx(duration, jitter),
on_load: () => {
$("#jspsych-image-keyboard-response-stimulus").addClass("image");
$("#jspsych-image-keyboard-response-stimulus").height(imageHeight);
$("#jspsych-image-keyboard-response-stimulus").width(imageWidth);
$("html").css("cursor", "none")(taskCode != null)
? pdSpotEncode(taskCode, numBlinks, config)
: null;
$("html").css("cursor", "none");
pdSpotEncode(taskCode, numBlinks, config);
},
on_finish: (data) => {
data.code = code;
data.code = taskCode;
$("html").css("cursor", "auto");
},
};
Expand Down
28 changes: 15 additions & 13 deletions trials/showMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,28 @@ const { baseStimulus } = require("../lib/markup/stimuli");
* @param {boolean} config.USE_ELECTRON - USE_ELECTRON flag
* @param {boolean} config.USE_MTURK - USE_MTURK flag
* @param {Object} options
* @param {string} options.responseType - This tells jsPsych which plugin file to use to run the trial.
* @param {number} options.duration - The trial duration in milliseconds.
* @param {string} options.stimulus - Onscreen stimulus in HTML to be shown in the trial, if not set default text is empty. If the stimulus is not provided, message should be provided as a string.
* @param {string} options.message - Onscreen message to be shown in the trial, if not set default text is empty.
* @param {string} options.responseType - This tells jsPsych which plugin file to use to run the trial. (default: 'html_keyboard_response')
* @param {number} options.duration - trial duration in milliseconds. (default: 1000)
* @param {string} options.stimulus - Onscreen stimulus in HTML to be shown in the trial, if not set default text is empty. If the stimulus is not provided, message should be provided as a string. (default: "")
* @param {string} options.message - Onscreen message to be shown in the trial. (default: "")
* @param {boolean} options.onstart - True if the message is to be display on start of the trial. False if the message needs to be in the stimulus.(default: false)
* @param {boolean} options.responseEndsTrial - True if the trial ends on response,false if the trial waits for the duration, by default false value.
* @param {number} options.taskCode - Task code to be saved into data log and for pdSpotEncode, which by default is null and is passed when config has USE_PHOTODIODE set true.
* @param {number} options.numBlinks - Number of times the pulse needs to be repeated for photodiode box, when USE_PHOTODIODE is set true. If not set, by default is 1.
* @param {Array} options.buttons - This array contains the keys that the subject is allowed to press in order to respond to the stimulus. Keys can be specified as their numeric key code or as characters (e.g., 'a', 'q'). The default value of jsPsych.ALL_KEYS means that all keys will be accepted as valid responses. Specifying jsPsych.NO_KEYS will mean that no responses are allowed.
* @param {boolean} options.responseEndsTrial - True if the trial ends on response,false if the trial waits for the duration. (default: false)
* @param {number} options.taskCode - Task code to be saved into data log (default: 1)
* @param {number} options.numBlinks - Number of times the pulse needs to be repeated for photodiode box, when USE_PHOTODIODE is set true. (default: 1)
* @param {Array} options.buttons - This array contains the keys that the subject is allowed to press in order to respond to the stimulus. Keys can be specified as their numeric key code or as characters (e.g., 'a', 'q'). The default value of jsPsych.ALL_KEYS means that all keys will be accepted as valid responses. Specifying jsPsych.NO_KEYS will mean that no responses are allowed. (default: ["OK"])
*/

module.exports = function (config, options) {
const defaults = {
message: "",
responseType: "html_keyboard_response",
duration: 1000,
stimulus: "",
message: "",
onstart: false,
responseEndsTrial: false,
taskCode: null,
taskCode: 1,
numBlinks: 1,
buttons: ["OK"],
};
const {
responseType,
Expand Down Expand Up @@ -64,8 +67,7 @@ module.exports = function (config, options) {
on_start: (trial) => {
onstart ? (trial.stimulus = stimulusOrMessage) : "";
},
on_load: () =>
taskCode != null ? pdSpotEncode(taskCode, numBlinks, config) : null,
on_finish: (data) => (taskCode != null ? (data.code = taskCode) : null),
on_load: () => pdSpotEncode(taskCode, numBlinks, config),
on_finish: (data) => (data.code = taskCode),
};
};
Loading

0 comments on commit 1d2efb0

Please sign in to comment.