{"id":21059724,"url":"https://github.com/zthxxx/leetsolve","last_synced_at":"2025-07-05T18:06:59.475Z","repository":{"id":75948982,"uuid":"110978479","full_name":"zthxxx/leetsolve","owner":"zthxxx","description":"simple \u0026 light testing frame for LeetCode solutions with JavaScript","archived":false,"fork":false,"pushed_at":"2022-02-17T16:16:48.000Z","size":1165,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-14T00:42:12.229Z","etag":null,"topics":["leetcode","leetcode-solutions","problem","solutions","testing-framework"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zthxxx.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-16T14:02:57.000Z","updated_at":"2023-03-08T20:39:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"0a7c7abf-fa89-4787-bc63-638c981e1643","html_url":"https://github.com/zthxxx/leetsolve","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/zthxxx/leetsolve","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zthxxx%2Fleetsolve","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zthxxx%2Fleetsolve/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zthxxx%2Fleetsolve/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zthxxx%2Fleetsolve/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zthxxx","download_url":"https://codeload.github.com/zthxxx/leetsolve/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zthxxx%2Fleetsolve/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259851742,"owners_count":22921633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["leetcode","leetcode-solutions","problem","solutions","testing-framework"],"created_at":"2024-11-19T17:12:58.792Z","updated_at":"2025-06-14T17:06:01.946Z","avatar_url":"https://github.com/zthxxx.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\u003ca href=\"https://github.com/zthxxx/leetsolve\" target=\"_blank\"\u003eLeetSolve.js\u003c/a\u003e\u003c/h1\u003e\n\n[![Build Status](https://travis-ci.org/zthxxx/leetsolve.svg?branch=master)](https://travis-ci.org/zthxxx/leetsolve)\n[![Maintainability](https://api.codeclimate.com/v1/badges/72768b68dd90d81e5dad/maintainability)](https://codeclimate.com/github/zthxxx/leetsolve/maintainability)\n[![Node.js](https://img.shields.io/badge/node-8.x%20LTS-blue.svg)](https://nodejs.org/)\n[![LeetCode](https://img.shields.io/badge/LeetCode-zthxxx-ff69b4.svg)](https://leetcode.com/zthxxxme/)\n\n:cake: simple \u0026 light testing frame for LeetCode solutions with JavaScript\n\n\n## Feature\n\noptimized for the algorithms question pattern, test output for input, such as LeetCode\n\n- easy to describe a problem and testcase\n- lightweight testing frame which a bit like mocha, but more features which are mocha NOT support\n- using **multiprocessing**, speed up testcase\n- canable to stop timeout testing with **infinite loop**\n- direct to run a single problem solution for test\n- also support hooks like `beforEach` `before` `after` `afterEach`\n\n\n## Style preview\n\noutput reporters style adjust to like mocha spec, preview some example:\n\n![testing-output-style](./docs/test-preview.png)\n\n\n## Unit test\n\nchone it, then run the unit test\n\n```bash\ngit clone git@github.com:zthxxx/leetsolve.git\ncd leetsolve\nnpm i\nnpm run unit\n```\n\nyou will get the result as shown above, those examples problem in [`test/examples`](./test/examples/)\n\n\n## Usage\n\nreplace your problems and solutions in [`problems/`](./problems/)\n\nto define a problem, as the same structure of unit test examples,\n\na problem is a folder which named its description, with two files in it, `index.js` as solution, `testcase.js` as test case.\n\n```\nproblems/\n│\n└─ problem1-description/  # define problem 1\n   │\n   ├─ index.js            # solution file\n   └─ testcase.js         # problem testcase file\n```\n\nin **`index.js`**, you may want export one or more solutions, for example:\n\n```js\nfunction solution1 () {}\nfunction solution2 () {}\n/**\n * @type {(function | function[])} - exports\n */\n// export one solution\nmodule.exports = solution1\n// or export some more solutions\nmodule.exports = [solution1, solution2]\n```\n\nit's means test the specified solution or test all.\n\nsolutions will gain input arguments with testcase `input` field, and compare its output to testcase `expect` field.\n\nso, in `testcase.js`, should export list of input and expect:\n\n```js\n/**\n * @type {{input: any[], expect: any}[]} - exports\n */\nmodule.exports = [\n  {\n    input: ['a', 'b'],\n    expect: 1\n  }\n]\n```\n\nsee the [example code](./test/examples/problem-for-unit-test) that you will understand immediately, I promise.\n\n### hooks\n\n**lifecycle hooks**\n\nsupport to use `beforeEach` `afterEach` hooks on exports, if the exports is array,\n\nand use `before` `after` hooks on each solutions.\n\nhook of before deal with input arguments and output processed 'input args' for next hook,\n\noppositely, hook of after deal with output result, origin in, processed out.\n\nthe full resolution flow:\n\n```\nbeforeEachs -\u003e befores -\u003e solution -\u003e afters -\u003e afterEachs\n```\n\n```js\n// register beforeEach or afterEachs hook\nmodule.exports = [solution1, solution2]\n/**\n * @type {(function | function[])} - beforeEach | afterEachs\n */\nmodule.exports.beforeEach = input =\u003e input\n// or\nmodule.exports.beforeEach = [() =\u003e {}, () =\u003e {}]\n```\n\n```js\n// register before or after hook\nmodule.exports = [solution1, solution2]\n/**\n * @type {(function | function[])} - before | after\n */\nsolution1.before = () =\u003e {}\n// or\nsolution2.after = [() =\u003e {}, () =\u003e {}]\n```\n\n**timeout setting hook**\n\nsupport to set different timelimit to specific problem or solution. By ues `timeout` property as lifecycle hooks.\n\n**direct running hook**\n\nyou may want to direct run a solution file for test as `node ./problem-1/index.js` or `node ./problem-1`\n\nall right, only ensure `index.js`  **require** this hook module **`libs/runDirect.js`**\n\n```js\n// problems/problem-for-unit-test/index.js\nrequire('../../libs/runDirect')\n```\n\n### configure\n\nyou can also adjust problems path at `problemBase` and testcase file name at `casefile` in `config.js`\n\nmore options description see [config.js](./config.js)\n\n\nok, come on, try out!\n\n\n## Author\n\n**LeetSolve** © [zthxxx](https://github.com/zthxxx), Released under the **[MIT](./LICENSE)** License.\u003cbr\u003e\n\n\u003e Blog [@zthxxx](https://blog.zthxxx.me) · GitHub [@zthxxx](https://github.com/zthxxx)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzthxxx%2Fleetsolve","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzthxxx%2Fleetsolve","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzthxxx%2Fleetsolve/lists"}