I define this function a file like this, and immediately export it.
const watchMongo = () => {
console.log("foo")
};
module.exports = { watchMongo };
Then I import it and run it the main app, as shown here.
const watchMongo = require('./controllers/path');
watchMongo();
However, I get this error when ran. "watchMongo is not a function".
When I console log 'watchMongo' instead of running it, I'm told "{ watchMongo: [Function: watchMongo] }"
So Node sees and recognizes the function? Until the function needs to be ran? What??
You can do one of 2 things. You are defining watchMongo as a named export. You can either do:
const { watchMongo } = require('./controllers/path');
or on your declaration file export like:
module.exports = watchMongo;
Related
I am developing plugin/index.ts file where I place async functions eg. clearing the database or uploading files to the app, but it starts to grow and I think about a way to keep it clean and structured.
In this video I see that there is a way to store functions in separate files and then export them using module.exports = { function } and then in the index.ts just import them using require.
But I can't have it working for my case.
This is a simplistic form of my plugins/index.ts file:
const uploadDocument = require('./documents');
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
on('task', {
clearDatabase: clearDatabase,
uploadDocument: uploadDocument,
});
async function clearDatabase() { ... }
}
I decided to move the code of function uploadDocument to the plugins/documents.ts file:
and this is how the file plugins/documents.ts looks like:
imports...
async function uploadDocument(fileName: string) { ... }
module.exports = { uploadDocument }
And when I run the test with a task this way:
cy.task("uploadDocument", 'Very_light_file.pdf')
I get this error in Cypress:
It looks like the problem is with your module.exports and the import.
Try this,
// document.ts
export async function uploadDocument(fileName: string) { ... }
// module.exports = { uploadDocument }
// plugins/index.ts
import { uploadDocument } from './documents'
From the post, I can tell TS is mixed JS there. The example is in JS, you're using TS, so there is no module.exports.
Try a pure JS version, then later convert it to TS.
If you look at cypress-io/cypress-realworld-app/blob/develop/cypress/plugins/index.ts you can see they change module.exports to:
// cypress/plugins/index.ts
export default (on, config) => {
config.env.defaultPassword = process.env.SEED_DEFAULT_USER_PASSWORD;
config.env.paginationPageSize = process.env.PAGINATION_PAGE_SIZE;
// Auth0
//
//
}
In my component.test.js, I tried mocking the IntersectionObserver by doing something like this:
const mock = ()=>({
observe: jest.fn(),
disconnect: jest.fn()
});
window.IntersectionObserver = jest.fn().mockImplementation(mock);
describe("Component", ()=>{
it("test 1", ()=>{
render(<Component/>);
...
}
});
My component.js looks something like this (it does that infinite pagination thing):
//ref to last item loaded >> load more items once it enters view
const observer = useRef();
const lastEntryRef = useCallback((node)=>{
...
observer.current.disconnect(); //ERROR LINE
}
...
);
When I run the tests, however, I get TypeError: observer.current.disconnect is not a function; same goes for observer.current.observe() if it runs. I tried testing it inside the it() block of component.test.js itself by instantiating an IntersectionObserver and then calling those methods and the same message showed when I re-ran the tests, so the errors look unrelated to how IntersectionObserver was set up in component.js. Am I not mocking IntersectionObserver correctly? If so, how do I fix it?
I recommend you to replace the arrow function for a normal function because you need to use the new operator to create an InterceptionObserver object:
const mock = function() {
return {
observe: jest.fn(),
disconnect: jest.fn(),
};
};
//--> assign mock directly without jest.fn
window.IntersectionObserver = mock;
The you can check if window.InterceptionObserver.observe has been called.
I have created a module greatings.js like this one:
function greatings() {
this.hello = function() {
return 'hello!';
}
this.goodbye = function() {
return 'goodbye!';
}
}
module.exports = greatings;
Then I imported it into main.js in VUE.JS just like:
import greatings from './assets/js/greatings';
Vue.use(greatings);
Now I would like to use it in my components but if I do it I got an error:
mounted() {
this.greatings.hello();
}
ERROR: Error in mounted hook: "TypeError: Cannot read property 'hello' of undefined"
How to fix it and be able to use my greatings?
Thanks for any help!
greatings.js file should be like this
export default {
hello() {
return "hello";
},
goodbye() {
return "goodbye!";
}
};
and import in any file you want to use like this
import greatings from './assets/js/greatings';
and call any function do you want. remove this function Vue.use(greatings);
When using Vue.use() to register a custom plugin, it has to define an install() function, which is called by Vue. From docs:
A Vue.js plugin should expose an install method. The method will be called with the Vue constructor as the first argument, along with possible options.
See the provided example, for all the options you have when creating a custom plugin: https://v2.vuejs.org/v2/guide/plugins.html
I need to access the fileHandler object of my logger so I can flush the buffer to the file.
This is my program:
import * as log from "https://deno.land/std#0.75.0/log/mod.ts"
import { Application } from "https://deno.land/x/oak#v6.3.1/mod.ts";
const app = new Application()
const port = 7001
await log.setup({
handlers:{
file: new log.handlers.FileHandler("DEBUG",{
filename: "logger.log",
formatter: lr => {
return `${lr.datetime.toISOString()} [${lr.levelName}] ${lr.msg}`
}
})
},
loggers: {
default: {
level: "DEBUG",
handlers: ["file"]
}
}
})
const logger = log.getLogger()
logger.debug("hi there")
app.use((ctx) => {
ctx.response.body = 'Hi there'
})
console.log(`listening on port ${port}`)
app.listen({ port })
My problem is that the log message is never being written to file.
If I remove the last line ( app.listen() ) it Does write to the file because the process ends.
But if I leave it listening process never ends so the log buffer is never flushed.
If I interrupt the process with Ctrl-C it doesn't write it either
Documentation (https://deno.land/std#0.75.0/log/README.md) says I can force log flush using the flush method from FileHandler. But I don't know how to access the fileHandler object.
So I've tried this:
const logger = log.getLogger()
logger.debug("hi there")
logger.handlers[0].flush()
And it works! but only as javascript, NOT as typescript
As typescript I get this error:
error: TS2339 [ERROR]: Property 'flush' does not exist on type 'BaseHandler'.
logger.handlers[0].flush()
Well, I found a solution.
I just have to import the FileHandler class and cast my handler down from BaseHandler to FileHandler.
So I added this line among the imports:
import { FileHandler } from "https://deno.land/std#0.75.0/log/handlers.ts"
And then after creating the logger:
logger.debug("hi there")
const fileHandler = <FileHandler> logger.handlers[0]
fileHandler.flush()
Looks a little weird, I still guess there must be less quirky / more semantic solution for this. But it works ok.
Let us just recap with the help of Santi's answer.
In my experience logs in file work fine in an ending program. I mean a program which dies by itself or with Deno.exit(0). Problem occurs in a never ending loop. In this case logs don't append in their files. Below is how to overcome this situation :
// dev.js : "I want my logs" example
import {serve} from "https://deno.land/std#0.113.0/http/server_legacy.ts";
import * as log from "https://deno.land/std#0.113.0/log/mod.ts";
// very simple setup, adapted from the official standard lib https://deno.land/std#0.113.0/log
await log.setup({
handlers: {
file: new log.handlers.FileHandler("WARNING", {
filename: "./log.txt",
formatter: "{levelName} {msg}",
}),
},
loggers: {
default: {
level: "DEBUG",
handlers: ["file"],
},
},
});
// here we go
let logger;
logger = log.getLogger();
logger.warning('started');
const fileHandler = logger.handlers[0];
await fileHandler.flush(); // <---- the trick, need to flush ! Thanks Santi
// loop on requests
const srv = serve(`:4321`);
for await (const request of srv) {
request.respond({body: 'bonjour', status: 200});
logger.warning('hit !');
fileHandler.flush(); // <---- flush again
}
Run with
$ deno run -A dev.js
And check the file log.txt with the following trigger
$ curl localhost:4321
This is a very low tech, problably adding important delay to the process. The next level will be to fire a time event to flush every minute or so.
I assume this must be a pretty straightforward solution, but I am struggling to find a solution.
I have a function at the top of my tests:
jest.mock('../someFile', () => {
const setWidth = () => {
// lots of complex logic
};
return {
width: jest
.fn()
.mockImplementation(element => {
setWidth(element);
};
};
};
};
So, I understand that jest.mock is hoisted above the import statements in every test run, but say I would like to cut down on the boiler plate code I need in this file and as an example if setWidth was a really big function and I want to import it from another file, is there any way I could do this?
If I move setWidth to another file and try the following it fails due to the hoisting
import { setWidth } from ./setWidth
jest.mock('../someFile', () => {
return {
width: jest
.fn()
.mockImplementation(element => {
setWidth(element);
};
};
};
};
The error received is:
● Test suite failed to run
Invalid variable access: setWidth
Thanks in advance for any possible solutions!
jest.mock gets hoisted above the import, so that won't work. But what you can do is use requireActual
jest.mock('../someFile', () => {
const { setWidth } = jest.requireActual('./setWidth');
return {
width: jest
.fn()
.mockImplementation(element => {
setWidth(element);
};
};
};
};
Looks like you’re starting to go a bit crazy with "testing infrastructure" though - try to consider if there's a more "real" way (less testing infrastructure) you can test your code.
The most likely way to do this is to break the code your testing down into smaller functions/components.