Migrate to TypeScript

This commit is contained in:
bjoluc 2021-07-06 17:55:42 +02:00
parent 584a8879ef
commit 91e7b1e3ff
273 changed files with 2584 additions and 1706 deletions

1963
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@
"scripts": {
"test": "jest",
"build": "npm run build -ws",
"watch": "npm run watch -ws",
"prepare": "npm run build"
"prepare": "npm run build",
"tsc": "npm run tsc -ws"
},
"devDependencies": {
"@babel/core": "^7.14.6",
@ -15,21 +15,27 @@
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"@types/jest": "^26.0.23",
"canvas": "^2.8.0",
"import-sort-style-module": "^6.0.0",
"jest": "^27.0",
"jest-environment-jsdom": "^27.0.3",
"prettier": "^2.3.1",
"jest": "^27.0.6",
"jest-environment-jsdom": "^27.0.6",
"prettier": "^2.3.2",
"prettier-plugin-import-sort": "^0.0.7",
"rollup": "^2.52.2",
"rollup-plugin-terser": "^7.0.2"
"rollup": "^2.52.7",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.30.0",
"ts-jest": "^27.0.3",
"tslib": "^2.3.0",
"typescript": "^4.3.5"
},
"prettier": {
"printWidth": 100
},
"importSort": {
".js, .mjs": {
"style": "module"
".ts, .js, .mjs": {
"style": "module",
"parser": "typescript"
}
}
}

View File

@ -1,3 +0,0 @@
module.exports = {
presets: [["@babel/preset-env", { targets: { node: "current" } }]],
};

View File

@ -1,7 +1,26 @@
module.exports.makePackageConfig = (packageJson) => {
const ts = require("typescript");
const { pathsToModuleNameMapper } = require("ts-jest/utils");
module.exports.makePackageConfig = (dirname) => {
const packageJson = require(dirname + "/package.json");
const packageBaseName = packageJson.name.replace("@jspsych/", "");
// based on https://github.com/formium/tsdx/blob/462af2d002987f985695b98400e0344b8f2754b7/src/createRollupConfig.ts#L51-L57
const tsCompilerOptions = ts.parseJsonConfigFileContent(
ts.readConfigFile(dirname + "/tsconfig.json", ts.sys.readFile).config,
ts.sys,
dirname
).options;
return {
preset: "ts-jest",
// moduleNameMapper: {
// "^@jspsych/(.*)$": "<rootDir>/../$1/src",
// "^jspsych(.*)$": "<rootDir>/../jspsych/src$1",
// },
moduleNameMapper: pathsToModuleNameMapper(tsCompilerOptions.paths, {
prefix: "<rootDir>/../../",
}),
resetModules: true,
testEnvironment: "jsdom",
testEnvironmentOptions: {
@ -9,9 +28,6 @@ module.exports.makePackageConfig = (packageJson) => {
pretendToBeVisual: true,
},
testURL: "http://localhost/",
transform: {
"\\.js$": ["babel-jest", { configFile: "@jspsych/config/babel.test.config.js" }],
},
displayName: {
name: packageBaseName,
color: packageBaseName === "jspsych" ? "white" : "cyanBright",

View File

@ -2,6 +2,7 @@
"private": true,
"name": "@jspsych/config",
"scripts": {
"build": ""
"build": "",
"tsc": ""
}
}

View File

@ -3,38 +3,79 @@ import json from "@rollup/plugin-json";
import resolve from "@rollup/plugin-node-resolve";
import { defineConfig } from "rollup";
import { terser } from "rollup-plugin-terser";
import typescript from "rollup-plugin-typescript2";
import ts from "typescript";
export const makeRollupConfig = (source, destination, outputOptions) =>
defineConfig({
input: `${source}.js`,
output: [
{
file: `${destination}.js`,
format: "iife",
exports: "default",
sourcemap: true,
...outputOptions,
},
{
file: `${destination}.min.js`,
format: "iife",
exports: "default",
sourcemap: true,
plugins: [terser()],
...outputOptions,
},
],
export const makeRollupConfig = (outputOptions, globalOptions = {}) => {
const source = "src/index";
const destination = "dist/index";
outputOptions = {
sourcemap: true,
...outputOptions,
};
const commonConfig = {
input: `${source}.ts`,
plugins: [
json(),
resolve(),
babel({ babelHelpers: "bundled", extends: "@jspsych/config/babel.build.config.js" }),
typescript({
typescript: ts,
tsconfigOverride: { compilerOptions: { rootDir: "./src", outDir: "./dist" } },
}),
json(),
],
});
...globalOptions,
};
export const makeRollupConfigForPlugin = (iifeName) => ({
...makeRollupConfig("src/index", "dist/index", {
name: iifeName,
globals: { jspsych: "jsPsych" },
}),
external: ["jspsych"],
});
return defineConfig([
{
// Non-babel builds
...commonConfig,
output: [
{
// Build file to be used as an ES import
file: `${destination}.js`,
format: "esm",
...outputOptions,
},
{
// Build file to be used for tinkering in modern browsers
file: `${destination}.browser.js`,
format: "iife",
exports: "default",
...outputOptions,
},
],
},
{
// Babel build
...commonConfig,
plugins: commonConfig.plugins.concat(
babel({
babelHelpers: "bundled",
extends: "@jspsych/config/babel.config.js",
})
),
output: [
{
// Minified production build file
file: `${destination}.browser.min.js`,
format: "iife",
exports: "default",
plugins: [terser()],
...outputOptions,
},
],
},
]);
};
export const makeRollupConfigForPlugin = (iifeName) =>
makeRollupConfig(
{
name: iifeName,
globals: { jspsych: "jsPsych" },
},
{ external: ["jspsych"] }
);

View File

@ -0,0 +1,41 @@
{
// based on https://github.com/formium/tsdx/blob/462af2d002987f985695b98400e0344b8f2754b7/templates/basic/tsconfig.json<<<<
// see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
"compilerOptions": {
"module": "ESNext",
"lib": ["dom", "esnext"],
"importHelpers": true,
// output .d.ts declaration files for consumers
"declaration": true,
// output .js.map sourcemap files for consumers
"sourceMap": true,
// stricter type-checking for stronger correctness. Recommended by TS
"strict": false, // should be enabled one lucky day
// linter checks for common issues
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
// noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
"noUnusedLocals": false, // should be enabled one lucky day
"noUnusedParameters": false, // should be enabled one lucky day
// use Node's module resolution algorithm, instead of the legacy TS one
"moduleResolution": "node",
// interop between ESM and CJS modules. Recommended by TS
"esModuleInterop": true,
// significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
"skipLibCheck": true,
// error out if import and file system have a casing mismatch. Recommended by TS
"forceConsistentCasingInFileNames": true,
// do note emit build output when running `tsc`
"noEmit": true,
// map package imports directly to their source files
"paths": {
"@jspsych/*": ["packages/*/src"],
"jspsych/tests*": ["packages/jspsych/tests*"],
"jspsych*": ["packages/jspsych/src*"]
},
"baseUrl": "../../",
// allow resolving json modules in tests (needed for transitive imports of jspsych in tests;
// the jspsych package itself uses https://stackoverflow.com/a/61426303 instead)
"resolveJsonModule": true
}
}

1
packages/jspsych/global.d.ts vendored Normal file
View File

@ -0,0 +1 @@
declare module "*.json"; // https://stackoverflow.com/a/61426303

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,20 +3,23 @@
"version": "7.0.0",
"description": "Behavioral experiments in a browser",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist",
"css"
],
"source": "src/index.ts",
"directories": {
"test": "tests"
},
"scripts": {
"test": "jest --config jest.config.cjs",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -1,3 +1,3 @@
import { makeRollupConfig } from "@jspsych/config/rollup.mjs";
export default makeRollupConfig("src/index", "dist/index", { name: "jsPsych" });
export default makeRollupConfig({ name: "jsPsych" });

View File

@ -13,8 +13,8 @@ var dataProperties = {};
var query_string;
// DataCollection
function DataCollection(data) {
var data_collection = {};
function DataCollection(data?) {
var data_collection: any = {};
var trials = typeof data === "undefined" ? [] : data;
@ -231,7 +231,7 @@ function DataCollection(data) {
// DataColumn class
function DataColumn() {
var data_column = {};
var data_column: any = {};
data_column.values = [];
@ -453,8 +453,11 @@ export function createInteractionListeners() {
// fullscreen change capture
function fullscreenchange() {
var type =
// @ts-expect-error
document.isFullScreen ||
// @ts-expect-error
document.webkitIsFullScreen ||
// @ts-expect-error
document.mozIsFullScreen ||
document.fullscreenElement
? "fullscreenenter"
@ -561,7 +564,6 @@ function JSON2CSV(objArray) {
function getQueryString() {
var a = window.location.search.substr(1).split("&");
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i) {
var p = a[i].split("=", 2);

View File

@ -6,7 +6,7 @@ import * as randomization from "./randomization";
import * as turk from "./turk";
import * as utils from "./utils";
const jsPsych = {
const jsPsych = <any>{
extensions: {},
data,
plugins,
@ -22,12 +22,12 @@ const jsPsych = {
//
// options
var opts = {};
var opts = <any>{};
// experiment timeline
var timeline;
// flow control
var global_trial_index = 0;
var current_trial = {};
var current_trial = <any>{};
var current_trial_finished = false;
// target DOM element
var DOM_container;
@ -52,6 +52,7 @@ if (
window.hasOwnProperty("webkitAudioContext") &&
!window.hasOwnProperty("AudioContext")
) {
// @ts-expect-error
window.AudioContext = webkitAudioContext;
}
// end patch
@ -165,7 +166,7 @@ jsPsych.init = function (options) {
if (opts.display_element instanceof Element) {
var display = opts.display_element;
} else {
var display = document.querySelector("#" + opts.display_element);
var display = document.querySelector("#" + opts.display_element) as any;
}
if (display === null) {
console.error("The display_element specified in jsPsych.init() does not exist in the DOM.");
@ -454,7 +455,7 @@ jsPsych.getSafeModeStatus = function () {
return file_protocol;
};
function TimelineNode(parameters, parent, relativeID) {
function TimelineNode(parameters, parent = undefined, relativeID = undefined) {
// a unique ID for this node, relative to the parent
var relative_id;
@ -472,7 +473,7 @@ function TimelineNode(parameters, parent, relativeID) {
var node_trial_data;
// track progress through the node
var progress = {
var progress = <any>{
current_location: -1, // where on the timeline (which timelinenode)
current_variable_set: 0, // which set of variables to use from timeline_variables
current_repetition: 0, // how many times through the variable set on this run of the node
@ -975,12 +976,6 @@ function TimelineNode(parameters, parent, relativeID) {
'Trial level node is missing the "type" parameter. The parameters for the node are: ' +
JSON.stringify(parameters)
);
} else if (
typeof trial_type == "undefined" &&
trial_type.toString().replace(/\s/g, "") !=
"function(){returntimeline.timelineVariable(varname);}"
) {
console.error('No plugin loaded for trials of type "' + trial_type + '"');
}
// create a deep copy of the parameters for the trial
trial_parameters = Object.assign({}, parameters);
@ -1338,7 +1333,7 @@ var progress_bar_amount = 0;
jsPsych.setProgressBar = function (proportion_complete) {
proportion_complete = Math.max(Math.min(1, proportion_complete), 0);
document.querySelector("#jspsych-progressbar-inner").style.width =
document.querySelector<HTMLElement>("#jspsych-progressbar-inner").style.width =
proportion_complete * 100 + "%";
progress_bar_amount = proportion_complete;
};
@ -1350,15 +1345,14 @@ jsPsych.getProgressBarCompleted = function () {
//Leave a trace in the DOM that jspsych was loaded
document.documentElement.setAttribute("jspsych", "present");
jsPsych.internal = (function () {
var module = {};
// this flag is used to determine whether we are in a scope where
// jsPsych.timelineVariable() should be executed immediately or
// whether it should return a function to access the variable later.
module.call_immediate = false;
return module;
})();
jsPsych.internal = {
/**
* this flag is used to determine whether we are in a scope where
* jsPsych.timelineVariable() should be executed immediately or
* whether it should return a function to access the variable later.
*
**/
call_immediate: false,
};
export default jsPsych;

View File

@ -1,5 +1,5 @@
import jsPsych from "./";
import { flatten, unique } from "./utils";
import jsPsych from ".";
// keyboard listeners //
@ -364,13 +364,16 @@ export function getAudioBuffer(audioID) {
// check whether audio file already preloaded
if (typeof audio_buffers[audioID] == "undefined" || audio_buffers[audioID] == "tmp") {
// if audio is not already loaded, try to load it
function complete() {
resolve(audio_buffers[audioID]);
}
function error(e) {
reject(e.error);
}
preloadAudio([audioID], complete, function () {}, error);
preloadAudio(
[audioID],
() => {
resolve(audio_buffers[audioID]);
},
() => {},
(e) => {
reject(e.error);
}
);
} else {
// audio is already loaded
resolve(audio_buffers[audioID]);
@ -399,8 +402,7 @@ export function preloadAudio(files, callback_complete, callback_load, callback_e
return;
}
function load_audio_file_webaudio(source, count) {
count = count || 1;
function load_audio_file_webaudio(source, count = 1) {
var request = new XMLHttpRequest();
request.open("GET", source, true);
request.responseType = "arraybuffer";
@ -421,7 +423,7 @@ export function preloadAudio(files, callback_complete, callback_load, callback_e
);
};
request.onerror = function (e) {
var err = e;
var err: ProgressEvent | string = e;
if (this.status == 404) {
err = "404";
}
@ -436,8 +438,7 @@ export function preloadAudio(files, callback_complete, callback_load, callback_e
preload_requests.push(request);
}
function load_audio_file_html5audio(source, count) {
count = count || 1;
function load_audio_file_html5audio(source, count = 1) {
var audio = new Audio();
audio.addEventListener("canplaythrough", function handleCanPlayThrough() {
audio_buffers[source] = audio;
@ -535,8 +536,7 @@ export function preloadVideo(video, callback_complete, callback_load, callback_e
return;
}
function preload_video(source, count) {
count = count || 1;
function preload_video(source, count = 1) {
//based on option 4 here: http://dinbror.dk/blog/how-to-preload-entire-html5-video-before-play-solved/
var request = new XMLHttpRequest();
request.open("GET", source, true);
@ -553,7 +553,7 @@ export function preloadVideo(video, callback_complete, callback_load, callback_e
}
};
request.onerror = function (e) {
var err = e;
var err: ProgressEvent | string = e;
if (this.status == 404) {
err = "404";
}
@ -589,8 +589,8 @@ export function registerPreload(plugin_name, parameter, media_type) {
preloads.push(preload);
}
export function getAutoPreloadList(timeline_description) {
function getTrialsOfTypeFromTimelineDescription(td, target_type, inherited_type) {
export function getAutoPreloadList(timeline_description?) {
function getTrialsOfTypeFromTimelineDescription(td, target_type, inherited_type?) {
var trials = [];
for (var i = 0; i < td.length; i++) {

View File

@ -22,7 +22,7 @@ export function repeat(array, repetitions, unpack) {
repetitions = reps;
} else {
if (array.length != repetitions.length) {
console.warning(
console.warn(
"Unclear parameters given to randomization.repeat. Items and repetitions are unequal lengths. Behavior may not be as expected."
);
// throw warning if repetitions is too short, use first rep ONLY.

View File

@ -2,7 +2,7 @@
// containing the workerID, assignmentID, and hitID, and whether or not the HIT is in
// preview mode, meaning that they haven't accepted the HIT yet.
export function turkInfo() {
var turk = {};
var turk = <any>{};
var param = function (url, name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
@ -24,14 +24,15 @@ export function turkInfo() {
turk.outsideTurk =
!turk.previewMode && turk.hitId === "" && turk.assignmentId == "" && turk.workerId == "";
turk_info = turk;
// TODO Was this intended to set a global variable?
// turk_info = turk;
return turk;
}
// core.submitToTurk will submit a MechanicalTurk ExternalHIT type
export function submitToTurk(data) {
var turkInfo = jsPsych.turk.turkInfo();
var turkInfo = turkInfo();
var assignmentId = turkInfo.assignmentId;
var turkSubmitTo = turkInfo.turkSubmitTo;

View File

@ -1,6 +1,6 @@
// methods used in multiple modules //
export function flatten(arr, out) {
export function flatten(arr, out?) {
out = typeof out === "undefined" ? [] : out;
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {

View File

@ -13,7 +13,7 @@ describe("The css_classes parameter for trials", function () {
jsPsych.init({ timeline: [trial] });
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(true);
expect(jsPsych.getDisplayElement().classList).toContain("foo");
pressKey("a");
});
@ -26,7 +26,7 @@ describe("The css_classes parameter for trials", function () {
jsPsych.init({ timeline: [trial] });
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(true);
expect(jsPsych.getDisplayElement().classList).toContain("foo");
pressKey("a");
});
@ -39,9 +39,9 @@ describe("The css_classes parameter for trials", function () {
jsPsych.init({ timeline: [trial] });
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(true);
expect(jsPsych.getDisplayElement().classList).toContain("foo");
pressKey("a");
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(false);
expect(jsPsych.getDisplayElement().classList).not.toContain("foo");
});
test("Class inherits in nested timelines", function () {
@ -57,9 +57,9 @@ describe("The css_classes parameter for trials", function () {
jsPsych.init({ timeline: [tm] });
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(true);
expect(jsPsych.getDisplayElement().classList).toContain("foo");
pressKey("a");
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(false);
expect(jsPsych.getDisplayElement().classList).not.toContain("foo");
});
test("Parameter works when defined as a function", function () {
@ -73,9 +73,9 @@ describe("The css_classes parameter for trials", function () {
jsPsych.init({ timeline: [trial] });
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(true);
expect(jsPsych.getDisplayElement().classList).toContain("foo");
pressKey("a");
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(false);
expect(jsPsych.getDisplayElement().classList).not.toContain("foo");
});
test("Parameter works when defined as a timeline variable", function () {
@ -92,8 +92,8 @@ describe("The css_classes parameter for trials", function () {
jsPsych.init({ timeline: [t] });
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(true);
expect(jsPsych.getDisplayElement().classList).toContain("foo");
pressKey("a");
expect(jsPsych.getDisplayElement().classList.contains("foo")).toBe(false);
expect(jsPsych.getDisplayElement().classList).not.toContain("foo");
});
});

View File

@ -25,6 +25,7 @@ describe("nested defaults", function () {
});
test("safe against extending the array.prototype (issue #989)", function () {
// @ts-expect-error
Array.prototype.qq = jest.fn();
const spy = jest.spyOn(console, "error").mockImplementation();

View File

@ -6,7 +6,7 @@ import { pressKey } from "../utils";
describe("on_finish (trial)", function () {
test("should get an object of data generated by the trial", function () {
return new Promise(function (resolve, reject) {
return new Promise<any>(function (resolve, reject) {
var key_data = null;
var trial = {
@ -31,8 +31,8 @@ describe("on_finish (trial)", function () {
});
test("should be able to write to the data", function () {
return new Promise(function (resolve, reject) {
var promise_data = {};
return new Promise<any>(function (resolve, reject) {
var promise_data = <any>{};
var trial = {
type: htmlKeyboardResponse,
@ -120,8 +120,8 @@ describe("on_start (trial)", function () {
describe("on_trial_finish (experiment level)", function () {
test("should get an object containing the trial data", function () {
return new Promise(function (resolve, reject) {
var promise_data = {};
return new Promise<any>(function (resolve, reject) {
var promise_data = <any>{};
var trial = {
type: htmlKeyboardResponse,
@ -147,8 +147,8 @@ describe("on_trial_finish (experiment level)", function () {
});
test("should allow writing to the data object", function () {
return new Promise(function (resolve, reject) {
var promise_data = {};
return new Promise<any>(function (resolve, reject) {
var promise_data = <any>{};
var trial = {
type: htmlKeyboardResponse,
@ -177,8 +177,8 @@ describe("on_trial_finish (experiment level)", function () {
describe("on_data_update", function () {
test("should get an object containing the trial data", function () {
return new Promise(function (resolve, reject) {
var promise_data = {};
return new Promise<any>(function (resolve, reject) {
var promise_data = <any>{};
var trial = {
type: htmlKeyboardResponse,
@ -239,8 +239,8 @@ describe("on_data_update", function () {
});
test("should contain data added with on_finish (trial level)", function () {
return new Promise(function (resolve, reject) {
var promise_data = {};
return new Promise<any>(function (resolve, reject) {
var promise_data = <any>{};
var trial = {
type: htmlKeyboardResponse,
@ -269,8 +269,8 @@ describe("on_data_update", function () {
});
test("should contain data added with on_trial_finish (experiment level)", function () {
return new Promise(function (resolve, reject) {
var promise_data = {};
return new Promise<any>(function (resolve, reject) {
var promise_data = <any>{};
var trial = {
type: htmlKeyboardResponse,
@ -301,8 +301,8 @@ describe("on_data_update", function () {
describe("on_trial_start", function () {
test("should get an object containing the trial properties", function () {
return new Promise(function (resolve, reject) {
var promise_data = {};
return new Promise<any>(function (resolve, reject) {
var promise_data = <any>{};
var trial = {
type: htmlKeyboardResponse,

View File

@ -48,23 +48,25 @@ describe("automatic progress bar", function () {
show_progress_bar: true,
});
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("");
const progressbarElement = document.querySelector<HTMLElement>("#jspsych-progressbar-inner");
expect(progressbarElement.style.width).toBe("");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("25%");
expect(progressbarElement.style.width).toBe("25%");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("50%");
expect(progressbarElement.style.width).toBe("50%");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("75%");
expect(progressbarElement.style.width).toBe("75%");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("100%");
expect(progressbarElement.style.width).toBe("100%");
});
test("progress bar does not automatically update when auto_update_progress_bar is false", function () {
@ -79,23 +81,25 @@ describe("automatic progress bar", function () {
auto_update_progress_bar: false,
});
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("");
const progressbarElement = document.querySelector<HTMLElement>("#jspsych-progressbar-inner");
expect(progressbarElement.style.width).toBe("");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("");
expect(progressbarElement.style.width).toBe("");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("");
expect(progressbarElement.style.width).toBe("");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("");
expect(progressbarElement.style.width).toBe("");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("");
expect(progressbarElement.style.width).toBe("");
});
test("setProgressBar() manually", function () {
@ -121,15 +125,17 @@ describe("automatic progress bar", function () {
auto_update_progress_bar: false,
});
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("");
const progressbarElement = document.querySelector<HTMLElement>("#jspsych-progressbar-inner");
expect(progressbarElement.style.width).toBe("");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("20%");
expect(progressbarElement.style.width).toBe("20%");
pressKey("a");
expect(document.querySelector("#jspsych-progressbar-inner").style.width).toBe("80%");
expect(progressbarElement.style.width).toBe("80%");
});
test("getProgressBarCompleted() -- manual updates", function () {

View File

@ -18,8 +18,8 @@ describe("data conversion to csv", function () {
jsPsych.init({ timeline });
document.querySelector("#input-0").value = "Response 1";
document.querySelector("#input-1").value = "Response 2";
document.querySelector<HTMLInputElement>("#input-0").value = "Response 1";
document.querySelector<HTMLInputElement>("#input-1").value = "Response 2";
clickTarget(document.querySelector("#jspsych-survey-text-next"));

View File

@ -19,8 +19,8 @@ describe("data conversion to json", function () {
jsPsych.init({ timeline });
document.querySelector("#input-0").value = "Response 1";
document.querySelector("#input-1").value = "Response 2";
document.querySelector<HTMLInputElement>("#input-0").value = "Response 1";
document.querySelector<HTMLInputElement>("#input-1").value = "Response 2";
clickTarget(document.querySelector("#jspsych-survey-text-next"));

View File

@ -1,4 +1,4 @@
const extension = {};
const extension = <any>{};
// private state for the extension
// extension authors can define public functions to interact
@ -9,7 +9,7 @@ var state = {};
// required, will be called at jsPsych.init
// should return a Promise
extension.initialize = function (params) {
return new Promise(function (resolve, reject) {
return new Promise<void>(function (resolve, reject) {
resolve();
});
};

View File

@ -404,7 +404,7 @@ describe("#compareKeys", function () {
expect(pluginAPI.compareKeys("q", "q")).toBe(true);
});
test("should accept null as argument, and return true if both arguments are null, and return false if one argument is null and other is string or numeric", function () {
const spy = jest.spyOn(console, "error").mockImplementation();
const spy = jest.spyOn(console, "error").mockImplementation(() => {});
expect(pluginAPI.compareKeys(null, "Q")).toBe(false);
expect(pluginAPI.compareKeys(80, null)).toBe(false);
expect(pluginAPI.compareKeys(null, null)).toBe(true);
@ -412,7 +412,7 @@ describe("#compareKeys", function () {
spy.mockRestore();
});
test("should return undefined and produce a console warning if either/both arguments are not a string, integer, or null", function () {
const spy = jest.spyOn(console, "error").mockImplementation();
const spy = jest.spyOn(console, "error").mockImplementation(() => {});
var t1 = pluginAPI.compareKeys({}, "Q");
var t2 = pluginAPI.compareKeys(true, null);
var t3 = pluginAPI.compareKeys(null, ["Q"]);
@ -420,7 +420,7 @@ describe("#compareKeys", function () {
expect(typeof t2).toBe("undefined");
expect(typeof t3).toBe("undefined");
expect(console.error).toHaveBeenCalledTimes(3);
expect(console.error.mock.calls).toEqual([
expect(spy.mock.calls).toEqual([
[
"Error in jsPsych.pluginAPI.compareKeys: arguments must be numeric key codes, key strings, or null.",
],

View File

@ -1,10 +1,10 @@
export function pressKey(key) {
document
.querySelector(".jspsych-display-element")
.dispatchEvent(new KeyboardEvent("keydown", { key: key }));
.dispatchEvent(new KeyboardEvent("keydown", { key }));
document
.querySelector(".jspsych-display-element")
.dispatchEvent(new KeyboardEvent("keyup", { key: key }));
.dispatchEvent(new KeyboardEvent("keyup", { key }));
}
export function mouseDownMouseUpTarget(target) {

View File

@ -0,0 +1,7 @@
{
"extends": "@jspsych/config/tsconfig.json",
"compilerOptions": {
"resolveJsonModule": false // using https://stackoverflow.com/a/61426303 instead
},
"exclude": ["./tests"]
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jsPsych plugin for showing animations and recording keyboard responses",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -1,7 +1,7 @@
import { jest } from "@jest/globals";
import jsPsych from "jspsych";
import animation from "./";
import animation from ".";
jest.useFakeTimers();

View File

@ -7,7 +7,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
jsPsych.pluginAPI.registerPreload("animation", "stimuli", "image");
@ -83,8 +83,8 @@ plugin.trial = function (display_element, trial) {
}
var canvas = document.createElement("canvas");
canvas.id = "jspsych-animation-image";
canvas.style.margin = 0;
canvas.style.padding = 0;
canvas.style.margin = "0";
canvas.style.padding = "0";
display_element.insertBefore(canvas, null);
var ctx = canvas.getContext("2d");
}
@ -117,7 +117,7 @@ plugin.trial = function (display_element, trial) {
canvas.height = img.naturalHeight;
canvas.width = img.naturalWidth;
ctx.drawImage(img, 0, 0);
if ((trial.prompt !== null) & (animate_frame == 0) & (reps == 0)) {
if (trial.prompt !== null && animate_frame == 0 && reps == 0) {
display_element.insertAdjacentHTML("beforeend", trial.prompt);
}
} else {

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jsPsych plugin for playing an audio file and getting a button response",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs --passWithNoTests",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -10,7 +10,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
jsPsych.pluginAPI.registerPreload("audio-button-response", "stimulus", "audio");
@ -127,7 +127,7 @@ plugin.trial = function (display_element, trial) {
}
// enable buttons after audio ends if necessary
if (!trial.response_allowed_while_playing & !trial.trial_ends_after_audio) {
if (!trial.response_allowed_while_playing && !trial.trial_ends_after_audio) {
audio.addEventListener("ended", enable_buttons);
}

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jsPsych plugin for playing an audio file and getting a keyboard response",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs --passWithNoTests",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -10,7 +10,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
jsPsych.pluginAPI.registerPreload("audio-keyboard-response", "stimulus", "audio");

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs --passWithNoTests",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -1,6 +1,6 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
jsPsych.pluginAPI.registerPreload("audio-slider-response", "stimulus", "audio");
@ -135,7 +135,7 @@ plugin.trial = function (display_element, trial) {
}
// enable slider after audio ends if necessary
if (!trial.response_allowed_while_playing & !trial.trial_ends_after_audio) {
if (!trial.response_allowed_while_playing && !trial.trial_ends_after_audio) {
audio.addEventListener("ended", enable_slider);
}
@ -191,7 +191,7 @@ plugin.trial = function (display_element, trial) {
// add submit button
var next_disabled_attribute = "";
if (trial.require_movement | !trial.response_allowed_while_playing) {
if (trial.require_movement || !trial.response_allowed_while_playing) {
next_disabled_attribute = "disabled";
}
html +=
@ -262,9 +262,11 @@ plugin.trial = function (display_element, trial) {
// function to enable slider after audio ends
function enable_slider() {
document.querySelector("#jspsych-audio-slider-response-response").disabled = false;
document.querySelector<HTMLInputElement>("#jspsych-audio-slider-response-response").disabled =
false;
if (!trial.require_movement) {
document.querySelector("#jspsych-audio-slider-response-next").disabled = false;
document.querySelector<HTMLButtonElement>("#jspsych-audio-slider-response-next").disabled =
false;
}
}

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jsPsych plugin for calling an arbitrary function during a jspsych experiment",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -1,7 +1,7 @@
import { jest } from "@jest/globals";
import jsPsych from "jspsych";
import callFunction from "./";
import callFunction from ".";
jest.useFakeTimers();

View File

@ -9,7 +9,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
plugin.info = {
name: "call-function",

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jsPsych plugin for displaying a canvas stimulus and getting a button response",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs --passWithNoTests",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -10,7 +10,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
plugin.info = {
name: "canvas-button-response",

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jsPsych plugin for displaying a canvas stimulus and getting a keyboard response",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs --passWithNoTests",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -10,7 +10,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
plugin.info = {
name: "canvas-keyboard-response",

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jsPsych plugin for displaying a canvas stimulus and getting a slider response",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs --passWithNoTests",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -10,7 +10,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
plugin.info = {
name: "canvas-slider-response",

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jspsych plugin for categorization trials with feedback and animated stimuli",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -2,7 +2,7 @@ import { jest } from "@jest/globals";
import jsPsych from "jspsych";
import { pressKey } from "jspsych/tests/utils";
import categorizeAnimation from "./";
import categorizeAnimation from ".";
jest.useFakeTimers();

View File

@ -7,7 +7,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
jsPsych.pluginAPI.registerPreload("categorize-animation", "stimuli", "image");
@ -113,8 +113,8 @@ plugin.trial = function (display_element, trial) {
}
var canvas = document.createElement("canvas");
canvas.id = "jspsych-categorize-animation-stimulus";
canvas.style.margin = 0;
canvas.style.padding = 0;
canvas.style.margin = "0";
canvas.style.padding = "0";
display_element.insertBefore(canvas, null);
var ctx = canvas.getContext("2d");
if (trial.prompt !== null) {
@ -222,6 +222,7 @@ plugin.trial = function (display_element, trial) {
var keyboard_listener;
var trial_data = {};
// @ts-ignore
var after_response = function (info) {
// ignore the response if animation is playing and subject
// not allowed to respond before it is complete

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jspsych plugin for categorization trials with feedback",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs --passWithNoTests",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -7,7 +7,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
plugin.info = {
name: "categorize-html",

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jspsych plugin for categorization trials with feedback",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs --passWithNoTests",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -7,7 +7,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
jsPsych.pluginAPI.registerPreload("categorize-image", "stimulus", "image");

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

View File

@ -3,16 +3,19 @@
"version": "1.0.0",
"description": "jsPsych plugin for displaying a cloze test and checking participants answers against a correct solution",
"type": "module",
"main": "src/index.js",
"unpkg": "dist/index.min.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest --config jest.config.cjs",
"build": "rollup --config rollup.config.mjs",
"watch": "npm run build -- --watch"
"watch": "npm run build -- --watch",
"tsc": "tsc"
},
"repository": {
"type": "git",

View File

@ -2,10 +2,12 @@ import { jest } from "@jest/globals";
import jsPsych from "jspsych";
import { clickTarget } from "jspsych/tests/utils";
import cloze from "./";
import cloze from ".";
jest.useFakeTimers();
const getIntpuElementById = (id: string) => document.getElementById(id) as HTMLInputElement;
describe("cloze", function () {
test("displays cloze", function () {
var trial = {
@ -82,7 +84,7 @@ describe("cloze", function () {
timeline: [trial],
});
document.getElementById("input0").value = "cloze";
getIntpuElementById("input0").value = "cloze";
clickTarget(document.querySelector("#finish_cloze_button"));
expect(jsPsych.getDisplayElement().innerHTML).toBe("");
});
@ -98,7 +100,7 @@ describe("cloze", function () {
timeline: [trial],
});
document.getElementById("input0").value = "some wrong answer";
getIntpuElementById("input0").value = "some wrong answer";
clickTarget(document.querySelector("#finish_cloze_button"));
expect(jsPsych.getDisplayElement().innerHTML).not.toBe("");
});
@ -118,7 +120,7 @@ describe("cloze", function () {
});
var called = false;
document.getElementById("input0").value = "cloze";
getIntpuElementById("input0").value = "cloze";
clickTarget(document.querySelector("#finish_cloze_button"));
expect(called).not.toBeTruthy();
});
@ -138,7 +140,7 @@ describe("cloze", function () {
});
var called = false;
document.getElementById("input0").value = "some wrong answer";
getIntpuElementById("input0").value = "some wrong answer";
clickTarget(document.querySelector("#finish_cloze_button"));
expect(called).toBeTruthy();
});
@ -153,8 +155,8 @@ describe("cloze", function () {
timeline: [trial],
});
document.getElementById("input0").value = "cloze1";
document.getElementById("input1").value = "cloze2";
getIntpuElementById("input0").value = "cloze1";
getIntpuElementById("input1").value = "cloze2";
clickTarget(document.querySelector("#finish_cloze_button"));
var data = jsPsych.data.get().values()[0].response;
expect(data.length).toBe(2);

View File

@ -9,7 +9,7 @@
import jsPsych from "jspsych";
const plugin = {};
const plugin = <any>{};
plugin.info = {
name: "cloze",
@ -67,7 +67,7 @@ plugin.trial = function (display_element, trial) {
var answers_correct = true;
for (var i = 0; i < solutions.length; i++) {
var field = document.getElementById("input" + i);
var field = document.getElementById("input" + i) as HTMLInputElement;
answers.push(field.value.trim());
if (trial.check_answers) {

View File

@ -0,0 +1,3 @@
{
"extends": "@jspsych/config/tsconfig.json"
}

View File

@ -1,4 +1 @@
const { makePackageConfig } = require("@jspsych/config/jest");
const packageJson = require("./package.json");
module.exports = makePackageConfig(packageJson);
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);

Some files were not shown because too many files have changed in this diff Show More