diff --git a/README.md b/README.md index ea81c33..142e8d5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This plugin reads and/or writes version/manifest files. -``` +```sh npm install --save-dev @release-it/bumper ``` @@ -30,13 +30,15 @@ file(s), or use The supported file types are: -| Type | Extension(s) | Mime-type | -| ---- | ----------------- | ----------------------------------- | -| JSON | `.json` | `application/json` | -| YAML | `.yaml` or `.yml` | `text/yaml` or `application-x-yaml` | -| TOML | `.toml` | `text/toml` or `application/toml` | -| INI | `.ini` | `text/x-properties` | -| TEXT | `.txt` | `text/*` | +| Type | Extension(s) | Mime-type | +| ---- | ----------------- | --------------------------------------------------------- | +| JSON | `.json` | `application/json` | +| YAML | `.yaml` or `.yml` | `text/yaml` or `application-x-yaml` or `application/yaml` | +| TOML | `.toml` | `text/toml` or `application/toml` | +| INI | `.ini` | `text/x-properties` | +| XML | `.xml` | `text/xml` or `application/xml` | +| HTML | `.html` | `text/html` or `application/xhtml+xml` | +| TEXT | `.txt` | `text/*` | Explicitly providing the (mime) `type` takes precedence over the file extension. @@ -125,6 +127,36 @@ The `path` option (default: `"version"`) can be used to change a different prope } ``` +> For the `xml` type, the `path` option must be in the form of a unique [css selector](https://www.w3.org/TR/selectors-4/#overview). The following example will set the +`project > version` property to the new version in `pom.xml`: + +```json +"plugins": { + "@release-it/bumper": { + "out": { + "file": "pom.xml", + "path": "project > version", + "type": "application/xml" + } + } +} +``` + +> For the `html` type, the `path` option must be in the form of a unique [css selector](https://www.w3.org/TR/selectors-4/#overview). The following example will set the +element text content with the css attribute `#version` to the new version in `foo.html`: + +```json +"plugins": { + "@release-it/bumper": { + "out": { + "file": "foo.html", + "path": "#version", + "type": "text/html" + } + } +} +``` + Multiple paths can be provided using an array. The `versionPrefix` option (default: `''`) can be used in cases where you'd like to maintain a specific prefix for your version number (for example, in `package.json` where you might want versions like `^1.0.0`). This will prepend the specified prefix to the bumped version: diff --git a/index.js b/index.js index b440850..6a9b153 100644 --- a/index.js +++ b/index.js @@ -8,17 +8,24 @@ import toml from '@iarna/toml'; import ini from 'ini'; import semver from 'semver'; import { Plugin } from 'release-it'; +import * as cheerio from 'cheerio'; const noop = Promise.resolve(); const isString = value => typeof value === 'string'; const mimeTypesMap = { 'application/json': 'json', - 'text/yaml': 'yaml', + 'application/yaml': 'yaml', 'application/x-yaml': 'yaml', - 'text/toml': 'toml', + 'text/yaml': 'yaml', 'application/toml': 'toml', - 'text/x-properties': 'ini' + 'text/toml': 'toml', + 'text/x-properties': 'ini', + 'application/xml': 'xml', + 'text/xml': 'xml', + 'application/xhtml+xml': 'html', + 'text/html': 'html', + 'text/plain': 'text' }; const extensionsMap = { @@ -26,7 +33,11 @@ const extensionsMap = { yml: 'yaml', yaml: 'yaml', toml: 'toml', - ini: 'ini' + ini: 'ini', + xml: 'xml', + html: 'html', + xhtml: 'html', + txt: 'text' }; const parseFileOption = option => { @@ -54,7 +65,11 @@ const parse = async (data, type) => { return toml.parse(data); case 'ini': return ini.parse(data); - default: + case 'xml': + return cheerio.load(data, { xmlMode: true }); + case 'html': + return cheerio.load(data); + default: // text return (data || '').toString(); } }; @@ -75,7 +90,27 @@ class Bumper extends Plugin { } const parsed = await parse(data, type); - const version = isString(parsed) ? parsed.trim() : get(parsed, path); + + let version = undefined; + switch (type) { + case 'json': + case 'yaml': + case 'toml': + case 'ini': + version = get(parsed, path); + break; + case 'xml': + case 'html': + const element = parsed(path); + if (!element) { + throw new Error(`Failed to find the element with the provided selector: ${path}`); + } + version = element.text(); + break; + default: // text + version = parsed.trim(); + } + const parsedVersion = semver.parse(version); return parsedVersion ? parsedVersion.toString() : null; } @@ -137,12 +172,34 @@ class Bumper extends Plugin { case 'yaml': return writeFileSync(file, yaml.dump(parsed, { indent: indent.length })); case 'toml': - return writeFileSync(file, toml.stringify(parsed)); + const tomlString = toml.stringify(parsed); + // handle empty objects for sections + const tomlContent = tomlString.replace(/^([a-zA-Z0-9\.\-]+) \= \{ \}/g, '[$1]'); + return writeFileSync(file, tomlContent); case 'ini': return writeFileSync(file, ini.encode(parsed)); + case 'xml': + const xmlElement = parsed(path); + if (!xmlElement) { + throw new Error(`Failed to find the element with the provided selector: ${path}`); + } + + xmlElement.text(version); + return writeFileSync(file, parsed.xml()); + case 'html': + const htmlElement = parsed(path); + if (!htmlElement) { + throw new Error(`Failed to find the element with the provided selector: ${path}`); + } + + // We are taking this approach as cheerio will modify the original html doc type and head formatting if we just used the parsed.html() function. + const previousContents = htmlElement.prop('outerHTML'); + htmlElement.text(version); + const html = data.replace(previousContents.trim(), htmlElement.prop('outerHTML').trim()); + return writeFileSync(file, html); default: const versionMatch = new RegExp(latestVersion || '', 'g'); - const write = (parsed && !consumeWholeFile) ? parsed.replace(versionMatch, version) : version + EOL; + const write = parsed && !consumeWholeFile ? parsed.replace(versionMatch, version) : version + EOL; return writeFileSync(file, write); } }) diff --git a/package.json b/package.json index 078b22a..84f2d4f 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "./package.json": "./package.json" }, "scripts": { - "test": "bron test.js", + "test": "node --test test", "release": "release-it" }, "keywords": [ @@ -23,31 +23,30 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/release-it/bumper.git" + "url": "git+https://github.com/release-it/bumper.git" }, "homepage": "https://github.com/release-it/bumper#readme", - "bugs": "https://github.com/release-it/bumper/issues", - "author": { - "email": "lars@webpro.nl", - "name": "Lars Kappert" + "bugs": { + "url": "https://github.com/release-it/bumper/issues" }, + "author": "Lars Kappert ", "dependencies": { - "@iarna/toml": "^2.2.5", + "@iarna/toml": "^3.0.0", + "cheerio": "^1.0.0", "detect-indent": "7.0.1", - "fast-glob": "^3.3.2", - "ini": "^4.1.1", + "fast-glob": "^3.3.3", + "ini": "^5.0.0", "js-yaml": "^4.1.0", "lodash-es": "^4.17.21", "semver": "^7.3.7" }, "devDependencies": { - "bron": "^2.0.3", - "mock-fs": "5.2.0", - "release-it": "^17.0.0", - "sinon": "^15.2.0" + "mock-fs": "5.4.1", + "release-it": "^18.0.0", + "sinon": "^19.0.2" }, "peerDependencies": { - "release-it": "^17.0.0" + "release-it": "^18.0.0" }, "engines": { "node": ">=18" @@ -63,5 +62,6 @@ "submit": true } } - } + }, + "main": "index.js" } diff --git a/test.js b/test.js deleted file mode 100644 index 3b4cee6..0000000 --- a/test.js +++ /dev/null @@ -1,342 +0,0 @@ -import test from 'bron'; -import { readFileSync } from 'fs'; -import { EOL } from 'os'; - -import assert from 'assert'; -import mock from 'mock-fs'; -import { factory, runTasks } from 'release-it/test/util/index.js'; -import Bumper from './index.js'; - -mock({ - './bower.json': JSON.stringify({ version: '1.0.0' }) + EOL, - './foo.txt': `1.0.0${EOL}`, - './foo2.txt': `1.0.0${EOL}`, - './foo.php': `/* comments${EOL}version: v1.0.0 */ hello world

; ?>${EOL}`, - './manifest.json': `{}${EOL}`, - './dryrun.json': JSON.stringify({ version: '1.0.0' }) + EOL, - './foo.toml': `[tool.test]${EOL}version = "1.0.0"${EOL}`, - './foo.ini': `path.version=1.0.0${EOL}path.name=fake${EOL}`, - './VERSION': `v1.0.0${EOL}`, - './VERSION-OLD': `v0.9.0${EOL}`, - './VERSION-OLD2': `v0.9.0${EOL}`, - './README.md': `Release v1.0.0${EOL}`, - './foo.yaml': `version: v1.0.0${EOL}`, - './invalid.toml': `/# -*- some invalid toml -*-${EOL}version = "1.0.0"${EOL}` -}); - -const namespace = 'bumper'; - -const nl = value => value.split(/\r\n|\r|\n/g).join(EOL); - -const readFile = file => nl(readFileSync(file).toString()); - -test('should not throw', async () => { - const options = { [namespace]: {} }; - const plugin = factory(Bumper, { namespace, options }); - await assert.doesNotReject(runTasks(plugin)); -}); - -test('should return latest version from JSON file', async () => { - const options = { [namespace]: { in: './bower.json' } }; - const plugin = factory(Bumper, { namespace, options }); - const version = await plugin.getLatestVersion(); - assert.equal(version, '1.0.0'); -}); - -test('should return latest version from plain text file', async () => { - const options = { - [namespace]: { in: { file: './foo.txt', type: 'text/plain' } } - }; - const plugin = factory(Bumper, { namespace, options }); - const version = await plugin.getLatestVersion(); - assert.equal(version, '1.0.0'); -}); - -test('should return latest version from plain text file (.txt)', async () => { - const options = { [namespace]: { in: { file: './foo.txt' } } }; - const plugin = factory(Bumper, { namespace, options }); - const version = await plugin.getLatestVersion(); - assert.equal(version, '1.0.0'); -}); - -test('should return latest version from YAML file', async () => { - const options = { [namespace]: { in: './foo.yaml' } }; - const plugin = factory(Bumper, { namespace, options }); - const version = await plugin.getLatestVersion(); - assert.equal(version, '1.0.0'); -}); - -test('should write indented JSON file', async () => { - const options = { [namespace]: { out: './manifest.json' } }; - const plugin = factory(Bumper, { namespace, options }); - await plugin.bump('1.2.3'); - assert.equal(readFile('./manifest.json'), `{${EOL} "version": "1.2.3"${EOL}}${EOL}`); -}); - -test('should write new, indented JSON file', async () => { - const options = { [namespace]: { out: ['./null.json'] } }; - const plugin = factory(Bumper, { namespace, options }); - await plugin.bump('0.0.0'); - assert.equal(readFile('./null.json'), `{${EOL} "version": "0.0.0"${EOL}}${EOL}`); -}); - -test('should write version at path', async () => { - const options = { - [namespace]: { out: { file: './deep.json', path: 'deep.sub.version' } } - }; - const plugin = factory(Bumper, { namespace, options }); - await plugin.bump('1.2.3'); - assert.equal( - readFile('./deep.json'), - `{${EOL} "deep": {${EOL} "sub": {${EOL} "version": "1.2.3"${EOL} }${EOL} }${EOL}}${EOL}` - ); -}); - -test('should write version at multiple paths', async () => { - const options = { - [namespace]: { - out: { - file: './multi.json', - path: ['version', 'deep.version', 'deep.sub.version'] - } - } - }; - const plugin = factory(Bumper, { namespace, options }); - await plugin.bump('1.2.3'); - assert.equal( - readFile('./multi.json'), - `{${EOL} "version": "1.2.3",${EOL} "deep": {${EOL} "version": "1.2.3",${EOL} "sub": {${EOL} "version": "1.2.3"${EOL} }${EOL} }${EOL}}${EOL}` - ); -}); - -test('should write plain version text file', async () => { - const options = { - [namespace]: { out: [{ file: './VERSION-OUT', type: 'text/plain' }] } - }; - const plugin = factory(Bumper, { namespace, options }); - await plugin.bump('3.2.1'); - assert.equal(readFile('./VERSION-OUT'), `3.2.1${EOL}`); -}); - -test('should write plain version text file (default text type)', async () => { - const options = { [namespace]: { out: [{ file: './VERSION-OUT' }] } }; - const plugin = factory(Bumper, { namespace, options }); - await plugin.bump('3.2.1'); - assert.equal(readFile('./VERSION-OUT'), `3.2.1${EOL}`); -}); - -test('should write toml file', async () => { - const options = { - [namespace]: { - out: { - file: './foo.toml', - type: 'application/toml', - path: 'tool.test.version' - } - } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.toml'), `[tool.test]${EOL}version = "1.0.1"${EOL}`); -}); - -test('should write toml file (.toml)', async () => { - const options = { - [namespace]: { out: { file: './foo.toml', path: 'tool.test.version' } } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.toml'), `[tool.test]${EOL}version = "1.0.1"${EOL}`); -}); - -test('should write ini file', async () => { - const options = { - [namespace]: { out: { file: './foo.ini', path: 'path.version' } } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.ini'), `path.version=1.0.1${EOL}path.name=fake${EOL}`); -}); - -test('should write plain text file', async () => { - const options = { - [namespace]: { - in: './bower.json', - out: { file: './foo.php', type: 'text/php' } - } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.php'), `/* comments${EOL}version: v1.0.1 */ hello world

; ?>${EOL}`); -}); - -test('should write YAML file', async () => { - const options = { [namespace]: { out: { file: './foo.yaml' } } }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.yaml'), `version: 1.0.1${EOL}`); -}); - -test('should read/write plain text file', async () => { - const options = { - [namespace]: { - in: { file: './foo.txt', type: 'text/plain' }, - out: { file: './foo.txt', type: 'text/plain' } - } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.txt'), `1.0.1${EOL}`); -}); - -test('should read/write plain text file (.txt)', async () => { - const options = { - [namespace]: { in: { file: './foo.txt' }, out: { file: './foo.txt' } } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.txt'), `1.0.1${EOL}`); -}); - -test('should read one and write multiple files', async () => { - const options = { - [namespace]: { in: { file: './foo.txt' }, out: './foo*.txt' } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.txt'), `1.0.1${EOL}`); - assert.equal(readFile('./foo2.txt'), `1.0.1${EOL}`); -}); - -test('should read one and write multiple files and respect prefix', async () => { - const options = { - [namespace]: { - in: { file: 'VERSION', type: 'text/plain' }, - out: ['README.md', 'VERSION'] - } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./README.md'), `Release v1.0.1${EOL}`); - assert.equal(readFile('./VERSION'), `v1.0.1${EOL}`); -}); - -test('should write various file types', async () => { - const options = { - [namespace]: { - out: [{ file: './foo*.txt' }, { file: './(bower|manifest).json' }] - } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./foo.txt'), `1.0.1${EOL}`); - assert.equal(readFile('./foo2.txt'), `1.0.1${EOL}`); - assert.equal(readFile('./bower.json'), `{${EOL} "version": "1.0.1"${EOL}}${EOL}`); - assert.equal(readFile('./manifest.json'), `{${EOL} "version": "1.0.1"${EOL}}${EOL}`); -}); - -test('should not write in dry run', async () => { - const options = { [namespace]: { in: './dryrun.json' } }; - const plugin = factory(Bumper, { - namespace, - options, - global: { isDryRun: true } - }); - await plugin.bump('1.0.1'); - assert.equal(readFile('./dryrun.json'), `{"version":"1.0.0"}${EOL}`); -}); - -test('should give precedence to mime type over file extension', async () => { - const options = { - [namespace]: { - out: { - file: './invalid.toml', - type: 'text/plain' - } - } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./invalid.toml'), `/# -*- some invalid toml -*-${EOL}version = "1.0.1"${EOL}`); -}); - -test('should read from plain text file, overwrite out-of-date plain version text file, completely', async () => { - const options = { - [namespace]: { - in: { file: 'VERSION', type: 'text/plain' }, - out: [ - { - file: './VERSION-OLD', - type: 'text/plain', - consumeWholeFile: true - }, - { - file: './VERSION', - type: 'text/plain' - } - ] } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./VERSION'), `v1.0.1${EOL}`); - assert.equal(readFile('./VERSION-OLD'), `1.0.1${EOL}`); -}); - -test('should read from plain text file, not update out-of-date plain version text file', async () => { - const options = { - [namespace]: { - in: { file: 'VERSION', type: 'text/plain' }, - out: [ - { - file: './VERSION-OLD2', - type: 'text/plain', - consumeWholeFile: false - }, - { - file: './VERSION', - type: 'text/plain' - } - ] } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./VERSION'), `v1.0.1${EOL}`); - assert.equal(readFile('./VERSION-OLD2'), `v0.9.0${EOL}`); -}); - -test('should read from plain text file, not update out-of-date plain version text file (default implied)', async () => { - const options = { - [namespace]: { - in: { file: 'VERSION', type: 'text/plain' }, - out: [ - { - file: './VERSION-OLD2', - type: 'text/plain' - }, - { - file: './VERSION', - type: 'text/plain' - } - ] } - }; - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./VERSION'), `v1.0.1${EOL}`); - assert.equal(readFile('./VERSION-OLD2'), `v0.9.0${EOL}`); -}); - -test('should update version in JSON file with prefix', async () => { - const options = { - [namespace]: { - out: { - file: './bower.json', - path: 'version', - versionPrefix: '^' - } - } - }; - - const plugin = factory(Bumper, { namespace, options }); - await runTasks(plugin); - assert.equal(readFile('./bower.json'), '{\n "version": "^1.0.1"\n}\n'); -}); diff --git a/test/general.test.js b/test/general.test.js new file mode 100644 index 0000000..a48a96d --- /dev/null +++ b/test/general.test.js @@ -0,0 +1,104 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { EOL } from 'os'; + +import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; +import Bumper from '../index.js'; +import { + NAMESPACE, + JSON_DATA, + OLD_VERSION, + CURRENT_VERSION, + NEW_VERSION +} from './globals/constants.js'; +import { readFile } from './globals/file-utils.js'; + +mock({ + './bower.json': JSON_DATA, + './dryrun.json': JSON_DATA, + './foo.json': JSON_DATA, + './foo.txt': `${CURRENT_VERSION}${EOL}`, + './foo2.txt': `${CURRENT_VERSION}${EOL}`, + './manifest.json': `{}${EOL}`, + './VERSION': `v${CURRENT_VERSION}${EOL}`, + './VERSION-OLD': `v${OLD_VERSION}${EOL}`, + './README.md': `Release v${CURRENT_VERSION}${EOL}`, + './foo.php': `/* comments${EOL}version: v${CURRENT_VERSION} */ hello world

; ?>${EOL}`, + './invalid.toml': `/# -*- some invalid toml -*-${EOL}version = "${CURRENT_VERSION}"${EOL}` +}); + +describe('release-it bumper', { concurrency: true }, () => { + it('should not throw', async () => { + const options = { [NAMESPACE]: {} }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await assert.doesNotReject(runTasks(plugin)); + }); + + it('should read one and write different', async () => { + const options = { + [NAMESPACE]: { + in: './bower.json', + out: { file: './foo.php', type: 'text/php' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal( + readFile('./foo.php'), + `/* comments${EOL}version: v${NEW_VERSION} */ hello world

; ?>${EOL}` + ); + }); + + it('should read one and write multiple files and respect prefix', async () => { + const options = { + [NAMESPACE]: { + in: { file: 'VERSION', type: 'text/plain' }, + out: ['README.md', 'VERSION'] + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./README.md'), `Release v${NEW_VERSION}${EOL}`); + assert.equal(readFile('./VERSION'), `v${NEW_VERSION}${EOL}`); + }); + + it('should write various file types', async () => { + const options = { + [NAMESPACE]: { + out: [{ file: './foo*.txt' }, { file: './(bower|manifest).json' }] + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.txt'), `${NEW_VERSION}${EOL}`); + assert.equal(readFile('./foo2.txt'), `${NEW_VERSION}${EOL}`); + assert.equal(readFile('./bower.json'), `{${EOL} "version": "${NEW_VERSION}"${EOL}}${EOL}`); + assert.equal(readFile('./manifest.json'), `{${EOL} "version": "${NEW_VERSION}"${EOL}}${EOL}`); + }); + + it('should not write in dry run', async () => { + const options = { [NAMESPACE]: { in: './dryrun.json' } }; + const plugin = factory(Bumper, { + NAMESPACE, + options, + global: { isDryRun: true } + }); + await plugin.bump(NEW_VERSION); + assert.equal(readFile('./dryrun.json'), `{"version":"${CURRENT_VERSION}"}${EOL}`); + }); + + it('should give precedence to mime type over file extension', async () => { + const options = { + [NAMESPACE]: { + out: { + file: './invalid.toml', + type: 'text/plain' + } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./invalid.toml'), `/# -*- some invalid toml -*-${EOL}version = "${NEW_VERSION}"${EOL}`); + }); +}); diff --git a/test/globals/constants.js b/test/globals/constants.js new file mode 100644 index 0000000..d6908d1 --- /dev/null +++ b/test/globals/constants.js @@ -0,0 +1,7 @@ +import { EOL } from 'os'; + +export const NAMESPACE = 'bumper'; +export const CURRENT_VERSION = '1.0.0'; +export const NEW_VERSION = '1.0.1'; +export const OLD_VERSION = '0.9.0'; +export const JSON_DATA = JSON.stringify({ version: CURRENT_VERSION }) + EOL; diff --git a/test/globals/file-utils.js b/test/globals/file-utils.js new file mode 100644 index 0000000..ab64288 --- /dev/null +++ b/test/globals/file-utils.js @@ -0,0 +1,10 @@ +import { EOL } from 'os'; +import { readFileSync } from 'fs'; + +export function nl(value) { + return value.split(/\r\n|\r|\n/g).join(EOL); +} + +export function readFile(file) { + return nl(readFileSync(file).toString()); +} diff --git a/test/html.test.js b/test/html.test.js new file mode 100644 index 0000000..d1d5927 --- /dev/null +++ b/test/html.test.js @@ -0,0 +1,131 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { EOL } from 'os'; + +import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; +import Bumper from '../index.js'; +import { NAMESPACE, CURRENT_VERSION, NEW_VERSION } from './globals/constants.js'; +import { readFile } from './globals/file-utils.js'; + +const html = `${EOL}${EOL} ${EOL} ${EOL}
${EOL}
${CURRENT_VERSION}
${EOL}
${EOL} ${EOL}${EOL}`; +const updatedHTML = `${EOL}${EOL} ${EOL} ${EOL}
${EOL}
${NEW_VERSION}
${EOL}
${EOL} ${EOL}${EOL}`; +const xhtml = `${EOL}${EOL}${EOL} Title of document${EOL}${EOL}${EOL}
${CURRENT_VERSION}
${EOL}${EOL}`; +const updatedXHTML = `${EOL}${EOL}${EOL} Title of document${EOL}${EOL}${EOL}
${NEW_VERSION}
${EOL}${EOL}`; + +mock({ + './foo.html': html, + './foo.xhtml': xhtml +}); + +describe('html file', { concurrency: true }, () => { + it('should return latest version', async () => { + const options = { [NAMESPACE]: { in: { file: './foo.html', path: '#version' } } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should return latest version (XHTML)', async () => { + const options = { [NAMESPACE]: { in: { file: './foo.xhtml', path: '#version' } } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should write', async () => { + const options = { + [NAMESPACE]: { + out: { + file: './foo.html', + type: 'text/html', + path: '#version' + } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.html'), updatedHTML); + }); + + it('should write (XHTML)', async () => { + const options = { + [NAMESPACE]: { + out: { + file: './foo.xhtml', + type: 'application/xhtml+xml', + path: '#version' + } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.xhtml'), updatedXHTML); + }); + + it('should write without defining the type', async () => { + const options = { + [NAMESPACE]: { out: { file: './foo.html', path: '#version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.html'), updatedHTML); + }); + + it('should write without defining the type (XHTML)', async () => { + const options = { + [NAMESPACE]: { out: { file: './foo.xhtml', path: '#version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.xhtml'), updatedXHTML); + }); + + it('should read/write', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.html', type: 'text/html', path: '#version' }, + out: { file: './foo.html', type: 'text/html', path: '#version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.html'), updatedHTML); + }); + + it('should read/write (XHTML)', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.xhtml', type: 'application/xhtml+xml', path: '#version' }, + out: { file: './foo.xhtml', type: 'application/xhtml+xml', path: '#version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.xhtml'), updatedXHTML); + }); + + it('should read/write without defining the type', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.html', path: '#version' }, + out: { file: './foo.html', path: '#version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.html'), updatedHTML); + }); + + it('should read/write without defining the type (XHTML)', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.xhtml', path: '#version' }, + out: { file: './foo.xhtml', path: '#version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.xhtml'), updatedXHTML); + }); +}); diff --git a/test/ini.test.js b/test/ini.test.js new file mode 100644 index 0000000..0246542 --- /dev/null +++ b/test/ini.test.js @@ -0,0 +1,98 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { EOL } from 'os'; + +import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; +import Bumper from '../index.js'; +import { NAMESPACE, CURRENT_VERSION, NEW_VERSION } from './globals/constants.js'; +import { readFile } from './globals/file-utils.js'; + +mock({ + './.foo': `path.version=${CURRENT_VERSION}${EOL}path.name=fake${EOL}`, + './foo.ini': `path.version=${CURRENT_VERSION}${EOL}path.name=fake${EOL}`, + './section.ini': `[db]${EOL}user=root${EOL}${EOL}[section]${EOL}version=${CURRENT_VERSION}${EOL}name=fake${EOL}` +}); + +describe('ini file', { concurrency: true }, () => { + it('should return latest version', async () => { + const options = { + [NAMESPACE]: { in: { file: './.foo', type: 'text/x-properties', path: 'path.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should return latest version without defining the type', async () => { + const options = { + [NAMESPACE]: { in: { file: './foo.ini', path: 'path.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should return latest version from section', async () => { + const options = { + [NAMESPACE]: { in: { file: './section.ini', path: 'section.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should write', async () => { + const options = { + [NAMESPACE]: { out: { file: './foo.ini', type: 'text/x-properties', path: 'path.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.ini'), `path.version=${NEW_VERSION}${EOL}path.name=fake${EOL}`); + }); + + it('should write without defining the type', async () => { + const options = { + [NAMESPACE]: { out: { file: './foo.ini', path: 'path.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.ini'), `path.version=${NEW_VERSION}${EOL}path.name=fake${EOL}`); + }); + + it('should read/write', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.ini', type: 'text/x-properties', path: 'path.version' }, + out: { file: './foo.ini', type: 'text/x-properties', path: 'path.version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.ini'), `path.version=${NEW_VERSION}${EOL}path.name=fake${EOL}`); + }); + + it('should read/write without defining the type', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.ini', path: 'path.version' }, + out: { file: './foo.ini', path: 'path.version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.ini'), `path.version=${NEW_VERSION}${EOL}path.name=fake${EOL}`); + }); + + it('should read/write with section', async () => { + const options = { + [NAMESPACE]: { + in: { file: './section.ini', path: 'section.version' }, + out: { file: './section.ini', path: 'section.version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./section.ini'), `[db]${EOL}user=root${EOL}${EOL}[section]${EOL}version=${NEW_VERSION}${EOL}name=fake${EOL}`); + }); +}); diff --git a/test/json.test.js b/test/json.test.js new file mode 100644 index 0000000..9c83bca --- /dev/null +++ b/test/json.test.js @@ -0,0 +1,91 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { EOL } from 'os'; + +import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; +import Bumper from '../index.js'; +import { + NAMESPACE, + JSON_DATA, + OLD_VERSION, + CURRENT_VERSION, + NEW_VERSION +} from './globals/constants.js'; +import { readFile } from './globals/file-utils.js'; + +mock({ + './bower.json': JSON_DATA, + './foo.json': JSON_DATA, + './manifest.json': `{}${EOL}`, + './VERSION': `v${CURRENT_VERSION}${EOL}`, + './VERSION-OLD': `v${OLD_VERSION}${EOL}` +}); + +describe('json file', { concurrency: true }, () => { + it('should return latest version', async () => { + const options = { [NAMESPACE]: { in: './foo.json' } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should write indented', async () => { + const options = { [NAMESPACE]: { out: './manifest.json' } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await plugin.bump('1.2.3'); + assert.equal(readFile('./manifest.json'), `{${EOL} "version": "1.2.3"${EOL}}${EOL}`); + }); + + it('should write new, indented', async () => { + const options = { [NAMESPACE]: { out: ['./null.json'] } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await plugin.bump('0.0.0'); + assert.equal(readFile('./null.json'), `{${EOL} "version": "0.0.0"${EOL}}${EOL}`); + }); + + it('should write version at path', async () => { + const options = { + [NAMESPACE]: { out: { file: './deep.json', path: 'deep.sub.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await plugin.bump('1.2.3'); + assert.equal( + readFile('./deep.json'), + `{${EOL} "deep": {${EOL} "sub": {${EOL} "version": "1.2.3"${EOL} }${EOL} }${EOL}}${EOL}` + ); + }); + + it('should write version at multiple paths', async () => { + const options = { + [NAMESPACE]: { + out: { + file: './multi.json', + path: ['version', 'deep.version', 'deep.sub.version'] + } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await plugin.bump('1.2.3'); + assert.equal( + readFile('./multi.json'), + `{${EOL} "version": "1.2.3",${EOL} "deep": {${EOL} "version": "1.2.3",${EOL} "sub": {${EOL} "version": "1.2.3"${EOL} }${EOL} }${EOL}}${EOL}` + ); + }); + + it('should update version with prefix', async () => { + const options = { + [NAMESPACE]: { + out: { + file: './bower.json', + path: 'version', + versionPrefix: '^' + } + } + }; + + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./bower.json'), `{${EOL} "version": "^${NEW_VERSION}"${EOL}}${EOL}`); + }); +}); diff --git a/test/text.test.js b/test/text.test.js new file mode 100644 index 0000000..5007bc5 --- /dev/null +++ b/test/text.test.js @@ -0,0 +1,158 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { EOL } from 'os'; + +import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; +import Bumper from '../index.js'; +import { + NAMESPACE, + JSON_DATA, + OLD_VERSION, + CURRENT_VERSION, + NEW_VERSION +} from './globals/constants.js'; +import { readFile } from './globals/file-utils.js'; + +mock({ + './bower.json': JSON_DATA, + './foo.json': JSON_DATA, + './foo.txt': `${CURRENT_VERSION}${EOL}`, + './foo2.txt': `${CURRENT_VERSION}${EOL}`, + './VERSION': `v${CURRENT_VERSION}${EOL}`, + './VERSION-OLD': `v${OLD_VERSION}${EOL}`, + './VERSION-OLD2': `v${OLD_VERSION}${EOL}` +}); + +describe('text file', { concurrency: true }, () => { + it('should return latest version', async () => { + const options = { + [NAMESPACE]: { in: { file: './foo.txt', type: 'text/plain' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should return latest version without defining the type', async () => { + const options = { [NAMESPACE]: { in: { file: './foo.txt' } } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should write', async () => { + const options = { + [NAMESPACE]: { out: [{ file: './VERSION-OUT', type: 'text/plain' }] } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await plugin.bump('3.2.1'); + assert.equal(readFile('./VERSION-OUT'), `3.2.1${EOL}`); + }); + + it('should write default text type', async () => { + const options = { [NAMESPACE]: { out: [{ file: './VERSION-OUT' }] } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await plugin.bump('3.2.1'); + assert.equal(readFile('./VERSION-OUT'), `3.2.1${EOL}`); + }); + + it('should read/write', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.txt', type: 'text/plain' }, + out: { file: './foo.txt', type: 'text/plain' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.txt'), `${NEW_VERSION}${EOL}`); + }); + + it('should read/write without defining the type', async () => { + const options = { + [NAMESPACE]: { in: { file: './foo.txt' }, out: { file: './foo.txt' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.txt'), `${NEW_VERSION}${EOL}`); + }); + + it('should read one and write multiple files', async () => { + const options = { + [NAMESPACE]: { in: { file: './foo.txt' }, out: './foo*.txt' } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.txt'), `${NEW_VERSION}${EOL}`); + assert.equal(readFile('./foo2.txt'), `${NEW_VERSION}${EOL}`); + }); + + it('should read and overwrite out-of-date, completely', async () => { + const options = { + [NAMESPACE]: { + in: { file: 'VERSION', type: 'text/plain' }, + out: [ + { + file: './VERSION-OLD', + type: 'text/plain', + consumeWholeFile: true + }, + { + file: './VERSION', + type: 'text/plain' + } + ] + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./VERSION'), `v${NEW_VERSION}${EOL}`); + assert.equal(readFile('./VERSION-OLD'), `${NEW_VERSION}${EOL}`); + }); + + it('should read but not update out-of-date', async () => { + const options = { + [NAMESPACE]: { + in: { file: 'VERSION', type: 'text/plain' }, + out: [ + { + file: './VERSION-OLD2', + type: 'text/plain', + consumeWholeFile: false + }, + { + file: './VERSION', + type: 'text/plain' + } + ] + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./VERSION'), `v${NEW_VERSION}${EOL}`); + assert.equal(readFile('./VERSION-OLD2'), `v${OLD_VERSION}${EOL}`); + }); + + it('should read but not update out-of-date (default implied)', async () => { + const options = { + [NAMESPACE]: { + in: { file: 'VERSION', type: 'text/plain' }, + out: [ + { + file: './VERSION-OLD2', + type: 'text/plain' + }, + { + file: './VERSION', + type: 'text/plain' + } + ] + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./VERSION'), `v${NEW_VERSION}${EOL}`); + assert.equal(readFile('./VERSION-OLD2'), `v${OLD_VERSION}${EOL}`); + }); +}); diff --git a/test/toml.test.js b/test/toml.test.js new file mode 100644 index 0000000..4d82856 --- /dev/null +++ b/test/toml.test.js @@ -0,0 +1,85 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { EOL } from 'os'; + +import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; +import Bumper from '../index.js'; +import { NAMESPACE, CURRENT_VERSION, NEW_VERSION } from './globals/constants.js'; +import { readFile } from './globals/file-utils.js'; + +mock({ + './foo.toml': `[tool.test]${EOL}version = "${CURRENT_VERSION}"${EOL}`, + './cargo.toml': `[workspace]${EOL}${EOL}[package]${EOL}name = "hello_world"${EOL}version = "${CURRENT_VERSION}"${EOL}authors = [ "Alice ", "Bob " ]${EOL}${EOL}[dependencies]${EOL}time = "0.1.12"${EOL}` +}); + +describe('toml file', { concurrency: true }, () => { + it('should return latest version', async () => { + const options = { + [NAMESPACE]: { in: { file: './foo.toml', path: 'tool.test.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should write', async () => { + const options = { + [NAMESPACE]: { + out: { + file: './foo.toml', + type: 'text/toml', + path: 'tool.test.version' + } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.toml'), `[tool.test]${EOL}version = "${NEW_VERSION}"${EOL}`); + }); + + it('should write without defining the type', async () => { + const options = { + [NAMESPACE]: { out: { file: './foo.toml', path: 'tool.test.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.toml'), `[tool.test]${EOL}version = "${NEW_VERSION}"${EOL}`); + }); + + it('should read/write', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.toml', type: 'application/toml', path: 'tool.test.version' }, + out: { file: './foo.toml', type: 'application/toml', path: 'tool.test.version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.toml'), `[tool.test]${EOL}version = "${NEW_VERSION}"${EOL}`); + }); + + it('should read/write without defining the type', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.toml', path: 'tool.test.version' }, + out: { file: './foo.toml', path: 'tool.test.version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.toml'), `[tool.test]${EOL}version = "${NEW_VERSION}"${EOL}`); + }); + + it('should read/write without formatting', async () => { + const options = { + [NAMESPACE]: { + in: { file: './cargo.toml', path: 'package.version' }, + out: { file: './cargo.toml', path: 'package.version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./cargo.toml'), `[workspace]${EOL}${EOL}[package]${EOL}name = "hello_world"${EOL}version = "${NEW_VERSION}"${EOL}authors = [ "Alice ", "Bob " ]${EOL}${EOL}[dependencies]${EOL}time = "0.1.12"${EOL}`); + }); +}); diff --git a/test/xml.test.js b/test/xml.test.js new file mode 100644 index 0000000..be8b131 --- /dev/null +++ b/test/xml.test.js @@ -0,0 +1,70 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { EOL } from 'os'; + +import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; +import Bumper from '../index.js'; +import { NAMESPACE, CURRENT_VERSION, NEW_VERSION } from './globals/constants.js'; +import { readFile } from './globals/file-utils.js'; + +mock({ + './foo.xml': `${EOL}\t4.0.0${EOL}\tcom.mycompany.app${EOL}\tmy-app${EOL}\t${CURRENT_VERSION}${EOL}\t${EOL}\t\t${EOL}\t\t\tgroup-a${EOL}\t\t\tartifact-a${EOL}\t\t\t${CURRENT_VERSION}${EOL}\t\t${EOL}\t${EOL}${EOL}` +}); + +describe('xml file', { concurrency: true }, () => { + it('should return latest version', async () => { + const options = { [NAMESPACE]: { in: { file: './foo.xml', path: 'project > version' } } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should write', async () => { + const options = { + [NAMESPACE]: { + out: { + file: './foo.xml', + type: 'text/xml', + path: 'project > version' + } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.xml'), `${EOL}\t4.0.0${EOL}\tcom.mycompany.app${EOL}\tmy-app${EOL}\t${NEW_VERSION}${EOL}\t${EOL}\t\t${EOL}\t\t\tgroup-a${EOL}\t\t\tartifact-a${EOL}\t\t\t${CURRENT_VERSION}${EOL}\t\t${EOL}\t${EOL}${EOL}`); + }); + + it('should write without defining the type', async () => { + const options = { + [NAMESPACE]: { out: { file: './foo.xml', path: 'project > version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.xml'), `${EOL}\t4.0.0${EOL}\tcom.mycompany.app${EOL}\tmy-app${EOL}\t${NEW_VERSION}${EOL}\t${EOL}\t\t${EOL}\t\t\tgroup-a${EOL}\t\t\tartifact-a${EOL}\t\t\t${CURRENT_VERSION}${EOL}\t\t${EOL}\t${EOL}${EOL}`); + }); + + it('should read/write', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.xml', type: 'application/xml', path: 'project > version' }, + out: { file: './foo.xml', type: 'application/xml', path: 'project > version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.xml'), `${EOL}\t4.0.0${EOL}\tcom.mycompany.app${EOL}\tmy-app${EOL}\t${NEW_VERSION}${EOL}\t${EOL}\t\t${EOL}\t\t\tgroup-a${EOL}\t\t\tartifact-a${EOL}\t\t\t${CURRENT_VERSION}${EOL}\t\t${EOL}\t${EOL}${EOL}`); + }); + + it('should read/write without defining the type', async () => { + const options = { + [NAMESPACE]: { + in: { file: './foo.xml', path: 'project > version' }, + out: { file: './foo.xml', path: 'project > version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.xml'), `${EOL}\t4.0.0${EOL}\tcom.mycompany.app${EOL}\tmy-app${EOL}\t${NEW_VERSION}${EOL}\t${EOL}\t\t${EOL}\t\t\tgroup-a${EOL}\t\t\tartifact-a${EOL}\t\t\t${CURRENT_VERSION}${EOL}\t\t${EOL}\t${EOL}${EOL}`); + }); +}); diff --git a/test/yaml.test.js b/test/yaml.test.js new file mode 100644 index 0000000..99c2f09 --- /dev/null +++ b/test/yaml.test.js @@ -0,0 +1,63 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { EOL } from 'os'; + +import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; +import Bumper from '../index.js'; +import { NAMESPACE, CURRENT_VERSION, NEW_VERSION } from './globals/constants.js'; +import { readFile } from './globals/file-utils.js'; + +mock({ + './foo.yaml': `version: v${CURRENT_VERSION}${EOL}`, + './nested.yaml': `node:${EOL} item:${EOL} version: ${CURRENT_VERSION}${EOL}` +}); + +describe('yaml file', { concurrency: true }, () => { + it('should return latest version', async () => { + const options = { [NAMESPACE]: { in: './foo.yaml' } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + const version = await plugin.getLatestVersion(); + assert.equal(version, CURRENT_VERSION); + }); + + it('should write', async () => { + const options = { [NAMESPACE]: { out: { file: './foo.yaml', type: 'application/yaml'} } }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./foo.yaml'), `version: ${NEW_VERSION}${EOL}`); + }); + + it('should write without defining the type', async () => { + const options = { + [NAMESPACE]: { out: { file: './nested.yaml', path: 'node.item.version' } } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./nested.yaml'), `node:${EOL} item:${EOL} version: ${NEW_VERSION}${EOL}`); + }); + + it('should read/write', async () => { + const options = { + [NAMESPACE]: { + in: { file: './nested.yaml', type: 'application/x-yaml', path: 'node.item.version' }, + out: { file: './nested.yaml', type: 'text/yaml', path: 'node.item.version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./nested.yaml'), `node:${EOL} item:${EOL} version: ${NEW_VERSION}${EOL}`); + }); + + it('should read/write without defining the type', async () => { + const options = { + [NAMESPACE]: { + in: { file: './nested.yaml', path: 'node.item.version' }, + out: { file: './nested.yaml', path: 'node.item.version' } + } + }; + const plugin = factory(Bumper, { NAMESPACE, options }); + await runTasks(plugin); + assert.equal(readFile('./nested.yaml'), `node:${EOL} item:${EOL} version: ${NEW_VERSION}${EOL}`); + }); +});