Custom webpack resolver plugin change #meow to ./meow.js - javascript

I am trying to create a webpack resolver that will convert the import for #meow to the import of ./meow.js. I have some basic code below that shows main imports #meow and the resolver should be converting all require statements to be ./meow.js.
meow.js
module.export = 'meow';
main.js
import meow from '#meow';
console.log(meow);
Resolver.js
module.exports = class Resolver {
apply(compiler) {
compiler.hooks.module.tapPromise('Resolver', async (init, resolveContext) => {
return compiler.doResolve(compiler.hooks.module, init, './meow.js', resolveContext, () => {});
});
}
}

Here's an example I got working with webpack 4.
class Example {
constructor() {
this.name = 'Example';
}
apply(compiler) {
compiler.hooks.resolve.tapPromise(this.name, async (init, context) => {
const callback = () => {};
if (init.request.match('#')) {
init.request = './meow.js'
return compiler.doResolve(compiler.hooks.resolve, init, null, context, callback)
} else {
return callback()
}
})
}
}
module.exports = Example;

I think that it is better to utilize NormalModuleReplacementPlugin to replace all the imports that are matched to some rule.
module.exports = function(env) {
return {
plugins: [
new webpack.NormalModuleReplacementPlugin(/(.*)#meow(\.*)/, function(resource) {
// do what ever mapping
resource.request = resource.request.replace(/#meow/, `meow.js`);
})
]
};
};

Related

clear encapsulated value in imported module - Jest js

Let's say I'm importing to Jest module like:
let var;
export const getVar = () => {
if(var == null) {
var = Date.now()
}
return var;
}
I am trying to make unit tests for this module, however, on every unit test I have to reset the "var" value. I've tried to redefine the module using require on "beforeEach" method but it does not work. Does anyone know how to reset encapsulated values like this?
Using old require syntax and resetModules
foo.js
let foo;
const getFoo = () => {
if (!foo) {
foo = "foo";
} else {
foo = "bar";
}
return foo;
};
module.exports = { getFoo };
foo.test.js
beforeEach(() => jest.resetModules());
test("first", () => {
const { getFoo } = require("./foo");
expect(getFoo()).toBe("foo");
});
test("second", () => {
const { getFoo } = require("./foo");
expect(getFoo()).toBe("foo");
});
Using dynamic import and resetModules
foo.js
let foo;
export const getFoo = () => {
if (!foo) {
foo = "foo";
} else {
foo = "bar";
}
return foo;
};
foo.test.js
import { jest } from "#jest/globals";
beforeEach(async () => {
jest.resetModules();
});
test("first", async () => {
const { getFoo } = await import("./foo.js");
expect(getFoo()).toBe("foo");
});
test("second", async () => {
const { getFoo } = await import("./foo.js");
expect(getFoo()).toBe("foo");
});

How to write simple Jest preset

How to write own Jest preset with common beforeAll and afterAll?
I'm quite confused, seems that there is no related documentation.
There is the environment that you can extend this way:
JEST config:
module.exports = {
testEnvironment: './suites/future/jest.myEnv.js',
};
The jest.myEnv.js:
const NodeEnvironment = require('jest-environment-node');
const start = async () => {
console.log('START');
};
const stop = async () => {
console.log('STOP');
};
class TestEnvironment extends NodeEnvironment {
constructor(config) {
super(config);
}
async setup() {
await super.setup();
await start();
}
async teardown() {
await stop();
await super.teardown();
}
runScript(script) {
return super.runScript(script);
}
}
module.exports = TestEnvironment;

Jest mocking module that exports a class and functions

I have a module that exports a class and 2 functions and that module is imported into a file that is being tested.
someFile.js
const {theclass, thefunction} = require("theModule");
const getSomeFileData = () => {
let obj = new theclass();
//some logic
return obj.getData();
}
In the test file, I want to mock the module "theModule" and return a known value when the function obj.getData() is called. How would I go about mocking this module("theModule") when testing file "someFile.js"?
Edit:
.spec.ts
import { someFunction } from './index-test';
jest.mock('lodash', () => {
return {
uniqueId: () => 2,
};
});
describe('', () => {
it('', () => {
expect(someFunction()).toBe(2);
});
});
index-test.ts
import { uniqueId } from 'lodash';
export const someFunction = () => {
return uniqueId();
};

Tapable.plugin is deprecated. Use new API on `.hooks` instead

A am trying to build a webpack resolver and the .plugin method code below seems to be deprecated and I can't find the analogous method call using .hooks.
module.exports = class Resolver {
apply(compiler) {
compiler.plugin('module', function (init, callback) {
console.log(init);
return callback();
});
}
}
I believe I found it, this works:
module.exports = class Resolver {
apply(compiler) {
compiler.hooks.module.tapPromise('module', async (init) => {
console.log(JSON.stringify(init));
return init;
});
}
}

Stubing a class call from another function

I have 2 files controller.js and entity.js which interact with each other. I am testing controller.js, and it creates an instance of entity.js (class) and use one of its functions. How can I stub/mock/spy the call and the return of that method?
controller.js
const controller= async (req, res) => {
try {
...
const entity = new Entity({
...
});
const validation = await entity.validate();
...
return res.send()
}
} catch (error) {
return res.send(error)
}
};
Entity.js
class Entity{
constructor() {
...
}
...
async validate() {
...
return response;
}
}
Any idea how to test controller.js using supertest, sinon and chai?
Sinon will happily stub the function. Since it's a class method you just need to be sure to stub the function on the prototype:
const controller = async (req, res) => {
const entity = new Entity();
const validation = await entity.validate();
console.log(validation)
};
class Entity{
constructor() {}
async validate() {
return "real function";
}
}
// stub it
let stub = sinon.stub(Entity.prototype, 'validate')
stub.returns('stubbed function')
controller()
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/7.1.1/sinon.min.js"></script>
This solution uses Ava (but you should be able to adapt to Mocha easily). However I'm more familiar with testdouble. If you have no success with sinon (I'm sure you will), here's an alternative that you may want to consider.
So if we have burrito.js:
module.exports = class {
eat() {
return '🌯';
}
};
And lunch.js:
var Burrito = require('./burrito');
module.exports = () => (new Burrito()).eat();
Then in your test:
const td = require('testdouble');
const test = require('ava');
test('swap burrito', t => {
td.replace('./burrito', class FakeBurrito {
eat() {
return '🌮';
}
});
const lunch = require('./lunch');
t.is(lunch(), '🌮'); // PASS
t.is(lunch(), '🌯'); // FAIL
});
The key is to require your dependency (a burrito) before your subject under test (your lunch) requires it, so that you have time to fake it.

Categories