mirror of
https://github.com/jspsych/jsPsych.git
synced 2025-05-10 11:10:54 +00:00
Merge pull request #3484 from jspsych/fix-build-citations-test
handle citation test edge case
This commit is contained in:
commit
6e7476784c
6
.changeset/rich-fans-jump.md
Normal file
6
.changeset/rich-fans-jump.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"jspsych": patch
|
||||
"@jspsych/config": patch
|
||||
---
|
||||
|
||||
Patches some edge cases for `getCitations` and the build process that reads CITATION.CFF files to include citation info
|
27
package-lock.json
generated
27
package-lock.json
generated
@ -16074,6 +16074,7 @@
|
||||
"@sucrase/jest-plugin": "3.0.0",
|
||||
"@types/gulp": "4.0.17",
|
||||
"@types/jest": "29.5.8",
|
||||
"@types/node": "^22.10.10",
|
||||
"alias-hq": "6.2.4",
|
||||
"app-root-path": "^3.1.0",
|
||||
"canvas": "^2.11.2",
|
||||
@ -16095,13 +16096,20 @@
|
||||
"rollup-plugin-node-externals": "7.1.3",
|
||||
"sucrase": "3.34.0",
|
||||
"tslib": "2.6.2",
|
||||
"typescript": "^5.2.2",
|
||||
"yaml": "^2.5.1"
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"packages/config/node_modules/@types/node": {
|
||||
"version": "22.10.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.10.tgz",
|
||||
"integrity": "sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"packages/config/node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@ -16142,17 +16150,10 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"packages/config/node_modules/yaml": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz",
|
||||
"integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
"packages/config/node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
|
||||
},
|
||||
"packages/extension-mouse-tracking": {
|
||||
"name": "@jspsych/extension-mouse-tracking",
|
||||
|
@ -7,7 +7,6 @@ import path from "node:path";
|
||||
|
||||
import { Cite } from "@citation-js/core";
|
||||
import appRootPath from "app-root-path";
|
||||
import yaml from "yaml";
|
||||
|
||||
/**
|
||||
* Generate citation data from CITATION.cff file
|
||||
@ -23,11 +22,8 @@ export default function generateCitations() {
|
||||
let rawCff;
|
||||
const getCff = (path) => {
|
||||
rawCff = fs.readFileSync(path, "utf-8").toString();
|
||||
const cffData = yaml.parse(rawCff);
|
||||
if (cffData["preferred-citation"]) {
|
||||
preferredCitation = true;
|
||||
}
|
||||
return yaml.stringify(rawCff);
|
||||
preferredCitation = rawCff.includes("preferred-citation:");
|
||||
return rawCff;
|
||||
};
|
||||
|
||||
try {
|
||||
@ -80,7 +76,7 @@ export default function generateCitations() {
|
||||
return citationBibtex;
|
||||
} catch (error) {
|
||||
console.log(`Error converting CITATION.cff to BibTeX string: ${error.message}`);
|
||||
return null;
|
||||
return "";
|
||||
}
|
||||
})();
|
||||
|
||||
|
1
packages/config/jest.config.cjs
Normal file
1
packages/config/jest.config.cjs
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require("./jest.cjs").makePackageConfig(__dirname);
|
@ -3,6 +3,10 @@
|
||||
"version": "3.2.1",
|
||||
"description": "Shared (build) configuration for jsPsych packages",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"test:watch": "npm test -- --watch"
|
||||
},
|
||||
"exports": {
|
||||
"./gulp": {
|
||||
"import": "./gulp.js",
|
||||
@ -45,6 +49,7 @@
|
||||
"@sucrase/jest-plugin": "3.0.0",
|
||||
"@types/gulp": "4.0.17",
|
||||
"@types/jest": "29.5.8",
|
||||
"@types/node": "^22.10.10",
|
||||
"alias-hq": "6.2.4",
|
||||
"app-root-path": "^3.1.0",
|
||||
"canvas": "^2.11.2",
|
||||
@ -66,7 +71,6 @@
|
||||
"rollup-plugin-node-externals": "7.1.3",
|
||||
"sucrase": "3.34.0",
|
||||
"tslib": "2.6.2",
|
||||
"typescript": "^5.2.2",
|
||||
"yaml": "^2.5.1"
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
|
94
packages/config/tests/generateCitations.test.js
Normal file
94
packages/config/tests/generateCitations.test.js
Normal file
@ -0,0 +1,94 @@
|
||||
import fs from "node:fs";
|
||||
|
||||
import generateCitations from "../generateCitations";
|
||||
|
||||
// Mock filesystem
|
||||
jest.mock("node:fs");
|
||||
jest.mock("app-root-path", () => ({
|
||||
path: "/mock/root/path",
|
||||
}));
|
||||
|
||||
describe("generateCitations", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const validCitationCff = `
|
||||
cff-version: 1.2.0
|
||||
message: Please cite this software using these metadata
|
||||
title: Test Software
|
||||
authors:
|
||||
- family-names: Doe
|
||||
given-names: John
|
||||
version: 1.0.0
|
||||
date-released: 2023-01-01
|
||||
`;
|
||||
|
||||
const citationCffWithPreferred = `
|
||||
cff-version: 1.2.0
|
||||
message: Please cite this software using these metadata
|
||||
title: Test Software
|
||||
authors:
|
||||
- family-names: Doe
|
||||
given-names: John
|
||||
preferred-citation:
|
||||
title: Preferred Citation
|
||||
authors:
|
||||
- family-names: Smith
|
||||
given-names: Jane
|
||||
`;
|
||||
|
||||
test("should generate citations when CITATION.cff exists in current directory", () => {
|
||||
fs.readFileSync.mockReturnValue(validCitationCff);
|
||||
|
||||
const result = generateCitations();
|
||||
|
||||
expect(result).toHaveProperty("apa");
|
||||
expect(result).toHaveProperty("bibtex");
|
||||
expect(result.apa).not.toBe("");
|
||||
expect(result.bibtex).not.toBe("");
|
||||
});
|
||||
|
||||
test("should handle preferred-citation when present", () => {
|
||||
fs.readFileSync.mockReturnValue(citationCffWithPreferred);
|
||||
|
||||
const result = generateCitations();
|
||||
|
||||
expect(result).toHaveProperty("apa");
|
||||
expect(result).toHaveProperty("bibtex");
|
||||
expect(result.apa.includes("Smith")).toBeTruthy();
|
||||
});
|
||||
|
||||
test("should return empty strings when CITATION.cff is not found", () => {
|
||||
fs.readFileSync.mockImplementation(() => {
|
||||
throw new Error("File not found");
|
||||
});
|
||||
|
||||
const result = generateCitations();
|
||||
|
||||
expect(result).toEqual({
|
||||
apa: "",
|
||||
bibtex: "",
|
||||
});
|
||||
});
|
||||
|
||||
test("should handle malformed CITATION.cff", () => {
|
||||
fs.readFileSync.mockReturnValue("invalid: yaml: content:");
|
||||
|
||||
const result = generateCitations();
|
||||
|
||||
expect(result).toEqual({
|
||||
apa: "",
|
||||
bibtex: "",
|
||||
});
|
||||
});
|
||||
|
||||
test("should remove newlines from citations", () => {
|
||||
fs.readFileSync.mockReturnValue(validCitationCff);
|
||||
|
||||
const result = generateCitations();
|
||||
|
||||
expect(result.apa).not.toMatch(/\n/);
|
||||
expect(result.bibtex).not.toMatch(/\n/);
|
||||
});
|
||||
});
|
@ -36,6 +36,9 @@ export class JsPsych {
|
||||
return version;
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
private citation: any = '__CITATIONS__';
|
||||
|
||||
/** Options */
|
||||
private options: any = {};
|
||||
|
||||
@ -274,8 +277,6 @@ export class JsPsych {
|
||||
format: "apa" | "bibtex" = "apa"
|
||||
) {
|
||||
const formatOptions = ["apa", "bibtex"];
|
||||
// prettier-ignore
|
||||
const jsPsychCitations: any = '__CITATIONS__';
|
||||
format = format.toLowerCase() as "apa" | "bibtex";
|
||||
// Check if plugins is an array
|
||||
if (!Array.isArray(plugins)) {
|
||||
@ -287,7 +288,7 @@ export class JsPsych {
|
||||
}
|
||||
// Print citations
|
||||
else {
|
||||
const jsPsychCitation = jsPsychCitations[format];
|
||||
const jsPsychCitation = this.citation[format];
|
||||
const citationSet = new Set([jsPsychCitation]);
|
||||
|
||||
for (const plugin of plugins) {
|
||||
|
@ -1,94 +1,76 @@
|
||||
import { initJsPsych } from "../../src";
|
||||
import { TestExtension } from "../extensions/TestExtension";
|
||||
import TestPlugin from "../TestPlugin";
|
||||
|
||||
const jsPsychApaCitation =
|
||||
"de Leeuw, J. R., Gilbert, R. A., & Luchterhandt, B. (2023). jsPsych: Enabling an Open-Source Collaborative Ecosystem of Behavioral Experiments. Journal of Open Source Software, 8(85), 5351. https://doi.org/10.21105/joss.05351 ";
|
||||
const jsPsychBibtexCitation =
|
||||
'@article{Leeuw2023jsPsych, author = {de Leeuw, Joshua R. and Gilbert, Rebecca A. and Luchterhandt, Bj{\\" o}rn}, journal = {Journal of Open Source Software}, doi = {10.21105/joss.05351}, issn = {2475-9066}, number = {85}, year = {2023}, month = {may 11}, pages = {5351}, publisher = {Open Journals}, title = {jsPsych: Enabling an {Open}-{Source} {Collaborative} {Ecosystem} of {Behavioral} {Experiments}}, url = {https://joss.theoj.org/papers/10.21105/joss.05351}, volume = {8}, } ';
|
||||
const jsPsychApaCitation = "Test base APA citation";
|
||||
const jsPsychBibtexCitation = "Test base BibTeX citation";
|
||||
const testPluginApaCitation = "Test plugin APA citation";
|
||||
const testPluginBibtexCitation = "Test plugin BibTeX citation";
|
||||
const testExtensionApaCitation = "Test extension APA citation";
|
||||
|
||||
let JsPsych;
|
||||
let jspsych;
|
||||
|
||||
/**
|
||||
* These tests are skipped if the built version of JsPsych is not found.
|
||||
* This is because the citation functionality is only available in the built version
|
||||
* due to code injections that run during the build.
|
||||
*/
|
||||
beforeEach(() => {
|
||||
jspsych = initJsPsych();
|
||||
(jspsych as any).citation = {
|
||||
apa: "Test base APA citation",
|
||||
bibtex: "Test base BibTeX citation",
|
||||
};
|
||||
});
|
||||
|
||||
try {
|
||||
// Try to import built version
|
||||
JsPsych = require("../../dist/index").JsPsych;
|
||||
let jspsych: typeof JsPsych;
|
||||
|
||||
beforeEach(() => {
|
||||
jspsych = new JsPsych();
|
||||
describe("citing not using an array", () => {
|
||||
test("citing without input", () => {
|
||||
expect(jspsych.getCitations()).toBe(jsPsychApaCitation);
|
||||
});
|
||||
test("citing null", () => {
|
||||
expect(() => jspsych.getCitations(null)).toThrow("Expected array of plugins/extensions");
|
||||
});
|
||||
test("citing without input and with invalid format", () => {
|
||||
expect(() => jspsych.getCitations(null, "apa")).toThrow("Expected array of plugins/extensions");
|
||||
});
|
||||
});
|
||||
|
||||
describe("citing not using an array", () => {
|
||||
test("citing without input", () => {
|
||||
expect(jspsych.getCitations()).toBe(jsPsychApaCitation);
|
||||
});
|
||||
test("citing null", () => {
|
||||
expect(() => jspsych.getCitations(null)).toThrow("Expected array of plugins/extensions");
|
||||
});
|
||||
test("citing without input and with invalid format", () => {
|
||||
expect(() => jspsych.getCitations(null, "apa")).toThrow(
|
||||
"Expected array of plugins/extensions"
|
||||
);
|
||||
});
|
||||
describe("citing using an array in different formats", () => {
|
||||
test("citing empty array with APA format", () => {
|
||||
expect(jspsych.getCitations([], "apa")).toBe(jsPsychApaCitation);
|
||||
});
|
||||
test("citing empty array with BibTeX format", () => {
|
||||
expect(jspsych.getCitations([], "bibtex")).toBe(jsPsychBibtexCitation);
|
||||
});
|
||||
test("citing empty array without format", () => {
|
||||
expect(jspsych.getCitations([])).toBe(jsPsychApaCitation);
|
||||
});
|
||||
test("citing one plugin with valid format in all caps", () => {
|
||||
expect(jspsych.getCitations([TestPlugin], "APA")).toBe(
|
||||
jsPsychApaCitation + "\n" + testPluginApaCitation
|
||||
);
|
||||
});
|
||||
test("citing with unsupported format", () => {
|
||||
expect(() => jspsych.getCitations([TestPlugin], "DummyTex")).toThrow(
|
||||
"Unsupported citation format"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("citing using an array in different formats", () => {
|
||||
test("citing empty array with APA format", () => {
|
||||
expect(jspsych.getCitations([], "apa")).toBe(jsPsychApaCitation);
|
||||
});
|
||||
test("citing empty array with BibTeX format", () => {
|
||||
expect(jspsych.getCitations([], "bibtex")).toBe(jsPsychBibtexCitation);
|
||||
});
|
||||
test("citing empty array without format", () => {
|
||||
expect(jspsych.getCitations([])).toBe(jsPsychApaCitation);
|
||||
});
|
||||
test("citing one plugin with valid format in all caps", () => {
|
||||
expect(jspsych.getCitations([TestPlugin], "APA")).toBe(
|
||||
jsPsychApaCitation + "\n" + testPluginApaCitation
|
||||
);
|
||||
});
|
||||
test("citing with unsupported format", () => {
|
||||
expect(() => jspsych.getCitations([TestPlugin], "DummyTex")).toThrow(
|
||||
"Unsupported citation format"
|
||||
);
|
||||
});
|
||||
describe("citing mix of valid plugins/extensions", () => {
|
||||
test("citing a plugin", () => {
|
||||
expect(jspsych.getCitations([TestPlugin])).toBe(
|
||||
jsPsychApaCitation + "\n" + testPluginApaCitation
|
||||
);
|
||||
});
|
||||
|
||||
describe("citing mix of valid plugins/extensions", () => {
|
||||
test("citing a plugin", () => {
|
||||
expect(jspsych.getCitations([TestPlugin])).toBe(
|
||||
jsPsychApaCitation + "\n" + testPluginApaCitation
|
||||
);
|
||||
});
|
||||
test("citing a plugin in BibTeX", () => {
|
||||
expect(jspsych.getCitations([TestPlugin], "bibtex")).toBe(
|
||||
jsPsychBibtexCitation + "\n" + testPluginBibtexCitation
|
||||
);
|
||||
});
|
||||
test("citing multiple plugins", () => {
|
||||
expect(jspsych.getCitations([TestPlugin, TestPlugin])).toBe(
|
||||
jsPsychApaCitation + "\n" + testPluginApaCitation
|
||||
);
|
||||
});
|
||||
test("citing mix of plugins and extensions", () => {
|
||||
expect(jspsych.getCitations([TestPlugin, TestExtension])).toBe(
|
||||
jsPsychApaCitation + "\n" + testPluginApaCitation + "\n" + testExtensionApaCitation
|
||||
);
|
||||
});
|
||||
test("citing a plugin in BibTeX", () => {
|
||||
expect(jspsych.getCitations([TestPlugin], "bibtex")).toBe(
|
||||
jsPsychBibtexCitation + "\n" + testPluginBibtexCitation
|
||||
);
|
||||
});
|
||||
} catch (e) {
|
||||
// Fall back to development version if built version not found
|
||||
describe("skipping citation tests because of missing built version", () => {
|
||||
test.skip("skip", () => {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
test("citing multiple plugins", () => {
|
||||
expect(jspsych.getCitations([TestPlugin, TestPlugin])).toBe(
|
||||
jsPsychApaCitation + "\n" + testPluginApaCitation
|
||||
);
|
||||
});
|
||||
}
|
||||
test("citing mix of plugins and extensions", () => {
|
||||
expect(jspsych.getCitations([TestPlugin, TestExtension])).toBe(
|
||||
jsPsychApaCitation + "\n" + testPluginApaCitation + "\n" + testExtensionApaCitation
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -542,8 +542,6 @@ describe("data simulation mode", () => {
|
||||
|
||||
const data = getData().values()[1];
|
||||
|
||||
console.log(data);
|
||||
|
||||
expect(data.rt).toBeGreaterThan(0);
|
||||
expect(data.response).toBeDefined();
|
||||
});
|
||||
|
@ -155,8 +155,6 @@ describe("instructions plugin simulation", () => {
|
||||
|
||||
const data = getData().values()[0];
|
||||
|
||||
console.log(data.view_history);
|
||||
|
||||
expect(data.rt).toBe(4000);
|
||||
|
||||
let sum_view_history_rt = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user