I'm building a project based on CJ's from Coding Garden Inventory App. In a knex migration file I have used an external file to bring a helper functions.
tableUtils.js
function addDefaultColumns(table) {
table.timestamps(false, true)
table.datetime('deleted_at')
}
function createNameTable(knex, tableName) {
return knex.schema.createTable(tableName, table => {
table.increments().notNullable()
table.string('name').notNullable().unique()
addDefaultColumns(table)
})
}
module.exports = {
createNameTable,
addDefaultColumns
}
and in my migration file:
const tableNames = require('../../src/constants/tableNames');
const { createNameTable, addDefaultColumns } = require('../../src/constants/tableNames');
exports.up = async (knex) => {
await knex.schema.createTable(tableNames.user, table => {
table.increments().notNullable()
table.string('name').notNullable()
table.string('email', 254).notNullable().unique()
table.string('password', 127).notNullable()
table.string('avatar_url', 2000)
table.string('color', 15).defaultTo('#dddddd')
table.specificType('balance', 'money').defaultTo('0')
addDefaultColumns(table)
})
};
Once tryint to run migration with knex migrate:latest I am getting error:
migration failed with error: addDefaultColumns is not a function
addDefaultColumns is not a function
TypeError: addDefaultColumns is not a function
What am I missing here as it looks like everything should work fine.. The function is declared with function and above module.exports so there shouldn't be a problem of function being undefined..
Your code shows you requiring tableNames, but you show a file named tableUtils.js so it appears you aren't requiring the right file.
Related
I'm trying to write a test for a function that downloads an Excel file within my React app.
I understand that I need to mock certain functionality, but it doesn't seem to be working according to everything that I have read online.
A basic mock that works is this:
import FileSaver from 'file-saver'
import { xlsxExport } from './functions'
// other code...
test('saveAs', async () => {
const saveAsSpy = jest.spyOn(FileSaver, 'saveAs')
FileSaver.saveAs('test')
expect(saveAsSpy).toHaveBeenCalledWith('test')
})
The above works: FileSaver.saveAs was successfully mocked. However, I am utilising FileSaver.saveAs within another function that I wish to test and the mocking does not seem to transfer into that. functions.ts and functions.tests.ts below.
functions.ts:
import { Dictionary } from './interfaces'
import * as ExcelJS from 'exceljs'
import FileSaver from 'file-saver'
export function xlsxExport(data: Dictionary<any>[], fileName?: string, tabName?: string) {
const workbook = new ExcelJS.Workbook()
const worksheet = workbook.addWorksheet(tabName || 'export')
// Get columns from first item in data
worksheet.columns = Object.keys(data[0]).map((key: string) => ({ header: key, key: key }))
// Write each item as a row
for (const row of data) {
worksheet.addRow(row)
}
// Download the file
workbook.xlsx.writeBuffer().then(function (buffer) {
const blob = new Blob([buffer], { type: 'applicationi/xlsx' })
FileSaver.saveAs(blob, (fileName || 'excel_export') + '.xlsx')
})
}
functions.tests.ts
import FileSaver from 'file-saver'
import { xlsxExport } from './functions'
// ...other code
test('xlsxExport', async () => {
const saveAsSpy = jest.spyOn(FileSaver, 'saveAs')
xlsxExport(myArrayOfDicts, 'test_download')
expect(saveAsSpy).toHaveBeenCalledWith('something, anything')
})
Error:
TypeError: Cannot read properties of null (reading 'createElement')
at Function.saveAs (C:\dev\pcig-react\node_modules\file-saver\src\FileSaver.js:92:9)
at C:\dev\pcig-react\src\common\functions.ts:221:19
at processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v19.3.0
FAIL src/common/functions.test.ts
● Test suite failed to run
Jest worker encountered 4 child process exceptions, exceeding retry limit
at ChildProcessWorker.initialize (node_modules/jest-runner/node_modules/jest-worker/build/workers/ChildProcessWorker.js:185:21)
It is trying to call the non-mocked FileSaver.saveAs (line 221 of my file) within xlsxExport.
How can I get it to call the mocked version?
I am currently using sql.js to view my database:
async function sqliteRun () { // eslint-disable-line
const SQL = await initSqlJs({
locateFile: () => 'misc/sql-wasm.wasm'
})
const db = new SQL.Database('public/misc/test.sqlite')
const stmt = db.prepare('SELECT * FROM test')
while (stmt.step()) { //
const row = stmt.getAsObject()
console.log('Here is a row: ' + JSON.stringify(row))
}
}
But then I am getting an error: "File is not a database". I double checked my file and it seems correct (I was able to view it in a sqlite file browser)
I also tried using .db and .sql, all give out the same error.
I prefer to load the file directly in the new SQL.Database() constructor. I wont be able to use fs. Any thoughts on how to do this?
I have the following code:
NOTE getDb() is wrapper around admin.firestore() see the link in the end of the question for more details.
let wordRef = await getDb().
.collection(DOC_HAS_WORD_COUNT)
.doc(word)
await wordRef.set({ word: word, 'count': 0 })
await wordRef.update('count', admin.firestore.FieldValue.increment(1))
When I execute it I get
FirebaseError: Function DocumentReference.update() called with invalid data. Unsupported field value: a custom object (found in field count)
How do I increment the value in node js, firestore, cloud functions?
NOTE: this problem is specific to Mocha testing, I didn't check but it will probably not fail on real env.
The problem is caused by the code using the real implementation in test, which need to be override by an emulator implementation, as explain in:
https://claritydev.net/blog/testing-firestore-locally-with-firebase-emulators/
Where u can also find the definition of getDb() I used in the code snipet
The following code will replace the firebase admin at run time, only when running in test env.
NOTE: this code is based on https://claritydev.net/blog/testing-firestore-locally-with-firebase-emulators/
and for a full solution, one need to do the same trick for db as explained in the link
//db.js
const admin = require("firebase-admin");
let firebase;
if (process.env.NODE_ENV !== "test") {
firebase = admin
}
exports.getFirebase = () => {
return firebase;
};
exports.setFirebase = (fb) => {
firebase = fb;
};
test:
// package.test.js
process.env.NODE_ENV = "test"
beforeEach(() => {
// Set the emulator firebase before each test
setFirebase(firebase)
});
import:
// package.test.js and package.js (at the top)
const { setFirebase } = require("../db.js")
code:
// package.js
let wordRef = await getDb()
.collection(DOC_HAS_WORD_COUNT)
.doc(word)
await wordRef.set({ word: word, 'count': 0 })
await wordRef.update('count', getFirebase().firestore.FieldValue.increment(1))
I'm trying to create a JHipster generator to setup Axon2 for the generated project.
In order to add a java library to the project I'using the function
addMavenDependency in the index.js,
try {
addMavenDependency('org.axonframework', 'axon-integration', '2.4.6','');
}catch (e) {
but I receive the following error:
ERROR!
Problem when adding the new libraries in your pom.xml
You need to add manually:
"org.axonframework:axon-integration": "2.4.6",
ReferenceError: addMavenDependency is not defined
Any help will be really appreciated.
You need to extend the BaseGenerator and call this.addMavenDependency().
Unless you are composing with another generator, then you can pass an object to be populated with the variables and functions being used by the generator like so:
const jhipsterVar = { moduleName: 'your-module' };
const jhipsterFunc = {};
module.exports = generator.extend({
initializing: {
compose() {
this.composeWith('other-module',
{ jhipsterVar, jhipsterFunc },
this.options.testmode ? { local: require.resolve('generator-jhipster/generators/modules') } : null
);
}
},
writing: {
jhipsterFunc.addMavenDependency('com.test', 'test', '1.0.0');
}
});
My Model Code is as follows:
module.exports = function(){
'use strict';
return {
getAllUsers : getAllUsers,
getWatchlists : getWatchlists,
getUserBidDetails : getUserBidDetails,
addToWatchlist : addToWatchlist,
removeFromWatchlist : removeFromWatchlist,
getUserBuyingLimit : getUserBuyingLimit,
userBidDetails : userBidDetails,
getUserWatchlists : getUserWatchlists
};
}
I have defined all the functions which we are returning in module.exports, but when the last function i.e "getUserWatchlists" get called then it is throwing an error
Error: has no method 'getUserWatchlists'
Might be i am not using the correct way to return multiple function in single module.exports function. Kindly suggest
Why not just set module.exports to the object that you're currently returning? For example:
module.exports = {
getAllUsers: getAllUsers,
getWatchlists: getWatchlists,
getUserBidDetails: getUserBidDetails,
addToWatchlist: addToWatchlist,
removeFromWatchlist: removeFromWatchlist,
getUserBuyingLimit: getUserBuyingLimit,
userBidDetails: userBidDetails,
getUserWatchlists: getUserWatchlists
};
Alternatively if you want to avoid duplicating the names like that, you could just set the functions on the exports object and avoid re-assigning module.exports at all. For example:
exports.getAllUsers = function getAllUsers(...) {
// ...
};
exports.getWatchlists = function getWatchlists(...) {
// ...
};
// ... etc.