jasmine / jasmine.github.io

Source for Jasmine's documentation
https://jasmine.github.io
MIT License
567 stars 418 forks source link

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

Closed adam-cyclones closed 2 years ago

adam-cyclones commented 2 years ago

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 commented 2 years ago

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:

I hope this helps.

adam-cyclones commented 2 years ago

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!