javascriptmeteormeteor-velocitymeteor-packages

Why does using Mongo in package tests fail when the package has api.use('mongo')?


I'm developing a custom package. Its package.js is :

Package.describe({
  name: 'adigiovanni:one-way-accounts',
  version: '0.0.1',
  summary: 'One Way Accounts',
  git: '',
  documentation: 'README.md',
});

Package.onUse(function (api) {
  api.versionsFrom('1.2.0.2');
  api.use('ecmascript');
  api.use('mongo');
  // api.imply('mongo');
  api.addFiles([
    'lib/collections/Accounts.js',
    'lib/methods.js',
    'lib/OneWayAccounts.js',
  ]);
  api.export('OneWayAccounts');
});

Package.onTest(function (api) {
  api.use([
    'ecmascript',
    'sanjo:jasmine@0.20.2',
    'velocity:html-reporter',
  ]);
  api.use('adigiovanni:one-way-accounts');
  api.addFiles('tests/client/OneWayAccounts.js', 'client');
  api.addFiles('tests/server/OneWayAccounts.js', 'server');
});

As you can see, package makes use of 'mongo'.

Tests fail with :

Reference error: Mongo is not defined

But if I uncomment the line api.imply('mongo') then tests succeed.

Same odd behavior applies to ecmascript dependency, if I don't api.use('ecmascript') in Package.onTest, tests fail.

Meteor version is 1.2.0.2.
Test runner is velocity.
Test framework is jasmine.
I am using Mongo and ES6 syntax and features in my tests.

What is happening and how can I fix it?


Solution

  • Using a package with api.use('other-package') in Package.onUse does not make 'other-package' available in your test codes in the same way it doesn't make it available for other packages that use('my-package') or in applications that meteor add my-package. To solve this issue there is two solutions depending on the need for other-package :

    1. Allowing users of the package (including your tests) to access 'other-package' with api.imply

      Package.onUse(function (api) {
        //...
        api.imply('other-package')
        //...
      })
      

      This makes sense if and only if the package you imply is necessary to use your own package. Do not imply everything willy-nilly for scope convenience. See more in this question.
      If it does not fall into that category,

    2. Simply use the package in your tests

      Package.onTest(function (api) {
        //...
        api.use('my-package')
        api.use('other-package')
        //...
      })
      

      This will allow you to use other-package in your tests too, without polluting scopes.