Skip to content

How do I resolve dependencies of 3rd party libs for testing? #1125

Closed
@NullVoxPopuli

Description

@NullVoxPopuli

Env Info

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 15.10
Release:    15.10
Codename:   wily
$ ng --version
Could not start watchman; falling back to NodeWatcher for file system events.
Visit http://ember-cli.com/user-guide/#watchman for more info.
angular-cli: 1.0.0-beta.5
node: 5.10.1
os: linux x64

Steps

  • Create angular-cli app.
  • Use JSData for a data layer, cause production apps are complex, and need a data layer.
  • Try to use xhr-interceptor to mock json returned from the server because JSData doesn't use @angular/http, but uses axios for async http. An example of how this is done can be seen with ember-cli-mirage. Previously, I tried pretender, but had similar problems with nested dependencies.
  • run ng test
  • get errors similar to Uncaught error: Could not find module 'methods' from 'path/to/xhr-interceptor/index.js'

All I want to do is mock JSON responses from a fake server (one that isn't actually running, but is just scoped to an individual test).

Here are some relevant configuration things I've done:

// config/karma.conf.js
module.exports = function (config) {
  config.set({
    basePath: '../',
    frameworks: ['jasmine', 'commonjs'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-spec-reporter'),
      require('karma-coverage'),
      require('karma-commonjs'),
    ],
    customLaunchers: {
      // chrome setup for travis CI using chromium
      Chrome_travis_ci: {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    },
    files: [
      { pattern: 'dist/vendor/es6-shim/es6-shim.js', included: true, watched: false },
      { pattern: 'dist/vendor/zone.js/dist/zone.js', included: true, watched: false },
      { pattern: 'dist/vendor/reflect-metadata/Reflect.js', included: true, watched: false },
      { pattern: 'dist/vendor/systemjs/dist/system-polyfills.js', included: true, watched: false },
      { pattern: 'dist/vendor/systemjs/dist/system.src.js', included: true, watched: false },
      { pattern: 'dist/vendor/zone.js/dist/async-test.js', included: true, watched: false },
      { pattern: 'dist/vendor/xhr-interceptor/**/*', served: true, watched: false },
      { pattern: 'dist/vendor/methods/**/*', served: true, watched: false },
      'dist/vendor/methods/index.js',
      'dist/vendor/http-browserify/index.js',
      { pattern: 'config/karma-test-shim.js', included: true, watched: true },
      // Distribution folder.
      { pattern: 'dist/**/*', included: false, watched: true }
    ],
    exclude: [
      // Vendor packages might include spec files. We don't want to use those.
      'dist/vendor/**/*.spec.js'
    ],
    preprocessors: {
      'dist/vendor/http-browserify/**/*.js': ['commonjs'],
      'dist/vendor/methods/**/*.js': ['commonjs'],
      'dist/vendor/xhr-interceptor/**/*.js': ['commonjs'],
      'dist/app/**/*.js': 'coverage',
    },
    reporters: [
      'spec',
      // 'coverage'
    ],
    coverageReporter: {
      type : 'html',
      dir : 'coverage/'
    },
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false
  });
};
// src/system-config.ts
/***********************************************************************************************
 * User Configuration.
 **********************************************************************************************/
/** Map relative paths to URLs. */
const map: any = {
  '@portal': '../src/app',
  'js-data': 'vendor/js-data',
  'js-data-http': 'vendor/js-data-http',
  'js-data-jsonapi': 'vendor/js-data-jsonapi',
  'traceur': 'vendor/traceur',

  // for testing
  'xhrinterceptor': 'vendor/xhr-interceptor',
  'methods': 'vendor/methods',
  'http': 'vendor/http-browserify',
};

const paths: any = {

}

/** User packages configuration. */
const packages: any = {
  'js-data': {
    main: 'dist/js-data.min.js'
  },
  'js-data-http': {
    main: 'dist/js-data-http.min.js'
  },
  'js-data-jsonapi': {
    main: 'dist/js-data-jsonapi.js'
  },
  'traceur': {
    main: 'bin/traceur.js'
  },
  'xhrinterceptor': {
    format: 'cjs',
    defaultExtension: 'js',
    main: 'index.js'
  },
  'methods': {
    format: 'cjs',
    defaultExtension: 'js',
    main: 'index.js'
  },
  'http': {
    format: 'cjs',
    defaultExtension: 'js',
    main: 'index.js'
  }

};

////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************************
 * Everything underneath this line is managed by the CLI.
 **********************************************************************************************/
const barrels: string[] = [
  // Angular specific barrels.
  '@angular/core',
  '@angular/common',
  '@angular/compiler',
  '@angular/http',
  '@angular/router',
  '@angular/platform-browser',
  '@angular/platform-browser-dynamic',


  // Thirdparty barrels.
  'rxjs',
  'xhr-interceptor',
  'xhrinterceptor',

  // App specific barrels.
  'app',
  'app/shared'
  /** @cli-barrel */
];

const cliSystemConfigPackages: any = {};
barrels.forEach((barrelName: string) => {
  cliSystemConfigPackages[barrelName] = { main: 'index' };
});

/** Type declaration for ambient System. */
declare var System: any;

// Apply the CLI SystemJS configuration.
System.config({
  map: {
    '@angular': 'vendor/@angular',
    'rxjs': 'vendor/rxjs',
    'main': 'main.js',
    'xhrinterceptor': 'vendor/xhr-interceptor'
  },
  packages: cliSystemConfigPackages
});

// Apply the user's configuration.
System.config({ map, packages });
// angular-cli-build.js
/* global require, module */

var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
var renderTemplates = require("broccoli-render-template");

module.exports = function(defaults) {
  var app = new Angular2App(defaults, {
    // these all get copied to dist/vendor
    vendorNpmFiles: [
      'systemjs/dist/system-polyfills.+(js|js.map)',
      'systemjs/dist/system.src.js',
      'zone.js/dist/**/*.+(js|js.map)',
      'es6-shim/es6-shim.js',
      'reflect-metadata/**/*.+(js|js.map)',
      'rxjs/**/*.+(js|js.map)',
      '@angular/**/*.+(js|js.map)',
      'js-data/**/*.+(js|js.map)',
      'js-data-http/**/*.+(js|js.map)',
      'js-data-jsonapi/**/*.js',
      'traceur/**/*.js',

      // for testing...
      'xhr-interceptor/**/*.js',
      'methods/**/*.js',
      'http-browserify/**/*.js',
    ],
  });

  // // Render all of the jade we have available
  var renderedJadeTree  = renderTemplates(app, { pretty:true });
  return renderedJadeTree;
};
// src/typings.d.ts
/// <reference path="../typings/browser.d.ts" />
declare var module: { id: string };
declare function require(id: string): any;
declare module 'xhrinterceptor' {
  //var Interceptor: any;
  export class Interceptor{
  }
}
// src/app/data/store.spec.ts
import { it, describe, expect } from '@angular/core/testing';
import { store, basePath } from './store';
import { Interceptor } from 'xhrinterceptor';

describe('JSData: Adaptor Configuration', () => {
  let interceptor;

  beforeEach(() => {
    // debugger;
    interceptor = new Interceptor;
  });
  ...

screenshot of dist/
image

So, things are getting copied to dist/vendor, but because dist/vendor/xhr-interceptor has some requirements of things that aren't in its node_module's directory, require is barfing.

Any ideas?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions