Jest mockImplementation on single function within module - javascript

Hi there I am just trying to use jest to jest my image min module, the issue I am having is when using imagemin it creates its own tmp folder within a child process which just screws with the path because I am using mock-fs. So all I want to do is have a single function within the module return a predetermined result which will then be passed to another function.
So far in my jest I have
it('Should compress jpg', () => {
expect.assertions(1);
let mock = jest.fn();
mock.mockReturnValueOnce(true);
utility.compress = mock;
let opts = {};
let dest = './tmp/dest/img';
let file = path.join(dest, 'jpeg_img.jpg');
return utility.imageCompress(['./dummy_data/img/*.jpg'], dest, opts)
.then(data => {
expect(data).toEqual([]);
expect(fs.existsSync(file)).toBe(true);
expect(fs.statSync('./dummy_data/img/jpeg_img.jpg').size)
.toBeLessThan(fs.statSync(file).size);
});
});
So the utility.imageCompress calls the compress function
I am exporting the function but I still get utility.compress.mockImplementation is not a function.
Any help would be great thanks

Related

Python Function in Javascript Package

I have a python file that holds many subsidiary methods and one essential function calling those subsidiary functions. The essential function takes a string as input and spits out a 2D array. However, I need to use it in the web development project. How do I pass on the user-input string to the python file via JS and then get the output in a JSON format back from the python file?
python file's essential function
def foo(str, num):
bar = doSomething(temp, str)
raw_output = doAction(bar)
final_output= doRefining(raw_output[:num], 10)
return final_output
What I tried in index.js
const getRes = () => {
const child_process = require('child_process');
child_process.spawn('python', ['pythonFile.py']);
process.stdout.on('data',function(response){
var output = response;
return output;
});
}
Your code should work, with only one important modification: instead of doing return output, you should use it. I usually do that by creating a buffer variable outside the callback's scope, and appending the data to it as it arrives.
Then, on the close event, you can use the data, or return it using a promise/callback.
An example:
const child_process = require('child_process');
const getRes = callback => {
child_process.spawn('python', ['pythonFile.py']);
let result = '';
process.stdout.on('data', data => {
result += data;
});
process.on('close', () => {
callback(result);
});
}
// Example usage:
getRes(result => {
console.log('Output:', result);
});

Testing javascript that updates DOM

I am new to web testing and would like to know how can I test javascript that reads and updates the DOM.
function otherFunction(string) {
// do some processing and return processed data
}
function domUpdater() {
var string = document.getElementById("input").value;
document.getElementById("output").innerHTML = otherFunction(string);
}
I can test easily the otherFunction which accepts and input and returns an output.
expect(otherFunction("input1")).to.be("expected1");
expect(otherFunction("input2")).to.be("expected2");
I am not clear on how can I test the domUpdater function which modifies the DOM?
I usually use jsdom, and in my case since I'm using mocha it would look like this (using jsdom-mocha):
var jsdom = require('mocha-jsdom')
var expect = require('chai').expect
describe('mocha tests', function () {
jsdom()
it('has document', function () {
var div = document.createElement('div')
expect(div.nodeName).eql('DIV')
})
})
However if you can afford it (the tests tend to take a bit longer to run) i would recommend looking into running your tests in a headless browser, using something like Puppeteer.
A quick google search yielded this for how to run jest with puppeteer:
First install jest-puppeteer
yarn add --dev jest-puppeteer
Specify preset in your Jest configuration:
{
"preset": "jest-puppeteer"
}
Write your test
describe('Google', () => {
beforeAll(async () => {
await page.goto('https://google.com');
});
it('should be titled "Google"', async () => {
await expect(page.title()).resolves.toMatch('Google');
});
});

Writing to file in NodeJS calling from another JS file

I am having a weird issue writing to a file in NodeJS.
I have this code in my FileHandler.js:
module.exports.writeFile = function (arr) {
var fs = require('fs');
console.log(arr);
var file = fs.createWriteStream(__dirname+'\\test.txt',{encoding: 'utf8'});
file.on('error', function (err) {
console.log(err); });
file.on("finish", function() {
console.log("finished");
});
arr.forEach(function (item) {
file.write(item+"\n");
});
file.end();
}
If I append
exports.writeFile(["1","2","3"])
To the end of this file and then run node FileHandler.js
The file is created correctly.
However, if I call the writeFile function from another .js file as:
var R = require("r-script");
const dataHandler = require("./DataHandler");
const fileHandler = require("./FileHandler");
var out = R(__dirname + "\\apriori.R");
exports.getRules = function () {
dataHandler.getListOfPageVisitsBySession(1000781912582,1530781912582,function (result){
//ignored result variable
fileHandler.writeFile(["1","2","3"]);
})
}
and passing the exact same array to the function it doesn't write anything (but the file is created), neither fires err or finish event.
If it matters, the DataHandler method contains a request module and a GET to another API.
Any clue of the problem?
Thanks in advance

Why is my Observer subscriber not running if I call it after I call an async function?

I have some code that looks like this:
async function promptHandler(source) {
source.subscribe(function(line) {
console.log(`line == ${line}`);
});
let matchingTests = await getMatchingTests('ROGL');
}
This prints out the contents of the source Observable, which is listening to a ReadStream of a txt file. When the function as it is above is called, I see the output of the file. However, if I call subscribe() after getMatchingTests() gets called, like this:
async function promptHandler(source) {
let matchingTests = await getMatchingTests('ROGL');
source.subscribe(function(line) {
console.log(`line == ${line}`);
});
}
I don't see the contents of the txt file. I know that the matchingTests variable contains the successful results of getMatchingTests, so I don't think it's preventing Node from executing that line.
I'm guessing that something about the getMatchingTests async function call is messing with the source Observable, but I'm not seeing how.
Here's my source code:
let fileStream = createReadStream(file)
.pipe(split());
let source = new Observable(o => {
fileStream.on('data', line => {console.log('data'); o.next(line);});
fileStream.on('error', err => o.error(err));
fileStream.on('end', () => {console.log('end'); o.complete();});
});
My intuition here is that the source observable is a hot source, and that by the time await has returned with the matching tests, your text file is already read. So when you subscribe at that point, there is no line to read, they were read before you subscribed to the source.
UPDATE :
Given your code, if the ordering is a problem for your use case, you can consider moving the filestream creation into the observable factory, i.e.
let source = new Observable(o => {
let fileStream = createReadStream(file)
.pipe(split());
fileStream.on('data', line => {console.log('data'); o.next(line);});
fileStream.on('error', err => o.error(err));
fileStream.on('end', () => {console.log('end'); o.complete();});
});
That way, the stream will be created and started only when you subscribe.

Node module is not initialized before use

I am trying to create my first node module to publish to NPM and have hit an issue for which I can't find an answer.
I decided to write the module using Promises and keep everything asynchronous. During initialization the module calls a few functions that spend some time accessing the file system.
My problem is the module is not being fully initialized before being called by consuming code that has required it.
The full module is on GitHub however here is the initialization code:
var uuid = require('node-uuid')
var fsBlobStoreFactory = require('fs-blob-store')
var Promise = require('bluebird')
var validator = require('validator')
var mkdirp = require('mkdirp')
var path = require('path')
var fs = require('fs')
module.exports = BlobStore
function BlobStore(opts) {
if (!(this instanceof BlobStore)) {
return new BlobStore(opts)
}
this._parseOpts(opts) // <-- Synchronous
this.currentBlobPath = ''
this.fsBlobStore = fsBlobStoreFactory(this.opts.blobStoreRoot) // <-- Synchronous
this._buildBlobPath().then(() => {
console.log('Blob Store Initialized');
console.log('Current Blob Path: ' + this.currentBlobPath);
}) // <-- This takes a while and is asynchronous
}
Here is a quick js file I am using for manual tests:
var crispyStream = require('crispy-stream');
var opts = {
blobStoreRoot: '/some/dir/blobs',
dirDepth: 3,
dirWidth: 3
}
var sbs = require('./index')(opts)
// Any code under here that uses sbs will fail because the module has not finished loading.
var input = 'pipe this';
var pipable = crispyStream.createReadStream(input);
sbs.write().then((ws) => {
pipable.pipe(ws);
}
As far as I can tell, the module loader within node is synchronous but because the function calls internally are asynchronous, the require is returning before the module has finished initializing.
The only solutions I can find are to have the consumers of the module use the 'then' method of the Promise, or use a callback.
Any pointers in the right direction would be greatly appreciated.

Categories

Resources