{"html_url": "https://github.com/simonw/datasette/issues/1165#issuecomment-752780000", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1165", "id": 752780000, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc4MDAwMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T22:41:25Z", "updated_at": "2020-12-30T22:41:25Z", "author_association": "OWNER", "body": "Jest works with Puppeteer: https://jestjs.io/docs/en/puppeteer", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776635426, "label": "Mechanism for executing JavaScript unit tests"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1165#issuecomment-752779820", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1165", "id": 752779820, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc3OTgyMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T22:40:28Z", "updated_at": "2020-12-30T22:40:28Z", "author_association": "OWNER", "body": "I don't know if Jest on the command-line is the right tool for this. It works for the `plugins.js` script but I'm increasingly going to want to start adding tests for browser JavaScript features - like the https://github.com/simonw/datasette/blob/0.53/datasette/static/table.js script - which will need to run in a browser.\r\n\r\nSo maybe I should just find a browser testing solution and figure out how to run that under CI in GitHub Actions. Maybe https://www.cypress.io/ ?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776635426, "label": "Mechanism for executing JavaScript unit tests"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1165#issuecomment-752779490", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1165", "id": 752779490, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc3OTQ5MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T22:38:43Z", "updated_at": "2020-12-30T22:38:43Z", "author_association": "OWNER", "body": "Turned that into a TIL: https://til.simonwillison.net/javascript/jest-without-package-json", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776635426, "label": "Mechanism for executing JavaScript unit tests"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1165#issuecomment-752777744", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1165", "id": 752777744, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc3Nzc0NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T22:30:24Z", "updated_at": "2020-12-30T22:30:24Z", "author_association": "OWNER", "body": "https://www.valentinog.com/blog/jest/ was useful.\r\n\r\nI created a `static/__tests__` folder and added this file as `plugins.spec.js`:\r\n\r\n```javascript\r\nconst datasette = require(\"../plugins.js\");\r\n\r\ndescribe(\"Datasette Plugins\", () => {\r\n test(\"it should have datasette.plugins\", () => {\r\n expect(!!datasette.plugins).toEqual(true);\r\n });\r\n test(\"registering a plugin should work\", () => {\r\n datasette.plugins.register(\"numbers\", (a, b) => a + b, [\"a\", \"b\"]);\r\n var result = datasette.plugins.call(\"numbers\", { a: 1, b: 2 });\r\n expect(result).toEqual([3]);\r\n datasette.plugins.register(\"numbers\", (a, b) => a * b, [\"a\", \"b\"]);\r\n var result2 = datasette.plugins.call(\"numbers\", { a: 1, b: 2 });\r\n expect(result2).toEqual([3, 2]);\r\n });\r\n});\r\n```\r\n\r\nIn `static/plugins.js` I put this:\r\n```javascript\r\nvar datasette = datasette || {};\r\ndatasette.plugins = (() => {\r\n var registry = {};\r\n return {\r\n register: (hook, fn, parameters) => {\r\n if (!registry[hook]) {\r\n registry[hook] = [];\r\n }\r\n registry[hook].push([fn, parameters]);\r\n },\r\n call: (hook, args) => {\r\n args = args || {};\r\n var results = [];\r\n (registry[hook] || []).forEach(([fn, parameters]) => {\r\n /* Call with the correct arguments */\r\n var result = fn.apply(fn, parameters.map(parameter => args[parameter]));\r\n if (result !== undefined) {\r\n results.push(result);\r\n }\r\n });\r\n return results;\r\n }\r\n };\r\n})();\r\n\r\nmodule.exports = datasette;\r\n```\r\nNote the `module.exports` line at the end.\r\n\r\nThen inside `static/` I ran the following command:\r\n\r\n```\r\n% npx jest -c '{}'\r\n PASS __tests__/plugins.spec.js\r\n Datasette Plugins\r\n \u2713 it should have datasette.plugins (3 ms)\r\n \u2713 registering a plugin should work (1 ms)\r\n\r\nTest Suites: 1 passed, 1 total\r\nTests: 2 passed, 2 total\r\nSnapshots: 0 total\r\nTime: 1.163 s\r\nRan all test suites.\r\n```\r\nThe `-c {}` was necessary because I didn't have a Jest configuration or a `package.json`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776635426, "label": "Mechanism for executing JavaScript unit tests"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1165#issuecomment-752757910", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1165", "id": 752757910, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc1NzkxMA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T21:04:18Z", "updated_at": "2020-12-30T21:04:18Z", "author_association": "OWNER", "body": "https://jestjs.io/ looks worth trying here.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776635426, "label": "Mechanism for executing JavaScript unit tests"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1164#issuecomment-752769452", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1164", "id": 752769452, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc2OTQ1Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T21:50:16Z", "updated_at": "2020-12-30T21:50:16Z", "author_association": "OWNER", "body": "If I implement this I can automate the CodeMirror minification and remove the bit about running `uglify-js` against it from the documentation here: https://docs.datasette.io/en/0.53/contributing.html#upgrading-codemirror", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776634318, "label": "Mechanism for minifying JavaScript that ships with Datasette"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1164#issuecomment-752768785", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1164", "id": 752768785, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc2ODc4NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T21:47:06Z", "updated_at": "2020-12-30T21:47:06Z", "author_association": "OWNER", "body": "If I'm going to minify `table.js` I'd like to offer a source map for it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776634318, "label": "Mechanism for minifying JavaScript that ships with Datasette"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1164#issuecomment-752768652", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1164", "id": 752768652, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc2ODY1Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T21:46:29Z", "updated_at": "2020-12-30T21:46:29Z", "author_association": "OWNER", "body": "Running https://skalman.github.io/UglifyJS-online/ against https://github.com/simonw/datasette/blob/0.53/datasette/static/table.js knocks it down from 7810 characters to 4643.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776634318, "label": "Mechanism for minifying JavaScript that ships with Datasette"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1164#issuecomment-752757075", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1164", "id": 752757075, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc1NzA3NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T21:01:27Z", "updated_at": "2020-12-30T21:01:27Z", "author_association": "OWNER", "body": "I don't want Datasette contributors to need a working Node.js install to run the tests or work on Datasette unless they are explicitly working on the JavaScript.\r\n\r\nI think I'm going to do this with a unit test that runs only if `upglify-js` is available on the path and confirms that the `*.min.js` version of each script in the repository correctly matches the results from running `uglify-js` against it.\r\n\r\nThat way if anyone checks in a change to JavaScript but forgets to run the minifier the tests will fail in CI.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776634318, "label": "Mechanism for minifying JavaScript that ships with Datasette"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1164#issuecomment-752756612", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1164", "id": 752756612, "node_id": "MDEyOklzc3VlQ29tbWVudDc1Mjc1NjYxMg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T20:59:54Z", "updated_at": "2020-12-30T20:59:54Z", "author_association": "OWNER", "body": "I tried a few different pure-Python JavaScript minifying libraries and none of them produced results as good as https://www.npmjs.com/package/uglify-js for the plugin code I'm considering in #983.\r\n\r\nSo I think I'll need to rely on a Node.js tool for this.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 776634318, "label": "Mechanism for minifying JavaScript that ships with Datasette"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/987#issuecomment-752714747", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/987", "id": 752714747, "node_id": "MDEyOklzc3VlQ29tbWVudDc1MjcxNDc0Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-12-30T18:23:08Z", "updated_at": "2020-12-30T18:23:20Z", "author_association": "OWNER", "body": "In terms of \"places to put your plugin content\", the simplest solution I can think of is something like this:\r\n```html\r\n
\r\n```\r\nAlternative designs:\r\n\r\n- A documented JavaScript function that returns the CSS selector where plugins should put their content\r\n- A documented JavaScript function that returns a DOM node where plugins should put their content. This would allow the JavaScript to create the element if it does not already exist (though it wouldn't be obvious WHERE that element should be created)\r\n- Documented JavaScript functions for things like \"append this node/HTML to the place-where-plugins-go\"\r\n\r\nI think the original option - an empty `