diff --git a/.eslintrc.json b/.eslintrc.json index 62ca0f4..98be725 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,6 +10,7 @@ "ObjectPattern": { "multiline": true, "consistent": true } }], "import/extensions": ["error", "ignorePackages"], + "import/no-extraneous-dependencies": ["error", { "devDependencies": true }], "import/prefer-default-export": 0 } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a5817b..4735f4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,21 +8,21 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@main - name: Use Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: '12.x' + node-version: 22 - name: Install Dependencies run: npm i - name: Build run: npm run build - name: Test - run: npm test + run: npm run cover - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} - file: ./coverage/lcov.info + file: ./coverage/clover.xml if: github.event_name == 'push' continue-on-error: true diff --git a/.gitignore b/.gitignore index f6e5f3d..aeb2ade 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ npm-debug.log* node_modules coverage -temp package-lock.json diff --git a/README.md b/README.md index b1b446b..1412c5c 100755 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ # ass-compiler -[![GitHub Action](https://github.com/weizhenye/ass-compiler/workflows/CI/badge.svg)](https://github.com/weizhenye/ass-compiler/actions) -[![Coverage](https://badgen.net/codecov/c/github/weizhenye/ass-compiler?icon=codecov)](https://codecov.io/gh/weizhenye/ass-compiler) -[![Dependencies](https://badgen.net/david/dep/weizhenye/ass-compiler?icon=https://api.iconify.design/si-glyph:connect-2.svg?color=white)](https://david-dm.org/weizhenye/ass-compiler) -[![NPM version](https://badgen.net/npm/v/ass-compiler?icon=npm)](https://www.npmjs.com/package/ass-compiler) -[![License](https://badgen.net/npm/license/ass-compiler?icon=https://api.iconify.design/octicon:law.svg?color=white)](https://github.com/weizhenye/ass-compiler/blob/master/LICENSE) -[![File size](https://badgen.net/bundlephobia/minzip/ass-compiler?icon=https://api.iconify.design/ant-design:file-zip-outline.svg?color=white)](https://bundlephobia.com/result?p=ass-compiler) -[![jsDelivr](https://badgen.net/jsdelivr/hits/npm/ass-compiler?icon=https://api.iconify.design/simple-icons:jsdelivr.svg?color=white)](https://www.jsdelivr.com/package/npm/ass-compiler) +[![GitHub Action](https://img.shields.io/github/actions/workflow/status/weizhenye/ass-compiler/ci.yml?logo=github)](https://github.com/weizhenye/ass-compiler/actions) +[![Codecov](https://img.shields.io/codecov/c/gh/weizhenye/ass-compiler?logo=codecov)](https://codecov.io/gh/weizhenye/ass-compiler) +[![License](https://img.shields.io/npm/l/ass-compiler)](https://github.com/weizhenye/ass-compiler/blob/master/LICENSE) +[![NPM Version](https://img.shields.io/npm/v/ass-compiler?logo=npm)](https://www.npmjs.com/package/ass-compiler) +[![jsDelivr](https://img.shields.io/jsdelivr/npm/hm/ass-compiler?logo=jsdelivr)](https://www.jsdelivr.com/package/npm/ass-compiler) +[![File size](https://img.shields.io/bundlejs/size/ass-compiler)](https://bundlephobia.com/result?p=ass-compiler) Parses and compiles ASS subtitle format to easy-to-use data structure. diff --git a/package.json b/package.json index a032a83..9c048b0 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "ass-compiler", "version": "0.1.11", + "type": "module", "description": "Parses and compiles ASS subtitle format to easy-to-use data structure.", "main": "dist/ass-compiler.js", "module": "src/index.js", @@ -13,10 +14,9 @@ "types": "types/index.d.ts", "scripts": { "lint": "eslint src test", - "preunit": "rollup -c rollup.config.test.js", - "unit": "mocha temp/test.js", - "cover": "cross-env ISTANBUL_REPORT_DIR=coverage ISTANBUL_REPORTERS=text-summary,lcov npm run unit -- --reporter=mocha-istanbul", - "test": "npm run lint && npm run unit && npm run cover", + "unit": "vitest run", + "cover": "vitest run --coverage", + "test": "npm run lint && npm run unit", "dev": "rollup -c -w", "bundle": "rollup -c", "minify": "uglifyjs dist/ass-compiler.js -m -o dist/ass-compiler.min.js", @@ -43,19 +43,14 @@ }, "homepage": "https://ass.js.org/ass-compiler/", "devDependencies": { - "chai": "^4.2.0", - "cross-env": "^7.0.2", - "eslint": "^6.8.0", - "eslint-config-airbnb-base": "^14.1.0", - "eslint-plugin-import": "^2.20.2", - "istanbul": "^0.4.5", - "mocha": "^7.1.1", - "mocha-istanbul": "^0.3.0", - "rollup": "^2.6.1", + "@vitest/coverage-v8": "^2.0.4", + "eslint": "^8.57.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "npm:eslint-plugin-i@^2.29.1", + "rollup": "^4.19.0", "rollup-plugin-buble": "^0.19.8", - "rollup-plugin-istanbul": "^2.0.1", - "rollup-plugin-multi-entry": "^2.1.0", "rollup-plugin-replace": "^2.2.0", - "uglify-js": "^3.9.1" + "uglify-js": "^3.19.0", + "vitest": "^2.0.4" } } diff --git a/rollup.config.test.js b/rollup.config.test.js deleted file mode 100644 index 854ec4c..0000000 --- a/rollup.config.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import multiEntry from 'rollup-plugin-multi-entry'; -import istanbul from 'rollup-plugin-istanbul'; - -export default { - input: 'test/**/*.js', - output: { - file: 'temp/test.js', - format: 'cjs', - }, - external: ['chai'], - plugins: [ - multiEntry(), - istanbul({ exclude: ['test/**/*'] }), - ], -}; diff --git a/src/compiler/dialogues.js b/src/compiler/dialogues.js index 4beea7b..16a9b2b 100755 --- a/src/compiler/dialogues.js +++ b/src/compiler/dialogues.js @@ -1,5 +1,4 @@ import { compileText } from './text.js'; -import { assign } from '../utils.js'; export function compileDialogues({ styles, dialogues }) { let minLayer = Infinity; @@ -22,7 +21,7 @@ export function compileDialogues({ styles, dialogues }) { }); const alignment = compiledText.alignment || stl.Alignment; minLayer = Math.min(minLayer, dia.Layer); - results.push(assign({ + results.push(Object.assign({ layer: dia.Layer, start: dia.Start, end: dia.End, diff --git a/src/compiler/drawing.js b/src/compiler/drawing.js index 492cdf6..d23263e 100755 --- a/src/compiler/drawing.js +++ b/src/compiler/drawing.js @@ -1,5 +1,3 @@ -import { assign } from '../utils.js'; - function createCommand(arr) { const cmd = { type: null, @@ -131,5 +129,5 @@ export function compileDrawing(rawCommands) { )), ); - return assign({ instructions, d: toSVGPath(instructions) }, getViewBox(commands)); + return Object.assign({ instructions, d: toSVGPath(instructions) }, getViewBox(commands)); } diff --git a/src/compiler/styles.js b/src/compiler/styles.js index f4f8406..50f83cc 100755 --- a/src/compiler/styles.js +++ b/src/compiler/styles.js @@ -1,5 +1,3 @@ -import { assign } from '../utils.js'; - // same as Aegisub // https://github.com/Aegisub/Aegisub/blob/master/src/ass_style.h const DEFAULT_STYLE = { @@ -54,9 +52,9 @@ export function parseStyleColor(color) { export function compileStyles({ info, style, defaultStyle }) { const result = {}; - const styles = [assign({}, defaultStyle, { Name: 'Default' })].concat(style); + const styles = [Object.assign({}, defaultStyle, { Name: 'Default' })].concat(style); for (let i = 0; i < styles.length; i++) { - const s = assign({}, DEFAULT_STYLE, styles[i]); + const s = Object.assign({}, DEFAULT_STYLE, styles[i]); // this behavior is same as Aegisub by black-box testing if (/^(\*+)Default$/.test(s.Name)) { s.Name = 'Default'; diff --git a/src/compiler/tag.js b/src/compiler/tag.js index 8dc919d..94d6641 100644 --- a/src/compiler/tag.js +++ b/src/compiler/tag.js @@ -1,5 +1,4 @@ import { compileDrawing } from './drawing.js'; -import { assign } from '../utils.js'; const tTags = [ 'fs', 'fsp', 'clip', @@ -79,7 +78,7 @@ export function compileTag(tag, key, presets = {}) { tags.forEach((t) => { const k = Object.keys(t)[0]; if (~tTags.indexOf(k) && !(k === 'clip' && !t[k].dots)) { - assign(compiledTag, compileTag(t, k, presets)); + Object.assign(compiledTag, compileTag(t, k, presets)); } }); return { t: { t1, t2, accel, tag: compiledTag } }; diff --git a/src/compiler/text.js b/src/compiler/text.js index 7254140..1a9a825 100644 --- a/src/compiler/text.js +++ b/src/compiler/text.js @@ -1,6 +1,5 @@ import { compileDrawing } from './drawing.js'; import { compileTag } from './tag.js'; -import { assign } from '../utils.js'; const a2an = [ null, 1, 2, 3, @@ -11,7 +10,7 @@ const a2an = [ const globalTags = ['r', 'a', 'an', 'pos', 'org', 'move', 'fade', 'fad', 'clip']; function inheritTag(pTag) { - return JSON.parse(JSON.stringify(assign({}, pTag, { + return JSON.parse(JSON.stringify(Object.assign({}, pTag, { k: undefined, kf: undefined, ko: undefined, @@ -59,7 +58,7 @@ export function compileText({ styles, style, parsed, start, end }) { fragment.tag.t = fragment.tag.t || []; fragment.tag.t.push(compiledTag.t); } else { - assign(fragment.tag, compiledTag); + Object.assign(fragment.tag, compiledTag); } } } @@ -80,5 +79,5 @@ export function compileText({ styles, style, parsed, start, end }) { } slices.push(slice); - return assign({ alignment, slices }, pos, org, move, fade, clip); + return Object.assign({ alignment, slices }, pos, org, move, fade, clip); } diff --git a/src/decompiler.js b/src/decompiler.js index 448ecf2..2453250 100644 --- a/src/decompiler.js +++ b/src/decompiler.js @@ -1,8 +1,8 @@ import { stringifyInfo, stringifyTime, stringifyEffect } from './stringifier.js'; -import { assign, stylesFormat, eventsFormat } from './utils.js'; +import { stylesFormat, eventsFormat } from './utils.js'; export function decompileStyle({ style, tag }) { - const obj = assign({}, style, { + const obj = Object.assign({}, style, { PrimaryColour: `&H${tag.a1}${tag.c1}`, SecondaryColour: `&H${tag.a2}${tag.c2}`, OutlineColour: `&H${tag.a3}${tag.c3}`, @@ -117,7 +117,7 @@ export function decompileDialogue(dia, style) { export function decompile({ info, width, height, collisions, styles, dialogues }) { return [ '[Script Info]', - stringifyInfo(assign({}, info, { + stringifyInfo(Object.assign({}, info, { PlayResX: width, PlayResY: height, Collisions: collisions, diff --git a/src/parser/style.js b/src/parser/style.js index ecacb03..4f934fc 100755 --- a/src/parser/style.js +++ b/src/parser/style.js @@ -1,6 +1,4 @@ -import { assign } from '../utils.js'; - export function parseStyle(text, format) { const values = text.match(/Style\s*:\s*(.*)/i)[1].split(/\s*,\s*/); - return assign({}, ...format.map((fmt, idx) => ({ [fmt]: values[idx] }))); + return Object.assign({}, ...format.map((fmt, idx) => ({ [fmt]: values[idx] }))); } diff --git a/src/utils.js b/src/utils.js index 71013c1..a76c69c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,17 +1,2 @@ -export const assign = Object.assign || ( - /* istanbul ignore next */ - function assign(target, ...sources) { - for (let i = 0; i < sources.length; i++) { - if (!sources[i]) continue; - const keys = Object.keys(sources[i]); - for (let j = 0; j < keys.length; j++) { - // eslint-disable-next-line no-param-reassign - target[keys[j]] = sources[i][keys[j]]; - } - } - return target; - } -); - export const stylesFormat = ['Name', 'Fontname', 'Fontsize', 'PrimaryColour', 'SecondaryColour', 'OutlineColour', 'BackColour', 'Bold', 'Italic', 'Underline', 'StrikeOut', 'ScaleX', 'ScaleY', 'Spacing', 'Angle', 'BorderStyle', 'Outline', 'Shadow', 'Alignment', 'MarginL', 'MarginR', 'MarginV', 'Encoding']; export const eventsFormat = ['Layer', 'Start', 'End', 'Style', 'Name', 'MarginL', 'MarginR', 'MarginV', 'Effect', 'Text']; diff --git a/test/.eslintrc.json b/test/.eslintrc.json deleted file mode 100755 index cc22815..0000000 --- a/test/.eslintrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "env": { - "mocha": true - }, - "rules": { - "import/no-extraneous-dependencies": ["error", { "devDependencies": true }] - } -} diff --git a/test/compiler/dialogues.js b/test/compiler/dialogues.js index 7fa0df7..8548406 100644 --- a/test/compiler/dialogues.js +++ b/test/compiler/dialogues.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseDialogue } from '../../src/parser/dialogue.js'; import { compileDialogues } from '../../src/compiler/dialogues.js'; import { compileStyles } from '../../src/compiler/styles.js'; diff --git a/test/compiler/drawing.js b/test/compiler/drawing.js index 5a43f63..36b8c9a 100644 --- a/test/compiler/drawing.js +++ b/test/compiler/drawing.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseDrawing } from '../../src/parser/drawing.js'; import { s2b, toSVGPath, compileDrawing } from '../../src/compiler/drawing.js'; diff --git a/test/compiler/index.js b/test/compiler/index.js index 3fd243e..1336da1 100644 --- a/test/compiler/index.js +++ b/test/compiler/index.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { compile } from '../../src/compiler/index.js'; import { text } from '../fixtures/index.js'; diff --git a/test/compiler/styles.js b/test/compiler/styles.js index b543fee..bae6120 100644 --- a/test/compiler/styles.js +++ b/test/compiler/styles.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseStyle } from '../../src/parser/style.js'; import { parseStyleColor, compileStyles } from '../../src/compiler/styles.js'; import { stylesFormat } from '../../src/utils.js'; diff --git a/test/compiler/tag.js b/test/compiler/tag.js index b41e6fc..5eee77a 100644 --- a/test/compiler/tag.js +++ b/test/compiler/tag.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { compileTag } from '../../src/compiler/tag.js'; describe('tag compiler', () => { diff --git a/test/compiler/text.js b/test/compiler/text.js index 4b19a04..848f779 100644 --- a/test/compiler/text.js +++ b/test/compiler/text.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseText } from '../../src/parser/text.js'; import { compileStyles } from '../../src/compiler/styles.js'; import { compileText } from '../../src/compiler/text.js'; diff --git a/test/decompiler.js b/test/decompiler.js index 732334b..51419ad 100644 --- a/test/decompiler.js +++ b/test/decompiler.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { decompile, decompileDrawing, decompileTag, decompileText } from '../src/decompiler.js'; import { compiled, decompiled, compiled2, decompiled2 } from './fixtures/decompiler.js'; diff --git a/test/index.js b/test/index.js index aea73cb..7add142 100644 --- a/test/index.js +++ b/test/index.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parse, stringify, compile, decompile } from '../src/index.js'; describe('ass-compiler', () => { diff --git a/test/parser/dialogue.js b/test/parser/dialogue.js index f5e9f9d..febac62 100755 --- a/test/parser/dialogue.js +++ b/test/parser/dialogue.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseDialogue } from '../../src/parser/dialogue.js'; import { eventsFormat } from '../../src/utils.js'; diff --git a/test/parser/drawing.js b/test/parser/drawing.js index c7565fb..de2c1fe 100755 --- a/test/parser/drawing.js +++ b/test/parser/drawing.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseDrawing } from '../../src/parser/drawing.js'; describe('drawing parser', () => { diff --git a/test/parser/effect.js b/test/parser/effect.js index c87cba9..a8dd933 100755 --- a/test/parser/effect.js +++ b/test/parser/effect.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseEffect } from '../../src/parser/effect.js'; describe('effect parser', () => { diff --git a/test/parser/format.js b/test/parser/format.js index 6daa465..d2cb83d 100644 --- a/test/parser/format.js +++ b/test/parser/format.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseFormat } from '../../src/parser/format.js'; import { stylesFormat, eventsFormat } from '../../src/utils.js'; diff --git a/test/parser/index.js b/test/parser/index.js index 580c5cb..118be2a 100755 --- a/test/parser/index.js +++ b/test/parser/index.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parse } from '../../src/parser/index.js'; import { stylesFormat, eventsFormat } from '../../src/utils.js'; import { text } from '../fixtures/index.js'; diff --git a/test/parser/style.js b/test/parser/style.js index b07949f..f9554fb 100755 --- a/test/parser/style.js +++ b/test/parser/style.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseStyle } from '../../src/parser/style.js'; import { stylesFormat } from '../../src/utils.js'; diff --git a/test/parser/tag.js b/test/parser/tag.js index 5960f84..3c92f33 100755 --- a/test/parser/tag.js +++ b/test/parser/tag.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseTag } from '../../src/parser/tag.js'; describe('tag parser', () => { diff --git a/test/parser/tags.js b/test/parser/tags.js index b0e0335..3e9c4e3 100755 --- a/test/parser/tags.js +++ b/test/parser/tags.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseTags } from '../../src/parser/tags.js'; describe('tags parser', () => { diff --git a/test/parser/text.js b/test/parser/text.js index 89934cf..af1e795 100755 --- a/test/parser/text.js +++ b/test/parser/text.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseText } from '../../src/parser/text.js'; describe('text parser', () => { diff --git a/test/parser/time.js b/test/parser/time.js index 4d69564..b191552 100755 --- a/test/parser/time.js +++ b/test/parser/time.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { parseTime } from '../../src/parser/time.js'; describe('time parser', () => { diff --git a/test/stringifier.js b/test/stringifier.js index 3284b3b..a2d4a9e 100644 --- a/test/stringifier.js +++ b/test/stringifier.js @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { describe, it, expect } from 'vitest'; import { stringifyTime, stringifyEffect, stringifyEvent, stringifyTag, stringify } from '../src/stringifier.js'; import { eventsFormat } from '../src/utils.js'; import { parsed, stringified, parsed2, stringified2 } from './fixtures/stringifier.js'; diff --git a/vitest.config.js b/vitest.config.js new file mode 100644 index 0000000..09693ac --- /dev/null +++ b/vitest.config.js @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: 'test/**/*.js', + exclude: 'test/fixtures/*.js', + }, +});