How can I use Require.js and Buster.js together? - javascript

I'm trying to get started with Buster.js, and I installed both buster and buster-amd, but even so my use of Require.js is causing problems. My buster.js file looks like this:
var config = module.exports;
config["My tests"] = {
autoRun: false,
environment: "browser", // as opposed to "node"
extensions: [require("buster-amd")],
rootPath: "../",
sources: ['ext/require/require.js'],
tests: ["buster-test/*-test.js"]
};
and my test like this:
define(['buster-test/buster'
], function(buster) {
buster.spec.expose(); // Make some functions global
describe("A Fake Test", function () {
it("can be instantiated", function () {
console.log('test')
});
});
buster.run()
});
But when I try to run the above, I get:
Uncaught exception: ./buster/load-all.js:1 Uncaught ReferenceError: require is not defined
TypeError: uncaughtException listener threw error: Cannot read property 'id' of undefined
at Object.module.exports.uncaughtException (/usr/lib/node_modules/buster/node_modules/buster-test-cli/lib/runners/browser/progress-reporter.js:42:50)
at notifyListener (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/bane/lib/bane.js:49:35)
at Object.object.emit (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/bane/lib/bane.js:127:17)
at Object.module.exports.bane.createEventEmitter.emitCustom (/usr/lib/node_modules/buster/node_modules/buster-test-cli/lib/runners/browser/remote-runner.js:289:14)
at /usr/lib/node_modules/buster/node_modules/buster-test-cli/lib/runners/browser/remote-runner.js:92:16
at PubSubClient.on._handler (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/lib/pubsub-client.js:73:43)
at Object.Faye.Publisher.trigger (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/node_modules/faye/node/faye-node.js:385:19)
at Object.Faye.extend.Set.Faye.Class.distributeMessage (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/node_modules/faye/node/faye-node.js:668:30)
at Object.Faye.Client.Faye.Class._deliverMessage (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/node_modules/faye/node/faye-node.js:1070:20)
at Object.Faye.Client.Faye.Class.receiveMessage (/usr/lib/node_modules/buster/node_modules/buster-test-cli/node_modules/ramp/node_modules/faye/node/faye-node.js:1007:12)
Has anyone seen anything like this before, and if so do you have any suggestions as to what I'm doing wrong?
P.S. If I remove the extensions: line I get a similar error, except that it complains about define instead of require. So it seems like the failure to find require is happening inside the plug-in ... but I have no idea how to provide Require to the plug-in.

Have you tried adding the require.js to libs instead of sources on your buster config? So the config would look like this:
var config = module.exports;
config["My tests"] = {
autoRun: false,
environment: "browser", // as opposed to "node"
libs: [ 'ext/require/require.js' ],
extensions: [require("buster-amd")],
rootPath: "../",
tests: ["buster-test/*-test.js"]
};

I take a different approach. I don't disable autorun, but instead use Buster's async test case format where you define the test case as a function that's passed a run callback. Use the (not well documented) resources: config setting to allow require to load your source code.
config["Browser tests"] = {
environment: "browser",
libs: [ 'test/require_config.js','require.js' ],
rootPath: "../",
resources: ["your_source_code/**/*.js"],
tests: ["buster-test/*-test.js"]
};
Then use require() in your tests, and when you've loaded your code call the run callback with the tests:
buster.testCase("AppCode",function(run) {
require(["appCode"],function(appCode) {
run({
"it works": function() { assert(true) }
})
});
});
I've created an example project showing this method require.js with buster.js. It has a small helper function to do both the testCase and require call simultaneously.

Related

Expo & NextJS - Cannot set property DEFAULT_ICON_COLOR of #<Object> which has only a getter

I am trying to move my React Native Web site using Expo over to Next as well for faster loading/rendering times/SEO.
Unfortunately, when I'm trying to do this, I've come up with a bug I cannot seem to solve and which I haven't been able to find any information on.
Here's what the error looks like:
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info - Loaded env from /Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/.env.local
info - Using webpack 4. Reason: webpack5 flag is set to false in next.config.js https://nextjs.org/docs/messages/webpack5
info - Using external babel configuration from /Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/babel.config.js
Warning: useTransformReactJsxExperimental has been renamed to useTransformReactJSXExperimental (capitalized JSX) in react-native#0.64.0
event - compiled successfully
event - build page: /
wait - compiling...
event - compiled successfully
event - build page: /next/dist/pages/_error
wait - compiling...
event - compiled successfully
TypeError: Cannot set property DEFAULT_ICON_COLOR of #<Object> which has only a getter
at eval (webpack-internal:///./node_modules/#expo/vector-icons/build/vendor/react-native-vector-icons/lib/create-icon-set.js:11:80)
at Module../node_modules/#expo/vector-icons/build/vendor/react-native-vector-icons/lib/create-icon-set.js (/Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/.next/server/pages/_app.js:1069:1)
at __webpack_require__ (/Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/.next/server/pages/_app.js:29:31)
at eval (webpack-internal:///./node_modules/#expo/vector-icons/build/createIconSet.js:39:46)
at Module../node_modules/#expo/vector-icons/build/createIconSet.js (/Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/.next/server/pages/_app.js:640:1)
at __webpack_require__ (/Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/.next/server/pages/_app.js:29:31)
at eval (webpack-internal:///./node_modules/#expo/vector-icons/build/AntDesign.js:10:45)
at Object../node_modules/#expo/vector-icons/build/AntDesign.js (/Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/.next/server/pages/_app.js:460:1)
at __webpack_require__ (/Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/.next/server/pages/_app.js:29:31)
at eval (webpack-internal:///./node_modules/#expo/vector-icons/build/IconsLazy.js:121:41)
at Object../node_modules/#expo/vector-icons/build/IconsLazy.js (/Users/myname/Desktop/Projects/MySite/Frontend/ExpoNextJS/.next/server/pages/_app.js:556:1)
As far as I can tell, this has to be due to my vector icon loading in some form or fashion. But I am using the next-fonts package to manage my fonts, so that should fix this, no?
Here's my next.config.js:
const { withExpo } = require("#expo/next-adapter");
const withFonts = require("next-fonts");
const withImages = require("next-images");
const withPlugins = require("next-compose-plugins");
const withTM = require("next-transpile-modules")(["react-native-web"]);
module.exports = withPlugins(
[withTM, withFonts, withImages, [withExpo, { projectRoot: __dirname }]],
{ webpack5: false }
);
I am on webpack 4, and Next 11.1.0 (because Next 12 isn't compatible with Expo yet)
This is my babel.config.js file:
module.exports = function (api) {
api.cache(true);
return {
presets: [
"#expo/next-adapter/babel",
"next/babel",
"babel-preset-expo",
[
"#babel/preset-env",
{
loose: true,
},
],
],
plugins: [
"#babel/plugin-transform-modules-commonjs",
[
"module-resolver",
{
alias: {
assets: "./assets",
components: "./src/components",
config: "./src/config",
controllers: "./src/controllers",
pages: "./src/pages",
reducers: "./src/redux",
resources: "./src/resources",
revenuecat: "./src/revenuecat",
routing: "./src/routing",
utils: "./src/utils",
root: "./",
},
},
],
],
};
};
As far as I can tell, these are fairly standard implementations, pretty similar to what you see here, and elsewhere on the internet:
https://docs.expo.dev/guides/using-nextjs/
I am at a total loss here, and can't find any information about this particular error with Expo/Next anywhere, so I have no idea where to go next.

How do I correctly configure mocha tests with ts_transformer_keys?

I can't seem to set the custom transformer for ts-transform-keys with my mocha tests.
I’m using mocha 6.1.4
ts-node 8.3.0 https://www.npmjs.com/package/ts-node
ts-trasnformer-keys 0.3.5 https://github.com/kimamula/ts-transformer-keys
ttypescript 1.5.7 https://github.com/cevek/ttypescript
The ts-node documentation says that you cannot set a custom transformer on the CLI, only programatically. So I'm trying to use ttypescript to get around that restriction.
I've tried the following...
Note: test.ts contains the following
import { keys } from 'ts-transformer-keys';
describe("xyz"), () => {
it("123", (done) => {
keys<CustomInterface>();
});
});
Attempt 1) - Set the ts-node with an environment variable
TS_NODE_COMPILER="ttypescript" mocha test/test.ts --require ts-node/register
Then I have the following in test/tsconfig.json
{
"compilerOptions": {
"plugins": [
{ "transform": "ts-transformer-keys/transformer" }
]
}
}
This results in Uncaught TypeError: ts_transformer_keys_1.keys is not a function which indicates that the custom transformer wasn't used at compile time.
Attempt 2) Following the typescript API example from ts-transformer-keys
I added a mocha.opts file with the following
--file test/transformer-config.js
and a transformer-config.js file with the following
const ts = require('typescript');
const keysTransformer = require('ts-transformer-keys/transformer').default;
const program = ts.createProgram(['test/test.ts'], {
strict: true,
noEmitOnError: true,
target: ts.ScriptTarget.ES5
});
const transformers = {
before: [keysTransformer(program)],
after: []
};
const { emitSkipped, diagnostics } = program.emit(undefined, undefined, undefined, false, transformers);
if (emitSkipped) {
throw new Error(diagnostics.map(diagnostic => diagnostic.messageText).join('\n'));
}
Then I invoke it like this mocha test/test.ts --require ts-node/register
This results in the following error
/Users/jjohnson/Documents/OCS/hmp/git/hmp-server/server/test/ttypescript-register.js:17
throw new Error(diagnostics.map(diagnostic => diagnostic.messageText).join('\n'));
^
Error: [object Object]
[object Object]
[object Object]
at Object.<anonymous> (/Users/jjohnson/Documents/OCS/hmp/git/hmp-server/server/test/ttypescript-register.js:17:9)
at Module._compile (internal/modules/cjs/loader.js:777:30)
...
It feels like in Attempt 1 it wasn't ever calling the code that sets the custom transformer in tsconfig.json or if it was getting called the code was failing silently.
It feels like in Attempt 2 I'm creating a new instance of the typescript program and then that fails for some reason. And even if it succeeded I'm not sure that this is the right way to go about configuring things since the ts.createProgram wants a list of RootNames for the files it will transpile.
Maybe my entire approach is wrong.
All I really want is a way that in my mocha tests I can verify that the expected result type is what the method returned. And I'd like to be able to do this w/out touching too much of the source code.
you should be able to define your required module (see below) and run ts-node programmatically. In this way, you can safely use any customer transformer.
// tsnode.js
const transformer = require('ts-transformer-keys/transformer').default;
require("ts-node").register({
transformers: program => ({
before: [
transformer(program)
]
})
});
then you can run mocha with require
mocha --require './tsnode.js' --watch-extensions ts,tsx "test/**/*.{ts,tsx}
You can tell ts-node which compiler to use in tsconfig.json. This is covered in the ts-node docs. If your using transformers presumably your also using ttypescript compiler. You just need to add this:
"ts-node": {
"compiler": "ttypescript"
}

JavaScript Standard Style does not recognize Mocha

I have a Mocha test file that looks like this:
var expect = require('chai').expect
var muting = require('../muting')
describe('muting', function () {
describe('init()', function () {
it('should inject an object into twitter', function () {
var twitter = 'twitter'
muting.init(twitter)
expect(muting.twitter).to.equal(twitter)
})
})
})
When I run mocha from the CLI, it runs the test successfully.
When I run standard (the executable for JavaScript Standard Style) I get errors on Mocha's framework functions like so:
standard: Use JavaScript Standard Style (https://github.com/feross/standard)
c:\..\test\index.js:5:0: 'describe' is not defined.
c:\..\test\index.js:6:2: 'describe' is not defined.
c:\..\test\index.js:7:4: 'it' is not defined.
What's the cleanest way to make Standard not complain about these functions?
I prefer to edit my .eslintrc and add mocha to env section:
...
"env": {
"commonjs": true,
"node": true,
"mocha": true
},
...
this way my package.json file is kept clean, also vscode plugin for eslint understands it better
Actually, you don't need to list every single global variable in your package.json
You can specify environments instead like this:
"standard": {
"env": [ "mocha" ]
}
Source: Official ESLint configuration docs.
while eslint's comment configuration works great for a single file, I prefer to use standard's package.json globals configuration to do this for my projects. E.g.
{
"name": "my-package",
"version": "1.0.0",
"standard": {
"globals": [
"describe",
"context",
"before",
"beforeEach",
"after",
"afterEach",
"it",
"expect"
]
}
}
for eslint use this line on the beginning of test_file.js
/* eslint-env mocha */
You can use the same solution as for web workers
/* global describe it */
var expect = require('chai').expect
var muting = require('../muting')
describe('muting', function () {
describe('init()', function () {
it('should inject an object into twitter', function () {
var twitter = 'twitter'
muting.init(twitter)
expect(muting.twitter).to.equal(twitter)
})
})
})
As pointed out by Nick Tomlin you just need to declare globals.
I use to put it in the command line, since I have different globals for tests as for sources or different parts of the project.
For tests we should use
standard --global describe --global it test/
elsewhere in my project I want to lint code that uses jQuery so I use
standard --global $ src/client/
Bonus tip
If you are using vim with Syntastic you maybe want to add to your .vimrc
let b:syntastic_checkers = ['standard']
let g:syntastic_javascript_standard_args = "--global $ --global it --global describe"

how to access config.paths after it is defined in main.js

Here is my main.js
requirejs.config({
baseUrl: '/js',
paths: {
jquery: 'jquery',
ckeditor: 'ckeditor/ckeditor',
juiAutocomplete: 'jquery-ui-1.10.4.custom',
tags: 'bootstrap-tokenfield',
createPost: 'createPost',
domReady: 'domReady',
test: 'dropUpload'
},
shim: {
createPost: {
deps: ['domReady!']
}
},
deps: ['require'],
callback: function(require) {
'use strice';
var moduleName = location.pathname.replace(/\//g, '-').replace(/^-/, '');
console.log('moduleName is: ' + moduleName);
console.log('yes is: ' + require.config);
}
});
In the callback, I'd like to access the paths which is defined in the requirejs.config() above. If it is possible, how to do it?
My purpose is to see if a module path is defined(exists). If so, then load the module script. If not checked, then a loading error will generate in the console.
Here are the available methods in requirejs by this console command. I can't find a way to access the paths I defined in requirejs.config(). Is this the right direction?
for (var i in requirejs) {console.log(i);}
config
nextTick
version
jsExtRegExp
isBrowser
s
toUrl
undef
defined
specified
onError
createNode
load
exec
undef
There is no public API to get the whole RequireJS configuration from inside a module. You can have a config section in your configuration, which modules may access.
However, the problem you describe trying to solve does not require you to read the configuration. Calling require the normal way will load the module. If the module can't be loaded, it will generate an error on the console. Presumably you also want your code to know whether the loading was successful or not. You can do it with an errback:
require(['foo'], function (foo) {
// Whatever you'd like to do with foo on success.
}, function (err) {
// Whatever you'd like to do on error.
});
If for some reason you must read the config directly then it is located at requirejs.s.contexts.<context name>.config where <context name> is the name of the RequireJS context. The default context is named _ so the configuration for it would be requirejs.s.contexts._.config. However, this is not part of the public API and can change at any time.

why is jasmine-node not picking up my helper script?

This question is likely based in my lack of previous experience with node.js, but I was hoping jasmine-node would just let me run my jasmine specs from the command line.
TestHelper.js:
var helper_func = function() {
console.log("IN HELPER FUNC");
};
my_test.spec.js:
describe ('Example Test', function() {
it ('should use the helper function', function() {
helper_func();
expect(true).toBe(true);
});
});
Those are the only two files in the directory. Then, when I do:
jasmine-node .
I get
ReferenceError: helper_func is not defined
I'm sure the answer to this is easy, but I didn't find any super-simple intros, or anything obvious on github. Any advice or help would be greatly appreciated!
Thanks!
In node, everything is namespaced to it's js file. To make the function callable by other files, change TestHelper.js to look like this:
var helper_func = function() {
console.log("IN HELPER FUNC");
};
// exports is the "magic" variable that other files can read
exports.helper_func = helper_func;
And then change your my_test.spec.js to look like this:
// include the helpers and get a reference to it's exports variable
var helpers = require('./TestHelpers');
describe ('Example Test', function() {
it ('should use the helper function', function() {
helpers.helper_func(); // note the change here too
expect(true).toBe(true);
});
});
and, lastly, I believe jasmine-node . will run every file in the directory sequentially - but you don't need to run the helpers. Instead you could move them to a different directory (and change the ./ in the require() to the correct path), or you could just run jasmine-node *.spec.js.
you do not necessarily need to include your helper script in the spec (testing) file if you have the jasmine config as:
{
"spec_dir": "spec",
"spec_files": [
"**/*[sS]pec.js"
],
"helpers": [
"helpers/**/*.js"
],
"stopSpecOnExpectationFailure": false,
"random": false
}
Everything in the helpers/ folder will run before the Spec files. In the helpers files have something like this to include your function.
beforeAll(function(){
this.helper_func = function() {
console.log("IN HELPER FUNC");
};
});
you will then be able to make references to it in your spec files

Categories

Resources