I'm working on some test for a very small vanilla js library, so I have this module
var otherModule = require('../module/mymodule');
var postscribe = require('postscribe');
var exports = module.exports = {};
var API_URL = URL;
exports.myFunction = function (arg1, arg2, arg3) {
if (arg1 && arg2) {
var myUrl = getApiUrl(arg1, arg2, arg3);
callSomeURL(myUrl);
}
}
function getApiUrl(arg1, arg2, arg3) {
var param1 = otherModule.getParams(arg1);
var param2 = otherModule.getOtherParams(arg1);
return `${API_URL}/v1/pixels/${arg1}/${arg2}${param1}${param2}`;
}
...
then I have otherModule module with my functions
var GLOBAL_VALUE = MY_VALUE;
var otherModule = {};
otherModule.getParams = function (arg1) {
return arg1 ? `&value=${arg1}` : '';
}
otherModule.getOtherParams = function (arg1) {
return GLOBAL_VALUE + arg1
}
module.exports = otherModule;
And my webpack configs
const { DefinePlugin } = require('webpack');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const devConfig = require('./src/config/dev');
module.exports = () => {
var envConfig = devConfig;
return merge(common, {
mode: 'development',
devtool: 'inline-source-map',
plugins: [
new DefinePlugin({
__DEV__: true,
URL: JSON.stringify(envConfig.URL),
MY_VALUE: JSON.stringify(envConfig.VALUE)
})
]
})
}
my common is:
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: './src/index.js',
plugins: [
new CleanWebpackPlugin()
],
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
};
And my jest.config
const config = require('./src/config/dev');
module.exports = {
globals: {
"MY_VALUE": config.VALUE,
"URL" : config.URL
}
}
my problem appears when I try to test exports.myFunction via rewire to have access to private function getApiUrl it seems that I can't access to the imported global values, like GLOBAL_VALUE
in my myOther, I keep getting ReferenceError: GLOBAL_VALUE is not defined, but when I test myOther module directly everything seems to work, can someone throw some light or resources on what I'm doing wrong?
Related
I'm trying to migrate an old express site to webpack, but don't wanna rework all the layout tempaltes which use express-handlebars. Is it possible to use express-handlebars with webpack?
handlebars-loader seems not to support the layout concept of express-handlebars, so is no help here.
A custom loader seems to do the trick:
express-handlebars-loader.js:
const loaderUtils = require('loader-utils');
const validateOptions = require('schema-utils');
const path = require('path');
const express = require('express');
const exphbs = require('express-handlebars');
module.exports = function (content) {
const options = loaderUtils.getOptions(this);
const app = options.app;
const contextCallback = options.contextCallback;
const view = path.relative(options.basePath, this.resourcePath);
const context = contextCallback(this.resourcePath, view);
var loaderAsyncCallback = this.async();
app.render(view, context, function (err, html) {
if (err) {
return loaderAsyncCallback(err);
}
const slug =
'// Module\n'
+ 'var code = ' + JSON.stringify(html) + ';\n'
+ '// Exports\n'
+ 'module.exports = code;'
loaderAsyncCallback(null, slug);
});
};
webpack.config.js:
const CopyPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const fs = require('fs');
const url = require('url');
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
// Handlebars Setup
/**
* Instantiate a Handlebars instance with our config (default layout, helpers, etc.)
*/
const handlebasInstance = exphbs.create({
defaultLayout: 'mainLayout',
// Specify helpers which are only registered on this instance.
helpers
});
app.engine('handlebars', handlebasInstance.engine);
app.set('view engine', 'handlebars');
app.use('/assets', express.static('assets'));
const basePath = path.resolve(__dirname, './views');
function generateHtmlPlugins(templateDir) {
const itemList = fs.readdirSync(templateDir);
return itemList.flatMap(item => {
const [ name, extension ] = item.split('.');
if (extension == 'handlebars') {
const templatePath = path.resolve(templateDir, item);
const outputPath = path.resolve(templateDir, name + '.html');
const outputName = path.relative(basePath, outputPath);
return new HtmlWebpackPlugin({
filename: outputName,
inject: false,
template: templatePath
})
} else {
return [];
}
})
}
const siteHtmlPlugins = generateHtmlPlugins(basePath);
function contextCallback(resourcePath, view) {
var context = {};
if (view.includes('documentation/')) {
context.layout = 'documentationLayout';
}
return context;
}
module.exports = {
mode: 'development',
resolveLoader: {
modules: [ 'node_modules', path.resolve(__dirname, 'loaders') ]
},
entry: './src/entry-workaround.js',
output: {
filename: 'entry-workaround.js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [{
test: /\.handlebars$/,
loader: "express-handlebars-loader",
options: {
app: app,
basePath: basePath,
contextCallback: contextCallback,
}
}]
},
plugins: []
};
I have a test to test my cloudflare worker that looks like this:
const workerScript = fs.readFileSync(
path.resolve(__dirname, '../pkg-prd/worker.js'),
'utf8'
);
describe('worker unit test', function () {
// this.timeout(60000);
let worker;
beforeEach(() => {
worker = new Cloudworker(workerScript, {
bindings: {
HTMLRewriter
},
});
});
it('tests requests and responses', async () => {
const request = new Cloudworker.Request('https://www.example.com/pathname')
const response = await worker.dispatch(request);
console.log(response);
// const body = await response.json();
expect(response.status).to.eql(200);
// expect(body).to.eql({message: 'Hello mocha!'});
});
});
In my worker I do something like this:
const response = await fetch(BASE_URL, request);
const modifiedResponse = new Response(response.body, response);
// Remove the webflow badge
class ElementHandler {
element(element) {
element.append('<style type="text/css">body .w-webflow-badge {display: none!important}</style>', {html: true})
}
}
console.log(3);
return new HTMLRewriter()
.on('head', new ElementHandler()).transform(modifiedResponse);
Now when i run my test I get this error message:
● worker unit test › tests requests and responses
TypeError: Cannot read property 'transform' of undefined
at evalmachine.<anonymous>:1:1364
at FetchEvent.respondWith (node_modules/#dollarshaveclub/cloudworker/lib/cloudworker.js:39:17)
What seems to be wrong?
HTMLRewriter i created looks like this:
function HTMLRewriter() {
const elementHandler = {};
const on = (selector, handler) => {
if (handler && handler.element) {
if (!elementHandler[selector]) {
elementHandler[selector] = [];
}
elementHandler[selector].push(handler.element.bind(handler));
}
};
const transform = async response => {
const tempResponse = response.clone();
const doc = HTMLParser.parse(await tempResponse.text());
Object.keys(elementHandler).forEach(selector => {
const el = doc.querySelector(selector);
if (el) {
elementHandler[selector].map(callback => {
callback(new _Element(el));
});
}
});
return new Response(doc.toString(), response);
};
return {
on,
transform
};
}
Since HTMLRewriter() is called with new, the function needs to be a constructor. In JavaScript, a constructor function should set properties on this and should not return a value. But, your function is written to return a value.
So, try changing this:
return {
on,
transform
};
To this:
this.on = on;
this.transform = transform;
I'm building a CRUD app using electron + vuejs + sequelize, i have used sequelize init and configured the .sequelizerc as below
const path = require('path');
module.exports = {
'config': path.resolve('src/renderer/database/config', 'config.json'),
'models-path': path.resolve('src/renderer/database', 'models'),
'seeders-path': path.resolve('src/renderer/database', 'seeders'),
'migrations-path': path.resolve('src/renderer/database', 'migrations')
}
Now i'm trying to populate a table with data from the database, I've tried to import the models in many ways, always leading to errors.
Error: Uncaught TypeError: Path must be a string. Received undefined
Component:
var models = require('./../../database/models'); // LINE WITH ERROR
export default {
name: "user-index",
data: function() {
return {
users: []
};
},
created: function() {
models.Users.findAll().then(users => {
//
});
},
components: {},
methods: {}
};
Thanks.
EDIT:
I found the problem, it is in the models/index.js:
'use strict';
var fs = require('fs');
var path = require('path');
var Sequelize = require('sequelize');
var basename = path.basename(__filename);
var env = process.env.NODE_ENV || 'development';
var config = require(__dirname + '/../config/config.json')[env];
var db = {};
if (config.use_env_variable) {
var sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
var sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter(file => {
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
})
.forEach(file => {
var model = sequelize['import'](path.join(__dirname, file)); // THIS LINE
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
I fixed by changing path.join to path.resolve and changing this:
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
to
for (var modelName in db) {
if (db[modelName].associate) {
db[modelName].associate(db);
}
}
in models/index.js file.
I can not add new action in Odoo9
openerp.pr_finance = function(instance, local) {
var _t = instance.web._t, _lt = instance.web._lt;
var QWeb = instance.web.qweb;
var Widget = instance.web.Widget;
var core = instance.web.core;
var data = instance.web.data;
var session = instance.web.session;
var utils = instance.web.utils;
var Model = instance.web.Model;
var ControlPanelMixin = instance.web.ControlPanelMixin;
instance.web.ListView.include({
init: function() {
//console.log('JS loaded');
this._super.apply(this, arguments);
},
render_buttons: function(data) {
console.log('JS loaded load_list');
console.log(data);
this._super(data);
if (this.$buttons) {
this.$buttons.find('.oe_my_button').click(this.proxy('do_import_file_csv_ya_tz')) ;
}
},
do_import_file_csv_ya_tz: function () {
console.log('123123123123123123 ooops....');
this.do_action(
{
name: _t("IMPORT MY FILE"),
type: "ir.actions.client",
tag: 'import_csv',
params: {}
}
);
}
});
var import_csv_yandex = Widget.extend({
template: 'ImportViewYaTC',
start: function () {
console.log("ImportViewYandexTC page loaded");
},
});
var DataImport = Widget.extend(ControlPanelMixin, {
template: 'ImportView',
init: function(parent, action) {
console.log("init ImportView");
this._super.apply(this, arguments);
action.display_name = _t('Import a File');
},
start: function () {
console.log("ImportView page loaded");
},
});
console.log("core.action_registry.add");
try {
instance.web.core.action_registry.add('import_csv', DataImport);
} catch (err) {
console.log(err);
}
console.log("core.action_registry.add - OK!");
}
I received error here:
instance.web.core.action_registry.add('import_csv', DataImport);
Error:
TypeError: instance.web.core is undefined Stack trace:
openerp.pr_finance#http//localhost:8069/web/content/2798-e13ba1c/web.assets_backend.js:4579:1276
start_modules#http//localhost:8069/web/content/2798-e13ba1c/web.assets_backend.js:3235:1
.init#http//localhost:8069/web/content/2798-e13ba1c/web.assets_backend.js:3229:3951
OdooClass.extend/Class.include/
Why this variable is undefined?
You need to use require to get the variables of the env: ie.
odoo.define('yourmodulename.pr_finance', function (require) {
"use strict";
var core = require('web.core');
});
a good place to look at to understand inheritance in odoo is the github.com/oca/web repo.
Here's my test
'use strict';
var assert = require('assert');
var sinon = require('sinon');
var proxyquire = require('proxyquire');
var Lab = require('lab');
var lab = exports.lab = Lab.script();
lab.experiment("src.mysql", function () {
var server = {
settings: {
app: {
mysql: {
connectionLimit: 10,
host: "none",
user: "me",
password: "nope",
database: "db"
}
}
},
expose: sinon.stub()
};
var mysql = sinon.stub();
var next = sinon.stub();
var plugin = proxyquire('../../src/mysql', {
mysql: mysql
});
lab.test("successful loads", function(done) {
plugin.register(server, {}, next, function(err) {
assert(err === 'hello');
});
done();
});
});
I'm not getting an error, but the test is passing, which is a false positive. Not sure what I am doing wrong
The latest version of hapi 8.x.x uses a new method for loading plugins, you should call server.register with arguments described here http://hapijs.com/api#serverregisterplugins-options-callback.