Skip to content

Commit

Permalink
fix(runner): ensure sequential suite overrides sequence.concurrent (#…
Browse files Browse the repository at this point in the history
…6653)

Co-authored-by: Hiroshi Ogawa <[email protected]>
  • Loading branch information
dsyddall and hi-ogawa authored Oct 12, 2024
1 parent 70baaaa commit 5e6de27
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 15 deletions.
9 changes: 5 additions & 4 deletions packages/runner/src/suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,16 +520,17 @@ function createSuite() {
optionsOrFactory,
)

const isConcurrentSpecified = options.concurrent || this.concurrent || options.sequential === false
const isSequentialSpecified = options.sequential || this.sequential || options.concurrent === false

// inherit options from current suite
if (currentSuite?.options) {
options = { ...currentSuite.options, ...options }
}

// inherit concurrent / sequential from suite
const isConcurrent
= options.concurrent || (this.concurrent && !this.sequential)
const isSequential
= options.sequential || (this.sequential && !this.concurrent)
const isConcurrent = isConcurrentSpecified || (options.concurrent && !isSequentialSpecified)
const isSequential = isSequentialSpecified || (options.sequential && !isConcurrentSpecified)
options.concurrent = isConcurrent && !isSequential
options.sequential = isSequential && !isConcurrent

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, test, vi } from 'vitest'

const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout))

let count = 0

describe.concurrent('concurrent suite', () => {
test('first test completes last', async ({ task }) => {
await delay(40)
expect(task.concurrent).toBeTruthy()
expect(++count).toBe(4)
})

test('second test completes third', async ({ task }) => {
await delay(30)
expect(task.concurrent).toBeTruthy()
expect(++count).toBe(3)
})
})

test.concurrent('third test completes second', async ({ task }) => {
await delay(20)
expect(task.concurrent).toBeTruthy()
expect(++count).toBe(2)
})

test.concurrent('last test completes first', async ({ task }) => {
await delay(10)
expect(task.concurrent).toBeTruthy()
expect(++count).toBe(1)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, test, vi } from 'vitest'

const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout))

let count = 0

describe('sequential suite', () => {
test('first test completes first', async ({ task }) => {
await delay(40)
expect(task.concurrent).toBeFalsy()
expect(++count).toBe(1)
})

test('second test completes second', async ({ task }) => {
await delay(30)
expect(task.concurrent).toBeFalsy()
expect(++count).toBe(2)
})
})

test('third test completes third', async ({ task }) => {
await delay(20)
expect(task.concurrent).toBeFalsy()
expect(++count).toBe(3)
})

test('last test completes last', async ({ task }) => {
await delay(10)
expect(task.concurrent).toBeFalsy()
expect(++count).toBe(4)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, test, vi } from 'vitest'

const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout))

let count = 0

describe('concurrent suite', () => {
test('first test completes last', async ({ task }) => {
await delay(40)
expect(task.concurrent).toBeTruthy()
expect(++count).toBe(4)
})

test('second test completes third', async ({ task }) => {
await delay(30)
expect(task.concurrent).toBeTruthy()
expect(++count).toBe(3)
})
})

test('third test completes second', async ({ task }) => {
await delay(20)
expect(task.concurrent).toBeTruthy()
expect(++count).toBe(2)
})

test('last test completes first', async ({ task }) => {
await delay(10)
expect(task.concurrent).toBeTruthy()
expect(++count).toBe(1)
})
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
import { describe, expect, test, vi } from 'vitest'

vi.setConfig({
sequence: {
concurrent: true,
},
})

const delay = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout))

let count = 0

describe.sequential('running sequential suite when sequence.concurrent is true', () => {
describe.sequential('sequential suite', () => {
test('first test completes first', async ({ task }) => {
await delay(50)
await delay(40)
expect(task.concurrent).toBeFalsy()
expect(++count).toBe(1)
})

test('second test completes second', ({ task }) => {
test('second test completes second', async ({ task }) => {
await delay(30)
expect(task.concurrent).toBeFalsy()
expect(++count).toBe(2)
})
})

test.sequential('third test completes third', async ({ task }) => {
await delay(50)
await delay(20)
expect(task.concurrent).toBeFalsy()
expect(++count).toBe(3)
})

test.sequential('fourth test completes fourth', ({ task }) => {
test.sequential('last test completes last', async ({ task }) => {
await delay(10)
expect(task.concurrent).toBeFalsy()
expect(++count).toBe(4)
})
47 changes: 47 additions & 0 deletions test/config/test/sequence-concurrent.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { expect, test } from 'vitest'

import { runVitest } from '../../test-utils'

test('should run suites and tests concurrently unless sequential specified when sequence.concurrent is true', async () => {
const { stderr, stdout } = await runVitest({
root: './fixtures/sequence-concurrent',
include: ['sequence-concurrent-true-*.test.ts'],
sequence: {
concurrent: true,
},
})

expect(stderr).toBe('')

expect(stdout).toContain('✓ sequence-concurrent-true-sequential.test.ts > sequential suite > first test completes first')
expect(stdout).toContain('✓ sequence-concurrent-true-sequential.test.ts > sequential suite > second test completes second')
expect(stdout).toContain('✓ sequence-concurrent-true-sequential.test.ts > third test completes third')
expect(stdout).toContain('✓ sequence-concurrent-true-sequential.test.ts > last test completes last')
expect(stdout).toContain('✓ sequence-concurrent-true-concurrent.test.ts > concurrent suite > first test completes last')
expect(stdout).toContain('✓ sequence-concurrent-true-concurrent.test.ts > concurrent suite > second test completes third')
expect(stdout).toContain('✓ sequence-concurrent-true-concurrent.test.ts > third test completes second')
expect(stdout).toContain('✓ sequence-concurrent-true-concurrent.test.ts > last test completes first')
expect(stdout).toContain('Test Files 2 passed (2)')
})

test('should run suites and tests sequentially unless concurrent specified when sequence.concurrent is false', async () => {
const { stderr, stdout } = await runVitest({
root: './fixtures/sequence-concurrent',
include: ['sequence-concurrent-false-*.test.ts'],
sequence: {
concurrent: false,
},
})

expect(stderr).toBe('')

expect(stdout).toContain('✓ sequence-concurrent-false-sequential.test.ts > sequential suite > first test completes first')
expect(stdout).toContain('✓ sequence-concurrent-false-sequential.test.ts > sequential suite > second test completes second')
expect(stdout).toContain('✓ sequence-concurrent-false-sequential.test.ts > third test completes third')
expect(stdout).toContain('✓ sequence-concurrent-false-sequential.test.ts > last test completes last')
expect(stdout).toContain('✓ sequence-concurrent-false-concurrent.test.ts > concurrent suite > first test completes last')
expect(stdout).toContain('✓ sequence-concurrent-false-concurrent.test.ts > concurrent suite > second test completes third')
expect(stdout).toContain('✓ sequence-concurrent-false-concurrent.test.ts > third test completes second')
expect(stdout).toContain('✓ sequence-concurrent-false-concurrent.test.ts > last test completes first')
expect(stdout).toContain('Test Files 2 passed (2)')
})

0 comments on commit 5e6de27

Please sign in to comment.