rework citation testing

This commit is contained in:
Josh de Leeuw 2025-01-27 15:37:37 -05:00
parent ad6c988449
commit b12ce3051d
7 changed files with 182 additions and 107 deletions

27
package-lock.json generated
View File

@ -16074,6 +16074,7 @@
"@sucrase/jest-plugin": "3.0.0", "@sucrase/jest-plugin": "3.0.0",
"@types/gulp": "4.0.17", "@types/gulp": "4.0.17",
"@types/jest": "29.5.8", "@types/jest": "29.5.8",
"@types/node": "^22.10.10",
"alias-hq": "6.2.4", "alias-hq": "6.2.4",
"app-root-path": "^3.1.0", "app-root-path": "^3.1.0",
"canvas": "^2.11.2", "canvas": "^2.11.2",
@ -16095,13 +16096,20 @@
"rollup-plugin-node-externals": "7.1.3", "rollup-plugin-node-externals": "7.1.3",
"sucrase": "3.34.0", "sucrase": "3.34.0",
"tslib": "2.6.2", "tslib": "2.6.2",
"typescript": "^5.2.2", "typescript": "^5.2.2"
"yaml": "^2.5.1"
}, },
"engines": { "engines": {
"node": ">=18.0.0" "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": { "packages/config/node_modules/brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -16142,17 +16150,10 @@
"node": "*" "node": "*"
} }
}, },
"packages/config/node_modules/yaml": { "packages/config/node_modules/undici-types": {
"version": "2.6.0", "version": "6.20.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14"
}
}, },
"packages/extension-mouse-tracking": { "packages/extension-mouse-tracking": {
"name": "@jspsych/extension-mouse-tracking", "name": "@jspsych/extension-mouse-tracking",

View File

@ -7,7 +7,6 @@ import path from "node:path";
import { Cite } from "@citation-js/core"; import { Cite } from "@citation-js/core";
import appRootPath from "app-root-path"; import appRootPath from "app-root-path";
import yaml from "yaml";
/** /**
* Generate citation data from CITATION.cff file * Generate citation data from CITATION.cff file
@ -23,11 +22,8 @@ export default function generateCitations() {
let rawCff; let rawCff;
const getCff = (path) => { const getCff = (path) => {
rawCff = fs.readFileSync(path, "utf-8").toString(); rawCff = fs.readFileSync(path, "utf-8").toString();
const cffData = yaml.parse(rawCff); preferredCitation = rawCff.includes("preferred-citation:");
if (cffData["preferred-citation"]) { return rawCff;
preferredCitation = true;
}
return yaml.stringify(rawCff);
}; };
try { try {
@ -80,7 +76,7 @@ export default function generateCitations() {
return citationBibtex; return citationBibtex;
} catch (error) { } catch (error) {
console.log(`Error converting CITATION.cff to BibTeX string: ${error.message}`); console.log(`Error converting CITATION.cff to BibTeX string: ${error.message}`);
return null; return "";
} }
})(); })();

View File

@ -0,0 +1 @@
module.exports = require("./jest.cjs").makePackageConfig(__dirname);

View File

@ -3,6 +3,10 @@
"version": "3.2.1", "version": "3.2.1",
"description": "Shared (build) configuration for jsPsych packages", "description": "Shared (build) configuration for jsPsych packages",
"type": "module", "type": "module",
"scripts": {
"test": "jest",
"test:watch": "npm test -- --watch"
},
"exports": { "exports": {
"./gulp": { "./gulp": {
"import": "./gulp.js", "import": "./gulp.js",
@ -45,6 +49,7 @@
"@sucrase/jest-plugin": "3.0.0", "@sucrase/jest-plugin": "3.0.0",
"@types/gulp": "4.0.17", "@types/gulp": "4.0.17",
"@types/jest": "29.5.8", "@types/jest": "29.5.8",
"@types/node": "^22.10.10",
"alias-hq": "6.2.4", "alias-hq": "6.2.4",
"app-root-path": "^3.1.0", "app-root-path": "^3.1.0",
"canvas": "^2.11.2", "canvas": "^2.11.2",
@ -66,7 +71,6 @@
"rollup-plugin-node-externals": "7.1.3", "rollup-plugin-node-externals": "7.1.3",
"sucrase": "3.34.0", "sucrase": "3.34.0",
"tslib": "2.6.2", "tslib": "2.6.2",
"typescript": "^5.2.2", "typescript": "^5.2.2"
"yaml": "^2.5.1"
} }
} }

View 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/);
});
});

View File

@ -36,6 +36,9 @@ export class JsPsych {
return version; return version;
} }
// prettier-ignore
private citation: any = '__CITATIONS__';
/** Options */ /** Options */
private options: any = {}; private options: any = {};
@ -274,8 +277,6 @@ export class JsPsych {
format: "apa" | "bibtex" = "apa" format: "apa" | "bibtex" = "apa"
) { ) {
const formatOptions = ["apa", "bibtex"]; const formatOptions = ["apa", "bibtex"];
// prettier-ignore
const jsPsychCitations: any = '__CITATIONS__';
format = format.toLowerCase() as "apa" | "bibtex"; format = format.toLowerCase() as "apa" | "bibtex";
// Check if plugins is an array // Check if plugins is an array
if (!Array.isArray(plugins)) { if (!Array.isArray(plugins)) {
@ -287,7 +288,7 @@ export class JsPsych {
} }
// Print citations // Print citations
else { else {
const jsPsychCitation = jsPsychCitations[format]; const jsPsychCitation = this.citation[format];
const citationSet = new Set([jsPsychCitation]); const citationSet = new Set([jsPsychCitation]);
for (const plugin of plugins) { for (const plugin of plugins) {

View File

@ -1,33 +1,21 @@
import { initJsPsych } from "../../src";
import { TestExtension } from "../extensions/TestExtension"; import { TestExtension } from "../extensions/TestExtension";
import TestPlugin from "../TestPlugin"; import TestPlugin from "../TestPlugin";
const jsPsychApaCitation = const jsPsychApaCitation = "Test base APA citation";
"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 = "Test base BibTeX citation";
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 testPluginApaCitation = "Test plugin APA citation"; const testPluginApaCitation = "Test plugin APA citation";
const testPluginBibtexCitation = "Test plugin BibTeX citation"; const testPluginBibtexCitation = "Test plugin BibTeX citation";
const testExtensionApaCitation = "Test extension APA 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.
*/
try {
// Try to import built version
JsPsych = require("../../dist/index").JsPsych;
let jspsych: typeof JsPsych;
// Check if getCitations exists in current built version
if (!jspsych.hasOwnProperty("getCitations")) {
throw new Error("getCitations not found");
}
beforeEach(() => { beforeEach(() => {
jspsych = new JsPsych(); jspsych = initJsPsych();
(jspsych as any).citation = {
apa: "Test base APA citation",
bibtex: "Test base BibTeX citation",
};
}); });
describe("citing not using an array", () => { describe("citing not using an array", () => {
@ -38,9 +26,7 @@ try {
expect(() => jspsych.getCitations(null)).toThrow("Expected array of plugins/extensions"); expect(() => jspsych.getCitations(null)).toThrow("Expected array of plugins/extensions");
}); });
test("citing without input and with invalid format", () => { test("citing without input and with invalid format", () => {
expect(() => jspsych.getCitations(null, "apa")).toThrow( expect(() => jspsych.getCitations(null, "apa")).toThrow("Expected array of plugins/extensions");
"Expected array of plugins/extensions"
);
}); });
}); });
@ -88,11 +74,3 @@ try {
); );
}); });
}); });
} 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);
});
});
}