Code Monkey home page Code Monkey logo

ember-qunit's Introduction

ember-qunit

Latest NPM release CI Build Status

ember-qunit simplifies testing of Ember applications with QUnit by providing QUnit-specific wrappers around the helpers contained in ember-test-helpers.

Requirements

  • Ember.js v4.0 or above
  • Ember Auto Import v2 or above (or Embroider)
  • Node.js v16 or above
  • TypeScript 4.8 and 4.9
  • ember-cli ~v4.8.1, ~v4.12.2, >= v5.1

If you need support for Node 14 please use v6.2 of this addon.

If you need support for Node 13 or older Ember CLI versions please use v4.x of this addon.

Installation

ember-qunit is an Ember CLI addon, so install it as you would any other addon:

$ ember install ember-qunit

Some other addons are detecting the test framework based on the installed addon names and are expecting ember-cli-qunit instead. If you have issues with this then ember install ember-cli-qunit, which should work exactly the same.

Upgrading

For instructions how to upgrade to the latest version, please read our Migration Guide.

Usage

The following section describes the use of ember-qunit with the latest modern Ember testing APIs, as laid out in the RFCs 232 and 268.

For the older APIs have a look at our Legacy Guide.

Setting the Application

Your tests/test-helper.js file should look similar to the following, to correctly setup the application required by @ember/test-helpers:

import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';

setApplication(Application.create(config.APP));

start();

Also make sure that you have set ENV.APP.autoboot = false; for the test environment in your config/environment.js.

Setup Tests

The setupTest() function can be used to setup a unit test for any kind of "module/unit" of your application that can be looked up in a container.

It will setup your test context with:

  • this.owner to interact with Ember's Dependency Injection system
  • this.set(), this.setProperties(), this.get(), and this.getProperties()
  • this.pauseTest() method to allow easy pausing/resuming of tests

For example, the following is a unit test for the SidebarController:

import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';

module('SidebarController', function(hooks) {
  setupTest(hooks);

  // Replace this with your real tests.
  test('exists', function() {
    let controller = this.owner.lookup('controller:sidebar');
    assert.ok(controller);
  });
});

Setup Rendering Tests

The setupRenderingTest() function is specifically designed for tests that render arbitrary templates, including components and helpers.

It will setup your test context the same way as setupTest(), and additionally:

import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';

module('GravatarImageComponent', function(hooks) {
  setupRenderingTest(hooks);

  test('renders', async function() {
    await render(hbs`{{gravatar-image}}`);
    assert.ok(find('img'));
  });
});

Setup Application Tests

The setupApplicationTest() function can be used to run tests that interact with the whole application, so in most cases acceptance tests.

On top of setupTest() it will:

import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { visit, currentURL } from '@ember/test-helpers';

module('basic acceptance test', function(hooks) {
  setupApplicationTest(hooks);

  test('can visit /', async function(assert) {
    await visit('/');
    assert.equal(currentURL(), '/');
  });
});

Configuration

Configuration is optionally managed via @embroider/macros

To configure ember-qunit, in your ember-cli-build.js, add:

'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');

module.exports = function (defaults) {
  const app = new EmberApp(defaults, {
    '@embroider/macros': {
      setConfig: {
        'ember-qunit': {
          /**
           * default: false
           *
           * removes the CSS for the test-container (where the app and components are rendered to)
           */
          disableContainerStyles: true,
          /**
           * default: 'qunit-default'
           * options: 'qunit-default' | 'ember'
           * 
           * Sets the theme for the Web UI of the test runner. Use a different value to disable loading any theme, allowing you to provide your own external one.
           */
          theme: 'qunit-default',
        },
      },
    },
    /* ... */ 
  });

  /* ... */
};

Contributing

Installation

  • git clone <repository-url>
  • cd ember-qunit
  • pnpm install

Running tests

  • pnpm test (Runs ember try:each to test your addon against multiple Ember versions)
  • ember test
  • ember test --server

Running the dummy application

For more information on using ember-cli, visit https://ember-cli.com/.

ember-qunit's People

Contributors

abuiles avatar bantic avatar bertdeblock avatar chancancode avatar chriskrycho avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar dfreeman avatar dgeb avatar ef4 avatar fivetanley avatar fsmanuel avatar gitkrystan avatar ignacemaes avatar ijlee2 avatar kategengler avatar melsumner avatar mydea avatar nullvoxpopuli avatar rohitpaulk avatar rwjblue avatar ryanflorence avatar scalvert avatar simonihmig avatar stefanpenner avatar trentmwillis avatar turbo87 avatar wagenet avatar zzarcon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-qunit's Issues

moduleForComponent and moduleForModel could also accept a delegate function

moduleForComponent, moduleForModel and future moduleForXXX could be used in more contexts, if we allow to pass a delegate function which is executed before the moduleForXXX implementation as it is currently done at moduleFor.

moduleForModel('model1', 'testing model 1', {
    teardown: function() {
        App.reset();
    }
  }, function(container, context, defaultSubject) {
     container.register('adapter:application', DS.RESTAdapter);
});

`moduleForComponent` does not properly destroy the views it created

I believe this is what this TODO comment is about. This just bit me and caused a few hours of pulling hair :)

The scenario I have is that my component attaches a click callback on the body on didInsertElement (to dismiss itself when clicked outside), which is removed in willDestroyElement. Problem is, since the views are not actually destroyed, the willDestroyElement hooks and friends are never fired.

So, a few (completely unrelated) test cases later, I used the click helper somewhere and the whole thing blew up with a Error: Cannot perform operations on a Metamorph that is not in the DOM.. It was an epic WTF moment ๐Ÿ˜…

This might also explain why the tests are leaking memory ๐Ÿ˜‰

refactor moduleForComponent view logic

These three helpers ought to be able to use almost all the same code:

  • moduleForView
  • moduleForComponent
  • moduleForSnippet

(moduleForSnippet would simply render a template string in a container view)

related: #11, #6, #5, #2

Extending test for 3rd party additions

Just a question regarding the intended scope of the project here.

In the future could ember-qunit add support for third party wrappers around QUnit.test?

Result of `this.$(...)` is cached after first call

Hello @stefanpenner.. so I convinced you to merge #54 yesterday.

My expectation (and the reason for the patch) was based on the assumption that this.$ is simply an alias for this.subject().$, which is why I expect to be able to do this.$(selector) to search for stuff inside the component being tested.

I tried using it in my tests today and noticed that things aren't quite right. It turns out that the result of this.$( ... ) is cached after the first call. Therefore, after running this.$('.my-button') in a test, subsequent calls to this.$ (such as this.$(), this.$('.another-button')) will return the same cached jQuery collection, regardless of the arguments you passed in ๐Ÿ’ฃ

Not sure what's the best way to "fix" this. I'm playing around with different ways to do this, but you might have better ideas.

Testing components with {{each}} helper in layout fails

Attempt to test components with {{each item in items itemController='item'}} in layout fails due to missing controller:array registration on isolated container.

Results

Died on test #1 at test (http://localhost:7357/bower_components/ember-qunit/dist/globals/main.js:262:9) at http://localhost:7357/tests/foo.spec.js:3:1: Cannot read property 'create' of undefined
Source: 
TypeError: Cannot read property 'create' of undefined
    at Ember.Handlebars.EachView.Ember.CollectionView.extend.init (http://localhost:7357/bower_components/ember/ember.js:29970:91)
    at superWrapper [as init] (http://localhost:7357/bower_components/ember/ember.js:1292:16)
    at new Class (http://localhost:7357/bower_components/ember/ember.js:12942:15)
    at Function.Mixin.create.create (http://localhost:7357/bower_components/ember/ember.js:13380:12)
    at Ember.View.Ember.CoreView.extend.createChildView (http://localhost:7357/bower_components/ember/ember.js:24483:19)
    at Object.Ember.merge.appendChild (http://localhost:7357/bower_components/ember/ember.js:25009:22)
    at Ember.View.Ember.CoreView.extend.appendChild (http://localhost:7357/bower_components/ember/ember.js:24356:30)
    at EmberHandlebars.ViewHelper.Ember.Object.create.helper (http://localhost:7357/bower_components/ember/ember.js:29376:17)
    at viewHelper (http://localhost:7357/bower_components/ember/ember.js:29554:37)
    at collectionHelper (http://localhost:7357/bower_components/ember/ember.js:29795:40)

Foo component

`import { Component, get, set, computed, observer } from 'ember'`

LAYOUT = Ember.Handlebars.compile """
         {{#each item in items itemController='item'}}
              {{item.value}}
         {{/each}}
   """

FooComponent = 

   layout: computed(-> LAYOUT).readOnly()

   tagName: 'foo'

   items: Ember.A()

`export default Component.extend(FooComponent)`

and foo spec

moduleForComponent('foo-component');

test('component should be created', function() {
  var component = this.subject();
  this.append(component);
  ok(true);
});

noCleanup option

when testing components you usually want to use the thing in the browser as you develop, can't do that when every test wipes it out.

Gotchas

Hi there, I've been using moduleFor() and friends for a couple of months now since Stefan invited me to take a look. I've encountered lots of "gotchas" along the way and implemented workarounds as I've gone.

I think it would be good to have a discussion about these and, where we don't remove the gotcha, document some use cases that address these issues. Here's some examples:

  • stefanpenner/ember-app-kit#465 and #3

  • The isolated container doesn't perform injections - you have to handle these manually

  • Calling model.serialize() on a DS.Model instance fails unless you container.register('serializer:application', DS.JSONSerializer), and all of the transforms (eg. transform:string etc).

  • Using a FixtureStore only in testing is a challenge, the solution we have is:

    // adapters/application.js
    if (Ember.testing) {
      Adapter = DS.FixtureAdapter;
    }
    else {
      Adapter = DS.RESTAdapter.extend({...
    
    // test/helpers.js
    export function fixtureStore(container) {
      container.register('store:main', DS.Store);
      container.register('serializer:application', DS.JSONSerializer);
      container.register('adapter:application', DS.FixtureAdapter);
      container.register('transform:boolean', DS.BooleanTransform);
      container.register('transform:date', DS.DateTransform);
      container.register('transform:number', DS.NumberTransform);
      container.register('transform:string', DS.StringTransform);
      container.injection('route', 'store', 'store:main');
      container.injection('model', 'store', 'store:main');
      return container.lookup('store:main');
    }
    

    Pretty verbose :)

  • The resolver seems doesn't resolve models, so you need to manually resolve them in tests where you need them:

    export function loadCampaignModels(container) {
      var needs = [
        'model:campaign', 'model:agency', 'model:campaign-type', 'model:advertiser',
        'model:brand', 'model:product'
      ];
      resolve(needs, container);
      loadMediaPlanModels(container);
    }
    
    export function loadMediaPlanModels(container) {
      var needs = [
        'model:mediaplan', 'model:lineitem'
      ];
      resolve(needs, container);
    }
    
    export function loadLineItemModels(container) {
      var needs = ['model:property', 'model:market',
        'model:audience', 'model:language',
        'model:targeting', 'model:dealtype'];
      resolve(needs, container);
    }
    
    export function resolve( needs, container ) {
      var resolver = Resolver['default'].create();
      resolver.namespace = {
        modulePrefix: 'mn'
      };
      for (var i = needs.length; i > 0; i--) {
        var fullName = needs[i - 1];
        container.register(fullName, resolver.resolve(fullName));
      }  
    }
    
  • Here's another example from my initial feedback on moduleFor()

I don't know enough about the concerns here, but IMHO I think it'd be good to get the isolatedContainer to inherit from the top-level container (which has the injections and resolver) in some way. I think at the very least the isolatedContainer should have a working resolver and have the same injection rules as the application container. Can we copy these over when we create the isolatedContainer?

Unit + Intergration Test Conflicts

if you do emq.globalize() it clobbers window.test, which I'm willing to bet causes problems.

  • Maybe do unitTest instead of test?
  • Or just be more careful in our clobbering, could probably use module/moduleFor to determine which test function to call.

Also, doing App.setupForTesting probably messes some stuff up to.

moduleForModel transforms

Howdy,

I'm in the process of trying to unit test a model. In my opinion, one of the easiest/best ways of doing this is asserting the results of myModel.toJSON(), since that's what gets sent to the server.

Unfortunately, the test container does not register the ember-data transforms required to actually do this. For example, calling toJSON() results in: Error: Assertion Failed: Unable to find transform for 'string'.

The error is caused when Ember-Data tries to lookup the transform in the container this.transformFor:

      serializeAttribute: function(record, json, key, attribute) {
        var attrs = get(this, 'attrs');
        var value = get(record, key), type = attribute.type;

        if (type) {
          var transform = this.transformFor(type);
          value = transform.serialize(value);
        }

        // if provided, use the mapping provided by `attrs` in
        // the serializer
        key = attrs && attrs[key] || (this.keyForAttribute ? this.keyForAttribute(key) : key);

        json[key] = value;
      }

Is there any easy way for me to import and register these dependencies within my isolated container?

I'd be happy to write some examples in the Wiki once I get this working. I have a feeling it would be very appreciated.

dist/named-amd does not work

Because of the project structure, the module naming does not work.

ember-qunit (main package) cannot find ./isolated-container which is defined at ember-qunit/isolated-container.

Removing relative paths or changing project structure could solve the issue.

moduleFor could accept `callback` as second argument

This function argument contract are closed to the qunit module API.

In much of the cases, developers would write integration tests through qunit module and unit tests with ember-qunit module api, in that case, having the module method to support the same format could originate less errors.

The API could also accept:

moduleFor(fullName, callback, delegate)
moduleFor(fullName, delegate)

Get access to ember store from moduleFor("controller:activity")

I'm trying to get a hold of the store instance to .createRecord('activity', {id: '1_1'}) inside my test, but I can't seem to make it happen. Anyone have any ideas?

I've tried a few different things here

I managed to get a store class, but it's not working as I would like by doing something like..

moduleFor "controller:activity", "Activity Controller"

test "does things", ->
  @container.register "store:main", DS.Store
  store = @container.lookup("store:main")


  Ember.run ->
    activity = store.createRecord('activity', {id: '1_1'})
    ctrl.set 'content', activity


  equal 1,1

but even this doesn't create the activity record as desired.

Testing Strangeness using Ember Qunit and Test Helpers

I have a test that passes and then upon refresh fails with a unhelpful error. If I run the test by itself, it always passes.

I am not sure if this issue falls under Ember-qunit, Ember-cli, EmberJs. This is a boiler plate Ember-cli project, I am running Ember-cli version 0.0.28.

Am I missing something or is this a bug?

This is the error:

screen shot 2014-06-05 at 10 28 35 pm

I know that the code works through manual testing. My Tournament model hasMany('competitor'). I have the appropriate Competitor model.

Also, the screen shot below will show that all of my selectors are correct.

screen shot 2014-06-05 at 10 32 40 pm

This is the integration test:

import { test } from 'ember-qunit';
import startApp from 'scratch-masters/tests/helpers/start-app';

var App;

module('Integration - Competitors Management', {
  setup: function() {
    App = startApp();
  },

  teardown: function() {
    Ember.run(App, App.destroy);
  }
});

var competitorNameInputSelector    = 'input#new-competitor-name',
    addCompetitorButtonSelector    = 'button#add-competitor',
    removeCompetitorButtonSelector = 'button.remove-competitor',
    competitorListSelector         = 'table#competitors-list',
    competitorListItemSelector     = 'table#competitors-list tbody tr';

test('it should have UI for adding and displaying competitors', function() {
  expect(4);

  visit('/tournaments/new');

  andThen(function() {
    shouldHaveElementWithCount(competitorNameInputSelector, 1, null);
    shouldHaveElementWithCount(addCompetitorButtonSelector, 1, null);
    shouldHaveElementWithCount(competitorListSelector, 1, null);
    shouldHaveElementWithCount(competitorListItemSelector, 0, null);
  });
});

test('it should allow competitor adding', function() {
  expect(2);

  visit('/tournaments/new');
  fillIn(competitorNameInputSelector, 'Bob Saget');
  click(addCompetitorButtonSelector);

  andThen(function() {
    shouldHaveElementWithCount(competitorListItemSelector, 1, null);
  });

  fillIn(competitorNameInputSelector, 'Keanu Reeves');
  click(addCompetitorButtonSelector);

  andThen(function() {
    shouldHaveElementWithCount(competitorListItemSelector, 2, null);
  });
});

The main pieces of code that get exercised are the actions in this controller:

var TournamentsNewController = Ember.ObjectController.extend({
  newCompetitorName: '',

  actions: {
    addCompetitor: function() {
      var newCompetitorName = this.get('newCompetitorName'),
          newCompetitor;

      if (newCompetitorName) {
        newCompetitor = this.store.createRecord('competitor', {
          name: newCompetitorName
        });

        this.get('competitors').pushObject(newCompetitor);
        this.set('newCompetitorName', '');
      }
    },

    removeCompetitor: function(competitor) {
      if (competitor) {
        this.get('competitors').removeObject(competitor);
      }
    }
  }
});

export default TournamentsNewController;

setting Ember.testing to true

Currently, ember-qunit sets Ember.testing to true on loading.
This is causing issues in my set-up, where i load ember-qunit and application. If ember-qunit is executed before the application, application initialization throws following assertion.

"You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run"

commenting out Ember.testing=true, solved the issue. I think it is better to allow user to set this by calling setupForTesting() on Application

andThen does not execute after click()

I'm trying to create a set of integration tests for my application that test login functionality. The code in question looks like this:

var App;

module('Login Tests', {
  setup: function() {
    return App = startApp();
  },
  teardown: function() {
    return App.reset();
  }
});

test("successful login", function() {
  expect(1);
  visit('/login');
  fillIn('input.username', 'username');
  fillIn('input.password', 'password');
  click('button');
  andThen(function() {
    equal(currentRouteName(), 'app.index');
  });
});

When this test case executes, the login page is displayed while the username and password are displayed and then the (only) button is clicked to log the user in. When all of this is complete the main page of the app for a logged in user is displayed in qunit's preview window, but qunit is still "running" this test case and the callback of the andThen function call is not called.

I tried everything - chaining the visit() and fillIn() calls (visit(...).fillIn(...).fillIn(...).click(...).then(...)) but the result is always the same - qunit hangs and doesn't return.

What's the bare minimum required to test a ember.object in isolation?

I'm migrating from a pure globals setup and I'm trying to understand what is required in my simple "test helper"

When I look at EAK I see a few additional items (and I just want to confirm they are /are not needed with this new ember-qunit project)

Number 1 on my list (do I need isolatedContainer) ?

window.isolatedContainer = require('ember-qunit/isolated-container')['default'];

Number 2 on my list (to use a custom resolver or not) ?

In the readme is states "if you don't have a custom resolver..."

When should you have a custom resolver? What are the benefits? I see that EAK has a simple resolver like so

import Resolver from 'ember/resolver';

var resolver = Resolver.create();

resolver.namespace = {
  modulePrefix: 'appkit'
};

export default resolver;

Is it preferred to use something like this or follow the readme to the letter?

import Resolver from './path/to/resolver';
import {setResolver} from 'ember-qunit';
setResolver(Resolver.create());

This brings up number 3 on my list ...

Because this has ES6 import statements, should my grunt build transpile all of my tests and dump those into karam/testem ? What if I have some tests/helpers that are not ES6? Will this be an issue?

I'm working on a EAK-lite like blog post series and I have integration testing down w/ something like the following

import Application from 'js/app';
import Router from 'js/router';

function startApp() {
  var App;

  var attributes = {
    rootElement: '#ember-testing',
    LOG_ACTIVE_GENERATION:false,
    LOG_VIEW_LOOKUPS: false
  };

  Router.reopen({
    location: 'none'
  });

  Ember.run(function(){
    App = Application.create(attributes);
    App.setupForTesting();
    App.injectTestHelpers();
  });

  App.reset();

  return App;
}

export default startApp;

(almost identical to what's in EAK now for integration testing)

What I'm having a hard time w/ today is mixing tests that need my startApp and using this ember-qunit project. Thanks for the help (this is literally the final step required to help my team start migrating to ES6)

QUnit start and stop not happening for promises within controller actions.

The section on async example
says that "Under the hood, if you use Ember.RSVP.Promise, ember-qunit will call QUnit's start and stop helpers to stop the test from tearing down and running other tests while your asynchronous code runs. ember-qunit also asserts that the promise gets fulfilled."

This appears to happen in the general case, but not when an Ember.Controller is being tested,
and action is sent to it:

var ctrl = this.subject();
ctrl.send('myAction'); //promises created here do not result in QUnit's start and stop helpers being called.

This can be inferred from an error that occurs in subsequent, unrelated, tests in other test modules, saying "Uncaught Error: Assertion Failed: calling set on destroyed object"

Code example

loading with require.js

This is not a bug. But wanted help in using this library. When i load "ember-qunit/dist/amd/main" using config.json of require, it is failing to load dependencies like "isolated-container", "module-for" and other module. Those modules are there as in the git-hub, but failing to load them.
Do you know how to fix this issue?
One difference i noticed compare to other modules,
all other modules i am loading contains a function. But the main module of ember-qunit contains define function.
what could be the problem?
Thanks for your help in advance. Any help is very much appreciated.

moduleForComponent and callbacks not working?

import { test , moduleForComponent } from 'ember-qunit';

moduleForComponent('dashboard-time-controls', 'Dashboard Time Controls - Refresh Interval Tests', {
    needs: ['component:radio-button']
});

i've tried all sorts of syntax variations.. but nothing seems to work.
both pieces of js source code live in
app/components/dashboard-time-controls.js
app/components/radio-button.js

app/templates/dashboard-time-controls.hbs is what is trying to use radio-button.

when I run localhost:8000/tests I get:

Error: <(subclass of Ember.Component):ember1720> Handlebars error: Could not find property 'radio-button' on object <(subclass of Ember.Component):ember1720>.
    at new Error (native)
    at Error.Ember.Error (http://localhost:8000/vendor/ember/ember.js:910:19)
    at null.<anonymous> (http://localhost:8000/vendor/ember/ember.js:27485:9)
    at Object.eval (eval at <anonymous> (http://localhost:8000/vendor/handlebars/handlebars.js:1945:25), <anonymous>:54:259)
    at http://localhost:8000/vendor/handlebars/handlebars.js:436:33
    at Ember.View.Ember.CoreView.extend.render (http://localhost:8000/vendor/ember/ember.js:23553:16)
    at Ember.CoreView.Ember.Object.extend._renderToBuffer (http://localhost:8000/vendor/ember/ember.js:22491:10)
    at superFunction [as _super] (http://localhost:8000/vendor/ember/ember.js:7723:16)
    at Ember.View.Ember.CoreView.extend._renderToBuffer (http://localhost:8000/vendor/ember/ember.js:24161:23)
    at superWrapper [as _renderToBuffer] (http://localhost:8000/vendor/ember/ember.js:1292:16)

moduleFor not allowing Adapter to use its Serializer.

I want to load some mocks into a model test, because I have some pretty complicated relationships that I want to test computed properties for.

I've been fiddling with various ways of doing this for about three days now, and I found a method that feels very close, and yet it fails in a very miserable way, failure to serialize.

I've basically subclassed moduleForModel, overriding its DS.FixtureAdapter assignment to an adapter I included in the needs array. This has worked so well that when I open the /tests route in my browser I'm able to hit my ember-cli mock server and retrieve great mock data from there.

However, once my RestAdapter subclass gets its response, it uses a fresh DS.JSONSerializer, instead of my own RESTSerializer subclass.

I've included 'serializer:application' in my needs array, and I've confirmed that calling container.lookup('serializer:application') returns the serializer I want. I've even then assigned this to the RestAdapter.defaultSerializer property, and even done that in a test, right before making a request, but every time, the result is the same:

Upon receiving the response, the store only has a default JSONSerializer, and it fails to serialize because it lacks my custom logic.

What is happening to my serializer? How can I preserve it?

Looking through the stack, it seems like the problem is in my store's adapterFor(type) method when it's called within the fetchAll() function. This adapterFor function calls this.container to lookup the adapters, and it's this container that doesn't have any real references that I loaded.

Is the store loaded with a dummy container? And if so, how do I give it a real container?

You cannot use the same root element (body)

Using karma I always get this error:

Setup failed on Works as link when popups disabled: Assertion Failed: You cannot use the same root element (body) multiple times in an Ember.Application

I don't know exactly but seems like that's because karma do run many tests in the same time. So module setup() maybe called twise before module teardown() gets called.

Tricky to use moduleForComponent for components with sub-components

If you want to test a component that uses subcomponents, you have to know to do a special needs incantation to include both the template and the component. Here's an example from Skylight:

moduleForComponent("billing-trial-status", "billing-trial-status component", {
  needs: [
    'component:calendar-date',
    'template:components/calendar-date',
    'helper:format-date'
  ]
});

I'm opposed exposing the container key like this anyway, but having to know how components are represented internally is definitely too much to ask new users, IMO. I'd like to see some sugar for specifying subcomponents that are required.

Tests fail with `MODEL_FACTORY_INJECTIONS = true`

Summary

See repo dustinfarris/bar (generated with ember-cli) with two models, a belongsTo relationship and unit test. All tests pass.

Set Ember.MODEL_FACTORY_INJECTIONS = true in app.js, and the tests fail.

Output

From npm test:

not ok 15 PhantomJS 1.9 - Pet Model: A Pet belongs to a Person

/Users/dustin/Forks/ember-cli/node_modules/testem/lib/strutils.js:10
  return text.split('\n').map(function(line){
              ^
TypeError: Object  has no method 'split'
    at Object.indent (/Users/dustin/Forks/ember-cli/node_modules/testem/lib/strutils.js:10:15)
    at /Users/dustin/Forks/ember-cli/node_modules/testem/lib/ci/test_reporters/tap_reporter.js:28:41
    at Array.map (native)
    at Object.TapReporter.errorDisplay (/Users/dustin/Forks/ember-cli/node_modules/testem/lib/ci/test_reporters/tap_reporter.js:27:8)
    at Object.TapReporter.display (/Users/dustin/Forks/ember-cli/node_modules/testem/lib/ci/test_reporters/tap_reporter.js:58:27)
    at Object.TapReporter.report (/Users/dustin/Forks/ember-cli/node_modules/testem/lib/ci/test_reporters/tap_reporter.js:18:10)
    at Object.BrowserTestRunner.onTestResult (/Users/dustin/Forks/ember-cli/node_modules/testem/lib/ci/browser_test_runner.js:35:19)
    at Socket.EventEmitter.emit [as $emit] (events.js:95:17)
    at SocketNamespace.handlePacket (/Users/dustin/Forks/ember-cli/node_modules/testem/node_modules/socket.io/lib/namespace.js:335:22)
    at Manager.onClientMessage (/Users/dustin/Forks/ember-cli/node_modules/testem/node_modules/socket.io/lib/manager.js:488:38)
    at WebSocket.Transport.onMessage (/Users/dustin/Forks/ember-cli/node_modules/testem/node_modules/socket.io/lib/transport.js:387:20)
    at Parser.<anonymous> (/Users/dustin/Forks/ember-cli/node_modules/testem/node_modules/socket.io/lib/transports/websocket/default.js:36:10)
    at Parser.EventEmitter.emit (events.js:95:17)
    at Parser.parse (/Users/dustin/Forks/ember-cli/node_modules/testem/node_modules/socket.io/lib/transports/websocket/default.js:343:12)
    at Parser.add (/Users/dustin/Forks/ember-cli/node_modules/testem/node_modules/socket.io/lib/transports/websocket/default.js:315:8)
    at Socket.<anonymous> (/Users/dustin/Forks/ember-cli/node_modules/testem/node_modules/socket.io/lib/transports/websocket/default.js:169:17)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at Socket.Readable.push (_stream_readable.js:127:10)
    at TCP.onread (net.js:528:21)
npm ERR! Test failed.  See above for more details.
npm ERR! not ok code 0

From localhost:4200/tests/:

Pet Model: A Pet belongs to a Person (1, 0, 1)
failed
Expected:   
[
  {
    "kind": "belongsTo",
    "name": "owner"
  }
]
Result:     
[]
Diff:   
[
  {
    "kind": "belongsTo",
    "name": "owner"
  }
] [] 
Source:     
    at Object.eval (bar/tests/unit/pet-test.js:23:31)
    at Object.wrapper (vendor/ember-qunit/dist/named-amd/main.js:266:31)
    at Object.Test.run (http://localhost:4200/assets/qunit.js:203:18)
    at http://localhost:4200/assets/qunit.js:361:10
    at process (http://localhost:4200/assets/qunit.js:1453:24)
    at http://localhost:4200/assets/qunit.js:479:5

To reproduce

  • Using ember-cli master create new project "bar"
  • Add two models, "bar/models/person" and "bar/models/pet"
  • Create a belongsTo relationship from pet to person
  • Create a unit test testing the relationship
  • import startApp somewhere before the test runs (required to run app.js and thus set MODEL_FACTORY_INJECTIONS)
  • Set (or leave) Ember.MODEL_FACTORY_INJECTIONS = true in app.js

Calling save on models

I'm happily using moduleForModel helper. But then to be able to call .save() on the record it returns you need to attach a "new" store to it like so

var flight = this.subject();
flight.set('store', App.__container__.lookup('store:main'));

Which is a bit ugly and flight record already contains its store. If I don't "re-attach" store like this I'll get the error when calling .save on the record

: store.serializerFor(...) is undefined
Source:
FixtureAdapter<.mockJSON@http://localhost:4001/vendor/ember-data/ember-data.js:722:9
FixtureAdapter<.createRecord@http://localhost:4001/vendor/ember-data/ember-data.js:833:1
_commit@http://localhost:4001/vendor/ember-data/ember-data.js:10423:1
Store<.flushPendingSave/<@http://localhost:4001/vendor/ember-data/ember-data.js:9659:11
utils.forEach@http://localhost:4001/vendor/ember/ember.js:2750:9
Store<.flushPendingSave@http://localhost:4001/vendor/ember-data/ember-data.js:9660:1
DeferredActionQueues.prototype.flush@http://localhost:4001/vendor/ember/ember.js:8175:17
Backburner.prototype.end@http://localhost:4001/vendor/ember/ember.js:8263:11
Backburner.prototype.run@http://localhost:4001/vendor/ember/ember.js:8302:13
apply@http://localhost:4001/vendor/ember/ember.js:7952:18
run@http://localhost:4001/vendor/ember/ember.js:6598:9
@http://localhost:4001/build/test/unit.js:37:7
wrapper@http://localhost:4001/vendor/ember-qunit/dist/globals/main.js:245:1
Test.prototype.run@http://localhost:4001/vendor/qunit/qunit/qunit.js:1303:4
run/<@http://localhost:4001/vendor/qunit/qunit/qunit.js:1463:5
process@http://localhost:4001/vendor/qunit/qunit/qunit.js:1016:4
QUnit.start/<@http://localhost:4001/vendor/qunit/qunit/qunit.js:186:5

I tried to fix the problem myself but I lack knowledge and couldn't figure it out just yet. Or am I doing something completely wrong for the kind of testing ember-qunit wants to provide?

Needs a README

Not sure how to use it what it does ๐Ÿ˜‰, could use a README.md.

Problems with moduleForComponent and testing div ID

I was having problems with testing ember components until I didn't renamed the testing ember app div element's id to ember-testing and set App.rootElement = '#ember-testing' as well.

I looked through the source code and found that moduleForComponent have hardcoded #ember-testing` in it's setup and the container view. I wouldn't change the way it's done right now, but I would at least add some info about it into the readme, so that next me, won't having issues with that.

I know same setup is also used in new ember testing guides and this setup info isn't provided as well. Would it be all right if I just add one step into examples section and describe that you need those two things to be set up as such?

Unit testing models with associations/relationships fail

[ This refers to v0.1.7 ]

When unit testing a model that makes use of DS.belongsTo() the createRecord() fails with the following error:

Error: No model was found for 'Client'

It appears that in order to create a record of a model, it expects its associated or related model to already exist. What's going on?


Here are the models and test

/app/models/client.js:

export default DS.Model.extend({
  name: DS.attr('string'),
  invoices: DS.hasMany('Invoice'),
});

/app/models/invoice.js:

export default DS.Model.extend({
  amount: DS.attr('number'),
  discountTotal: DS.attr('number'),

  totalAmount: function() {
    return this.get('amount') - this.get('discountTotal');
  }.property('amount', 'discountTotal'),

  client: DS.belongsTo('Client'),
});

tests/models/invoice.js:

import { test, moduleForModel } from 'ember-qunit';

moduleForModel('invoice', 'Invoice Model');

test('totalAmount computed property considers discounts', function() {
  // this.subject() is aliased more or less to createRecord() for the
  // invoice model. See module-for-model.js in ember-qunit.
  //
  // Attempting to run the below function throws the error.
  var invoice = this.subject({
    id: 1,
    amount: 50.0
    discountTotal: 10.0
  });

  equal(invoice.get('totalAmount'), 40.0);
});

README?

At least list the helpers :P

testing components that use other components

Testing a component that is dependent on another component fails when the dependent component uses a template instead of having the layout defined on the component.

I altered the jsbin example from the emberjs guides to show this.

Working example with template defined in the component as layout

Not working example where I moved the layout to a separate template

How to tell QUnit to execute tests wrapped in AMD definition ?

I closed the issue I opened earlier because it all boils down to this 1 issue

With karma/testem/qunit in browser - how do I force the test runner to execute a transpiled amd module? My test is very simple (including a simple import for my person model in this example), but karma never executes the specs inside the module.

Any help would be really appreciated

define("js/tests/unit/unit_tests", 
  ["js/models/person"],
  function(__dependency1__) {
    "use strict";
    var Person = __dependency1__["default"];

    test('selects first tab and shows the panel', function() {
      expect(1);
      equal(1, 1);
    });
  });

Contributing steps do not work

Wanted to write a quick patch, but couldn't get this thing booted up. I followed the new steps and get this stack trace...

$ broccoli serve

/usr/local/lib/node_modules/broccoli-cli/node_modules/resolve/lib/sync.js:32
    throw new Error("Cannot find module '" + x + "' from '" + y + "'");
          ^
Error: Cannot find module 'broccoli' from '/Users/tonycoco/Development/javascript/ember-qunit'
    at Function.module.exports [as sync] (/usr/local/lib/node_modules/broccoli-cli/node_modules/resolve/lib/sync.js:32:11)
    at Object.<anonymous> (/usr/local/lib/node_modules/broccoli-cli/bin/broccoli:7:28)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.