|
| 1 | +/** |
| 2 | + * @license |
| 3 | + * Copyright Google LLC All Rights Reserved. |
| 4 | + * |
| 5 | + * Use of this source code is governed by an MIT-style license that can be |
| 6 | + * found in the LICENSE file at https://angular.io/license |
| 7 | + */ |
| 8 | + |
| 9 | +import { last, tap } from 'rxjs/operators'; |
| 10 | +import { promisify } from 'util'; |
| 11 | +import { execute } from '../../index'; |
| 12 | +import { BASE_OPTIONS, KARMA_BUILDER_INFO, describeBuilder } from '../setup'; |
| 13 | + |
| 14 | +// In each of the test below we'll have to call setTimeout to wait for the coverage |
| 15 | +// analysis to be done. This is because karma-coverage performs the analysis |
| 16 | +// asynchronously but the promise that it returns is not awaited by Karma. |
| 17 | +// Coverage analysis begins when onRunComplete() is invoked, and output files |
| 18 | +// are subsequently written to disk. For more information, see |
| 19 | +// https://github.com/karma-runner/karma-coverage/blob/32acafa90ed621abd1df730edb44ae55a4009c2c/lib/reporter.js#L221 |
| 20 | + |
| 21 | +const setTimeoutPromise = promisify(setTimeout); |
| 22 | +const coveragePath = 'coverage/lcov.info'; |
| 23 | + |
| 24 | +describeBuilder(execute, KARMA_BUILDER_INFO, (harness) => { |
| 25 | + describe('Behavior: "codeCoverage"', () => { |
| 26 | + it('should generate coverage report when file was previously processed by Babel', async () => { |
| 27 | + // Force Babel transformation. |
| 28 | + await harness.appendToFile('src/app/app.component.ts', '// async'); |
| 29 | + |
| 30 | + harness.useTarget('test', { |
| 31 | + ...BASE_OPTIONS, |
| 32 | + codeCoverage: true, |
| 33 | + }); |
| 34 | + |
| 35 | + const { result } = await harness.executeOnce(); |
| 36 | + expect(result?.success).toBeTrue(); |
| 37 | + |
| 38 | + await setTimeoutPromise(1000); |
| 39 | + harness.expectFile(coveragePath).toExist(); |
| 40 | + }); |
| 41 | + |
| 42 | + it('should exit with non-zero code when coverage is below threshold', async () => { |
| 43 | + await harness.modifyFile('karma.conf.js', (content) => |
| 44 | + content.replace( |
| 45 | + 'coverageReporter: {', |
| 46 | + `coverageReporter: { |
| 47 | + check: { |
| 48 | + global: { |
| 49 | + statements: 100, |
| 50 | + lines: 100, |
| 51 | + branches: 100, |
| 52 | + functions: 100 |
| 53 | + } |
| 54 | + }, |
| 55 | + `, |
| 56 | + ), |
| 57 | + ); |
| 58 | + |
| 59 | + await harness.appendToFile( |
| 60 | + 'src/app/app.component.ts', |
| 61 | + ` |
| 62 | + export function nonCovered(): boolean { |
| 63 | + return true; |
| 64 | + } |
| 65 | + `, |
| 66 | + ); |
| 67 | + |
| 68 | + harness.useTarget('test', { |
| 69 | + ...BASE_OPTIONS, |
| 70 | + codeCoverage: true, |
| 71 | + }); |
| 72 | + |
| 73 | + await harness |
| 74 | + .execute() |
| 75 | + .pipe( |
| 76 | + // In incremental mode, karma-coverage does not have the ability to mark a |
| 77 | + // run as failed if code coverage does not pass. This is because it does |
| 78 | + // the coverage asynchoronously and Karma does not await the promise |
| 79 | + // returned by the plugin. |
| 80 | + |
| 81 | + // However the program must exit with non-zero exit code. |
| 82 | + // This is a more common use case of coverage testing and must be supported. |
| 83 | + last(), |
| 84 | + tap((buildEvent) => expect(buildEvent.result?.success).toBeFalse()), |
| 85 | + ) |
| 86 | + .toPromise(); |
| 87 | + }); |
| 88 | + }); |
| 89 | +}); |
0 commit comments