Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running in Mozilla Rhino.js - How to load tests into root suite from string? #150

Closed
adam-cyclones opened this issue Jun 27, 2022 · 2 comments

Comments

@adam-cyclones
Copy link

I have an unusual use case that I have struggled with for over a year, I have run Jasmine standalone through babel to support the Rhino.js engine (somewhere between ES5 and ES6 support). This is now parsing just fine and I have access to Jasmine, I can write a custom boot file!

How do I load up a test from string and have it run?

or

How do I create an entire test suite pragmatically
b. do I need to write a parser myself?

const jasmineRequire = require("./build/jasmine");
this.global = this;
const jasmine = jasmineRequire.core(jasmineRequire);
// Object.assign(this.global, jasmineRequire.patch());
this.global.console = jasmineRequire.patch().console;
this.require = jasmineRequire.patch().require;

// !!Patched!! custom fs and path modules powered by java
const fs = require('fs');
const path = require('path');

// TODO: COPY boot0
Object.assign(this.global, jasmine.getGlobal());

global.jasmine = jasmine;

// it, describe and more
const env = jasmine.getEnv();

const jasmineConfigFile = fs.readFileSync(path.resolve('.', 'spec', 'support', 'jasmine.json'));
const jasmineConfigJSON = JSON.parse(jasmineConfigFile);
env.configure(jasmineConfigJSON);

var jasmineInterface = jasmineRequire.interface(jasmine, env);

// custom more like jest
jasmineInterface.test = jasmineInterface.it;

// const Suite = jasmineInterface.jasmine.Suite;

// A test
const x = jasmineInterface.it('does a thing', function () {
    jasmineInterface.expect(true).toBe(false);
});

// ADD TESTS HERE?
env.topSuite().suite_.children.push(Object.assign({
    execute: env.execute.bind(null, false, function (args) { console.log(args) }),
}, x));

env.execute(['spec/a.test.js'], function () {
    console.log("");
    console.log("All tests complete:")
})
    .then(function (doneInfo) {
        console.log(doneInfo);
    });
@sgravrock
Copy link
Member

The only supported way to create specs and suites is by calling the describe and it functions. If you've got specs in a JavaScript file and you want to run them, the way to do that is to load and execute the file after you've created the Env but before you've executed the Env. How you do that depends on the JS runtime you're using. In the browser you'd add a script tag. In Node you'd call require. I don't know what the Rhino equivalent is.

In other words:

  1. Create and boot an Env.
  2. Copy the Jasmine globals (descrbe, it, expect, etc) to the global object so they can be referenced from spec files.
  3. Tell Rhino to load and execute the spec files.
  4. env.execute().

If Rhino doesn't have an equivalent of require, you could use your build process to insert the contents of the spec files before env.execute().

A few other things to be aware of:

  • env.execute() takes an array of spec/suite IDs, not filenames. (For the most part, jasmine-core doesn't have any concept of files.) In most cases you should pass null or undefined as the first parameter to execute().
  • env.execute() isn't reentrant. You can't call it again e.g. from inside suites.
  • Jasmine isn't designed to allow for suites/specs to be mutated via topSuite(). Doing that will corrupt Jasmine's internal state, in ways that could be sublte or catastrophic. Creating your own suite/spec objects and adding them via topSuite() will definitely not work. In general, you're better off sticking to the documented public API.

I hope this helps.

@sgravrock sgravrock closed this as not planned Won't fix, can't repro, duplicate, stale Jul 1, 2022
@adam-cyclones
Copy link
Author

I did get this working but realized that it was better to just use node.js and run each test in its own Rhino process then extract the result by manipulating the code that I ran in the Rhino environment, I wrote a few test utils to introspect the code and return an object containing the value of variables.

Thank you so much for your pointers and I hope this helps future searches!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants