Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jstayton committed Aug 23, 2024
1 parent f4bbd91 commit 97f7cf1
Show file tree
Hide file tree
Showing 21 changed files with 380 additions and 45 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
push:
workflow_dispatch:

jobs:
lint-test:
name: Lint & test
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['18.x', '20.x', '22.x']
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up Node.js v${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install npm dependencies
run: npm install
- name: Run lint
run: npm run lint
- name: Run tests
run: npm test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@

# JSDoc
/docs

# Test builds
/test/templates/*/build
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Test files with invalid syntax
/test/templates/fail_config_json/suri.config.json
/test/templates/fail_links_json/src/links.json
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,25 @@ Install dependencies with npm:
npm install
```

### Tests

The built-in Node.js [test runner](https://nodejs.org/docs/latest/api/test.html)
and [assertions module](https://nodejs.org/docs/latest/api/assert.html) is used
for testing.

To run the tests:

```bash
npm test
```

During development, it's recommended to run the tests automatically on file
change:

```bash
npm test -- --watch
```

### Docs

[JSDoc](https://jsdoc.app/) is used to document the code.
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"lint:format:fix": "prettier --write .",
"lint:quality": "eslint .",
"lint:quality:fix": "eslint --fix .",
"release": "release-it --only-version"
"release": "release-it --only-version",
"test": "node --test ./src"
},
"devDependencies": {
"eslint": "^8.56.0",
Expand Down
85 changes: 41 additions & 44 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,6 @@ import SuriError from './error.js'
*/
const SURI_DIR_PATH = join(dirname(fileURLToPath(import.meta.url)), '..')

/**
* The path to the current working directory of the Node.js process.
*
* @private
* @constant {string}
*/
const CWD_PATH = cwd()

/**
* The path to the build directory in the current working directory.
*
* @private
* @constant {string}
*/
const BUILD_DIR_PATH = join(CWD_PATH, 'build')

/**
* Tagged template function for composing HTML.
*
Expand Down Expand Up @@ -64,18 +48,18 @@ function isErrorFileNotExists(error) {
* Load the config from `suri.config.json`, if it exists, merged with defaults.
*
* @private
* @param {Object} params
* @param {string} params.path The path to the `suri.config.json` file to load.
* @throws {SuriError} If `suri.config.json` fails to be read or parsed.
* @returns {Object} The parsed and merged config.
*/
async function loadConfig() {
const configFilePath = join(CWD_PATH, 'suri.config.json')

console.log(`Config file: ${configFilePath}`)
async function loadConfig({ path }) {
console.log(`Config file: ${path}`)

let config

try {
config = await readFile(configFilePath)
config = await readFile(path)
} catch (error) {
if (!isErrorFileNotExists(error)) {
throw new SuriError('Failed to load config file', error)
Expand All @@ -102,18 +86,18 @@ async function loadConfig() {
* Load the links from `links.json`.
*
* @private
* @param {Object} params
* @param {string} params.path The path to the `links.json` file to load.
* @throws {SuriError} If `links.json` fails to be loaded or parsed.
* @returns {Object} The parsed links.
*/
async function loadLinks() {
const linkFilePath = join(CWD_PATH, 'src', 'links.json')

console.log(`Links file: ${linkFilePath}`)
async function loadLinks({ path }) {
console.log(`Links file: ${path}`)

let links

try {
links = await readFile(linkFilePath)
links = await readFile(path)
} catch (error) {
throw new SuriError('Failed to load links file', error)
}
Expand Down Expand Up @@ -157,11 +141,12 @@ function buildLinkPage({ redirectURL, config }) {
* @param {string} params.linkPath The shortlink path to redirect from.
* @param {string} params.redirectURL The target URL to redirect to.
* @param {Object} params.config The parsed and merged config.
* @param {string} params.buildDirPath The path to the build directory.
* @throws {SuriError} If the directory/file fails to be created.
* @returns {true} If the link was created.
*/
async function createLink({ linkPath, redirectURL, config }) {
const linkDirPath = join(BUILD_DIR_PATH, linkPath)
async function createLink({ linkPath, redirectURL, config, buildDirPath }) {
const linkDirPath = join(buildDirPath, linkPath)

console.log(`Creating link: ${linkPath}`)

Expand All @@ -187,23 +172,23 @@ async function createLink({ linkPath, redirectURL, config }) {
* Copy the public directories/files to the build directory.
*
* The directory in this repository of "default" files is copied first, followed
* by the directory in the current working directory, if it exists.
* by the directory in the source directory, if it exists.
*
* @private
* @param {Object} params
* @param {string} params.path The path to the public directory to copy.
* @param {string} params.buildDirPath The path to the build directory.
* @throws {SuriError} If a directory/file fails to be copied.
* @returns {true} If the directories/files were copied.
*/
async function copyPublic() {
const publicDirPaths = [
join(SURI_DIR_PATH, 'public'),
join(CWD_PATH, 'public'),
]
async function copyPublic({ path, buildDirPath }) {
const publicDirPaths = [join(SURI_DIR_PATH, 'public'), path]

for (const publicDirPath of publicDirPaths) {
console.log(`Copying public directory: ${publicDirPath}`)

try {
await cp(publicDirPath, BUILD_DIR_PATH, {
await cp(publicDirPath, buildDirPath, {
preserveTimestamps: true,
recursive: true,
})
Expand All @@ -223,12 +208,14 @@ async function copyPublic() {
* Remove the build directory and all of its child directories/files.
*
* @private
* @param {Object} params
* @param {string} params.path The path to the build directory to remove.
* @throws {SuriError} If the directory fails to be removed.
* @returns {undefined} If the directory was removed.
*/
async function removeBuild() {
async function removeBuild({ path }) {
try {
return await rm(BUILD_DIR_PATH, { recursive: true, force: true })
return await rm(path, { recursive: true, force: true })
} catch (error) {
throw new SuriError('Failed to remove build directory', error)
}
Expand All @@ -238,27 +225,37 @@ async function removeBuild() {
* Build the static site from a `links.json` file.
*
* @memberof module:suri
* @param {Object} [params]
* @param {string} [params.path] The path to the directory to build from. Defaults to the current working directory of the Node.js process.
* @throws {SuriError} If the build fails.
* @returns {true} If the build succeeds.
*/
async function main() {
async function main({ path = cwd() } = {}) {
try {
await removeBuild()
await removeBuild({ path: join(path, 'build') })

const config = await loadConfig()
const links = await loadLinks()
const config = await loadConfig({ path: join(path, 'suri.config.json') })
const links = await loadLinks({ path: join(path, 'src', 'links.json') })

for (const [linkPath, redirectURL] of Object.entries(links)) {
await createLink({ linkPath, redirectURL, config })
await createLink({
linkPath,
redirectURL,
config,
buildDirPath: join(path, 'build'),
})
}

await copyPublic()
await copyPublic({
path: join(path, 'public'),
buildDirPath: join(path, 'build'),
})

console.log('Done!')

return true
} catch (error) {
await removeBuild()
await removeBuild({ path: join(path, 'build') })

throw error
}
Expand Down
Loading

0 comments on commit 97f7cf1

Please sign in to comment.