Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add coverage as a separate babel loader if loaders already exist #63

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
name: CI

on: [push, pull_request]
on:
pull_request:
branches:
- '**'
push:
branches:
- master

jobs:
build:
Expand Down
9 changes: 9 additions & 0 deletions e2e-test/webpack-custom/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = (api) => {
api.cache(true);

return {
plugins: [
['@babel/plugin-transform-react-jsx', { pragma: 'createElement' }],
],
};
};
1 change: 1 addition & 0 deletions e2e-test/webpack-custom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@babel/core": "^7.10.3",
"@babel/plugin-transform-react-jsx": "^7.10.3",
"babel-loader": "8.1.0",
"babel-plugin-transform-rename-properties": "^0.1.0",
"karmatic": "file:../..",
Expand Down
9 changes: 7 additions & 2 deletions e2e-test/webpack-custom/src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export function box(value) {
return { _value: value };
// eslint-disable-next-line no-unused-vars
function createElement(tag, props) {
return { tag, props };
}

export function render(value1, value2) {
return <div _value1={value1} _value2={value2} />;
}
22 changes: 16 additions & 6 deletions e2e-test/webpack-custom/test/index.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { box } from '../src/index';
import { render } from '../src/index';

describe('Box', () => {
it('should have a __v property', () => {
const boxed = box(1);
expect('_value' in boxed).toBe(false);
expect(boxed.__v).toBe(1);
describe('Render result', () => {
it('should have a _value1 property', () => {
const result = render(1, 2);
expect('_value1' in result.props).toBe(true);
expect(result.props._value1).toBe(1);
});
it('should have a __v2 property', () => {
const result = render(1, 2);
expect('_value2' in result.props).toBe(false);
expect(result.props.__v2).toBe(2);
});
it('should have a __t property', () => {
const result = render(1, 2);
expect('tag' in result).toBe(false);
expect(result.__t).toBe('div');
});
});
2 changes: 1 addition & 1 deletion e2e-test/webpack-custom/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = {
plugins: [
[
'babel-plugin-transform-rename-properties',
{ rename: { _value: '__v' } },
{ rename: { _value2: '__v2', tag: '__t' } },
],
],
},
Expand Down
31 changes: 24 additions & 7 deletions scripts/run-e2e-tests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,22 @@ async function npmInstall(cwd, prefix) {
*/
async function setupTests(projectPath, prefix) {
const name = path.basename(projectPath);
const log = (...msgs) => console.log(`${info(prefix)}`, ...msgs);
const log = (...msgs) => console.log(info(prefix), ...msgs);
const throwError = (...msgs) => {
process.exitCode = 1;
console.error(error(prefix), ...msgs.map((msg) => error(msg)));
throw new Error(msgs[0]);
};

log(`Beginning E2E test at`, projectPath);
const pkgJsonPath = path.join(projectPath, 'package.json');
if (!(await fileExists(pkgJsonPath))) {
prefix = error(prefix);
console.error(
`${prefix} Could not locate package.json for "${name}". Ensure every e2e test has a package.json defined.`
throwError(
`Could not locate package.json for "${name}".`,
`Ensure every e2e test has a package.json.\n`,
`${prefix} Expected to find one at "${pkgJsonPath}".`
);
console.error(`${prefix} Expected to find one at "${pkgJsonPath}".`);
throw new Error(`Could not locate package.json for "${name}".`);
}

const pkg = JSON.parse(await fs.readFile(pkgJsonPath, 'utf8'));
Expand Down Expand Up @@ -228,10 +233,22 @@ async function setupTests(projectPath, prefix) {
await onExit(cp);
} catch (e) {
process.exitCode = 1;
console.error(error(prefix) + ` Test run failed: ${e.message}`);
throwError(`Test run failed: ${e.message}`);
}

// TODO: validate coverage/lcov.info is not empty
const coveragePath = path.join(projectPath, 'coverage', 'lcov.info');
if (!(await fileExists)) {
throwError(
`Code coverage failed to generate results: Results file does not exist at ${coveragePath}`
);
}

const coverageInfo = await fs.readFile(coveragePath, { encoding: 'utf8' });
if (!coverageInfo) {
throwError(
`Code coverage failed to generate results: Results file is empty`
);
}
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/babel-loader.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default function babelLoader(options) {
export function getDefaultBabelLoader(options) {
return {
test: /\.jsx?$/,
exclude: /node_modules/,
Expand Down
44 changes: 28 additions & 16 deletions src/webpack.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import delve from 'dlv';
import { tryRequire, dedupe } from './lib/util';
import babelLoader from './lib/babel-loader';
import { getDefaultBabelLoader } from './lib/babel-loader';
import cssLoader from './lib/css-loader';

/**
Expand Down Expand Up @@ -104,6 +104,32 @@ export function addWebpackConfig(karmaConfig, pkg, options) {
return Object.assign({}, configured || {}, value);
}

let babelLoader = getLoader((rule) =>
`${rule.use},${rule.loader}`.match(/\bbabel-loader\b/)
);
if (babelLoader) {
if (options.coverage) {
if (babelLoader.loader.query) {
babelLoader.loader.query.plugins = [
...(babelLoader.loader.query?.plugins ?? []),
require.resolve('babel-plugin-istanbul'),
];
} else {
babelLoader.loader.options = babelLoader.loader.options || {};
babelLoader.loader.options.plugins = [
...(babelLoader.loader.options?.plugins ?? []),
require.resolve('babel-plugin-istanbul'),
];
}
}
} else {
loaders.push(getDefaultBabelLoader(options));
}

if (!getLoader('foo.css')) {
loaders.push(cssLoader(options));
}

for (let prop of Object.keys(karmaConfig.preprocessors)) {
karmaConfig.preprocessors[prop].unshift('webpack');
}
Expand All @@ -115,21 +141,7 @@ export function addWebpackConfig(karmaConfig, pkg, options) {
// devtool: 'module-source-map',
mode: webpackConfig.mode || 'development',
module: {
// @TODO check webpack version and use loaders VS rules as the key here appropriately:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this TODO is handled by line 180 below so I removed it

//
// TODO: Consider adding coverage as a separate babel-loader so that
// regardless if the user provides their own babel plugins, coverage still
// works
rules: loaders
.concat(
!getLoader((rule) =>
`${rule.use},${rule.loader}`.match(/\bbabel-loader\b/)
)
? babelLoader(options)
: false,
!getLoader('foo.css') && cssLoader(options)
)
.filter(Boolean),
rules: loaders,
},
resolve: webpackProp('resolve', {
modules: webpackProp('resolve.modules', [
Expand Down