bitjson/typescript-starter

How to execute tests for internal methods?

Closed this issue · 3 comments

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [x] question about how to use this project

  • Summary
    It is not clear how would I write and execute tests for methods and classes that are not exposed from the module?

Currently, you need to expose a function from a module to be able to run a test.

  • Other information (e.g. detailed explanation, stack traces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

I am having the same problem. I believe the root cause is that the test files are being move to a test folder. I am looking into perhaps updating the build-tests.js to see if I can get the require-paths to match what they should be.

I believe the other alternative is to move your tests into a more standard layout for typescript (separate folder for tests)

I am not sure this is the ideal solution, but it is at least "a solution";

Change the content of the build-tests.js with the following;

// this script watches the tests exported by typescript, copies them to the test directories, and modifies the require("PKG.NAME") statements to test each build
const cpx = require("cpx");
const separator = require("path").sep;
const Transform = require("stream").Transform;
const pkg = require('../../package');
const req = (path) => 'require("' + path + '")';
const pathUp = (levels) => Array.from(Array(levels), () => '../').join('');

// replace instances of pkg.name with the proper route to the build being tested
const makeTransform = (filePath, buildPath) => {
  const buildPathParts = buildPath.split(separator);
  const filePathParts = filePath.split(separator);
  // filePath includes build/main (-2), test/BUILD is 2 deep (+2),
  // remove filename (-1). Total is length - 2
  const pathToRoot = pathUp(filePath.split(separator).length - 1);
  const placeholder = req(pkg.name);
  return new Transform({
    transform(chunk, encoding, done) {
      const str = chunk.toString();
      const parts = str.split(placeholder)
      const newPath = req(pathToRoot + buildPath)
      const result = parts.join(newPath)
      .replace(/require\(\"\.\.\//g, 'require("' + pathToRoot + filePathParts.slice(0, -2).join(separator) + separator)
      .replace(/require\(\"\.\//g, 'require("' + pathToRoot + filePathParts.slice(0, -1).join(separator) + separator);
      this.push(result);
      done();
    }
  });
}

// copy, then watch for changes to the tests
const testsFromRoot = 'build/main/**/*.spec.js';
const watchMode = process.argv.indexOf('-w') !== -1 ? true : false;
const browserTests = process.argv.indexOf('--no-browser') !== -1 ? true : false;
const task = watchMode ? cpx.watch : cpx.copy;

task(testsFromRoot, 'test/main', {
  transform: (filePath) => makeTransform(filePath, pkg.main)
});
if (!browserTests) {
  task(testsFromRoot, 'test/browser', {
    transform: (filePath) => makeTransform(filePath, pkg.browser.replace('.js', '.cjs.js'))
  });
}

Hey @asmagin and @stephan-nordnes-eriksen – thanks for opening an issue!

The testing infrastructure is significantly simplified in the latest release, and there are now lots of examples of both internal and public APIs being tested. Please take a look and let me know what you think.

I'm going to close this issue now, but please let me know if I should re-open.