diff --git a/.github/workflows/example_app.yml b/.github/workflows/example_app.yml index 52f7afa..439b279 100644 --- a/.github/workflows/example_app.yml +++ b/.github/workflows/example_app.yml @@ -8,7 +8,7 @@ on: jobs: test: - name: Tests & Checks + name: Tests & Checks (Elixir ${{ matrix.elixir }} / OTP ${{ matrix.otp }}) runs-on: ubuntu-latest permissions: contents: read @@ -19,14 +19,24 @@ jobs: env: MIX_ENV: test + strategy: + matrix: + include: + - elixir: '1.15.x' + otp: '25.x' + - elixir: '1.16.x' + otp: '26.x' + - elixir: '1.17.x' + otp: '27.x' + steps: - uses: actions/checkout@v4 - name: Setup Erlang and Elixir - uses: erlef/setup-beam@v1.17 + uses: erlef/setup-beam@v1.18 with: - elixir-version: "1.16.0-otp-26" - otp-version: "26.0" + elixir-version: ${{ matrix.elixir }} + otp-version: ${{ matrix.otp }} - name: Mix and build cache uses: actions/cache@v4 @@ -34,8 +44,9 @@ jobs: path: | ./tests/example_app/deps ./tests/example_app/_build - key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} - restore-keys: ${{ runner.os }}-mix- + key: ${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}-${{ hashFiles('**/mix.lock') }} + restore-keys: | + ${{ runner.os }}-mix-${{ matrix.elixir }}-${{ matrix.otp }}- - name: Get dependencies run: mix deps.get diff --git a/lib/parser.js b/lib/parser.js index 9e5bda9..3b9e2ec 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -3,7 +3,8 @@ const calculatedData = (data, coverageThreshold) => ({ testsSuccess: data.totalFailures === 0, }); -const parser = { +// Used for Elixir <= 1.16 +const oldFormatParser = { pattern: /(.+?)(?=Finished)(.+sync\))\n(.*?)([0-9]+ failure[s]?)(.+)(Randomized with seed [0-9]+)(.+)(Percentage \| Module.+)( [0-9]+\.[0-9]+%)( \| Total)/gs, mapGroupsToData: (groups) => ({ summary: groups[2], @@ -15,7 +16,25 @@ const parser = { }), }; +// Used for Elixir >= 1.17 +const newFormatParser = { + pattern: /(Running ExUnit with seed: [0-9]+, max_cases: [0-9]+\n\n)(.+?)(?=Finished)(Finished.+sync\))\n(.*?)([0-9]+ failure[s]?)(.+?)(Percentage \| Module.+)((?:\n.+)+\n-+\|-+\n\s+([0-9]+\.[0-9]+)%\s+\|\s+Total)/s, + mapGroupsToData: (groups) => ({ + summary: groups[3], + tests: groups[4].slice(0, -2), + totalFailures: parseInt(groups[5]), + totalCoverage: parseFloat(groups[9]), + randomizedSeed: groups[1].trim(), + coverageTable: groups[7] + groups[8], + }), +}; + +const detectFormat = (output) => output.includes("Running ExUnit with seed:") ? "new" : "old"; + const parseData = (output, coverageThreshold) => { + const format = detectFormat(output); + const parser = format === "new" ? newFormatParser : oldFormatParser; + try { parser.pattern.lastIndex = 0; const groups = parser.pattern.exec(output); diff --git a/tests/fixtures/success_03 b/tests/fixtures/success_03 new file mode 100644 index 0000000..4837bdd --- /dev/null +++ b/tests/fixtures/success_03 @@ -0,0 +1,25 @@ +Running ExUnit with seed: 922031, max_cases: 8 + +....................................... +Finished in 0.1 seconds (0.07s async, 0.03s sync) +1 doctest, 38 tests, 0 failures + +Generating cover results ... + +Percentage | Module +-----------|-------------------------- + 100.00% | Example.Application + 100.00% | Example.Lists + 100.00% | Example.Math + 100.00% | Example.Strings + 100.00% | ExampleWeb + 100.00% | ExampleWeb.ConnCase + 100.00% | ExampleWeb.Endpoint + 100.00% | ExampleWeb.ErrorJSON + 100.00% | ExampleWeb.IndexController + 100.00% | ExampleWeb.Router +-----------|-------------------------- + 100.00% | Total + +Generated HTML coverage results in "cover" directory +success running the tests diff --git a/tests/lib/parser.test.js b/tests/lib/parser.test.js index 69c7c40..85b76cc 100644 --- a/tests/lib/parser.test.js +++ b/tests/lib/parser.test.js @@ -45,11 +45,14 @@ describe('parser tests', () => { const fixture = fs.readFileSync(file, 'utf8'); const output = parser(fixture, 80); - const summaryFormat = /^Finished in [0-9.]+ seconds \([0-9.]+s async, [0-9.]+s sync\)$/; - expect(output.summary).toMatch(summaryFormat); + // Format for Elixir versions before 1.17 + const oldSeedFormat = /^Randomized with seed [0-9]+$/; + + // Format for Elixir versions 1.17 and later + const newSeedFormat = /^Running ExUnit with seed: [0-9]+(?:, max_cases: [0-9]+)?$/; + + expect(oldSeedFormat.test(output.randomizedSeed) || newSeedFormat.test(output.randomizedSeed)).toBe(true); - const seedFormat = /^Randomized with seed [0-9]+$/; - expect(output.randomizedSeed).toMatch(seedFormat); expect(Number.isInteger(output.totalFailures)).toBe(true); expect(typeof output.totalCoverage).toBe('number'); });