Skip to content

Instantly share code, notes, and snippets.

@zdennis
Last active March 9, 2017 20:07
Show Gist options
  • Save zdennis/cf2d0cac699e6c9bcebc23fc77699689 to your computer and use it in GitHub Desktop.
Save zdennis/cf2d0cac699e6c9bcebc23fc77699689 to your computer and use it in GitHub Desktop.
New Twiddle
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
clicked(){
const clicked = this.get('clicked');
this.get('model').toggleProperty('completed');
if(clicked) { clicked(); }
}
}
});
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
clicked(){
let listComplete = this.get('list.items').every( item => item.get('completed') );
if(listComplete){
this.set('list.completed', true);
} else {
this.set('list.completed', false);
}
}
}
});
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
todoLists: [
Ember.Object.create({name: 'Personal', items: [
Ember.Object.create({name: 'Pick up groceries', completed: false}),
Ember.Object.create({name: 'Feed the dog', completed: false})
]}),
Ember.Object.create({name: 'Work', items: [
Ember.Object.create({name: 'Call Bob back', completed: false}),
Ember.Object.create({name: 'Schedule team lunch', completed: false})
]})
]
});
test('it marks the list as complete when all todo-list-item components are completed', function(assert) {
this.render(hbs`{{todo-list list=todoList}}`);
let pickupGroceriesItem = this.$(".todo-list-item:contains('☐ Pick up groceries')");
let feedTheDogItem = this.$(".todo-list-item:contains('☐ Feed the dog')");
assert.equal(this.get('todoList.completed'), false, 'The todoList is incomplete since no item has been clicked on to call the +clicked+ action');
// clicking on a todo list item completes it
pickupGroceriesItem.click();
assert.equal(this.get('todoList.completed'), false, 'The todoList is still incomplete since no item has been clicked on to call the +clicked+ action');
// when all items are completed
feedTheDogItem.click();
assert.equal(this.get('todoList.completed'), true, 'The todoList is completed now that the +clicked+ action has been called by clicking on a todo item');
// incomplete the last completed item
feedTheDogItem.click();
assert.equal(this.get('todoList.completed'), false, 'The todoList is no longer complete');
});
test('it uses fake a fake component and template to create a simplified DOM element we can interact with', function(assert) {
// This is the key to this test: stubbing out the component and the view.
this.register('component:todo-list-item', Ember.Component.extend());
this.register(
'template:components/todo-list-item',
hbs`<div class="todo-list-item" {{action clicked}}>{{model.name}}</div>`
);
this.render(hbs`{{todo-list list=todoList}}`);
let pickupGroceriesItem = this.$(".todo-list-item:first");
// when all todo list items are completed, the list is also completed
this.get('todoList.items').forEach( item => item.set('completed', true) );
assert.equal(this.get('todoList.completed'), false, 'The todoList is incomplete since no item has been clicked on to call the +clicked+ action');
pickupGroceriesItem.click();
assert.equal(this.get('todoList.completed'), true, 'The todoList is completed now that the +clicked+ action has been called by clicking on a todo item');
// when not all todo list items are completed, the list becomes marked as incomplete
this.get('todoList.items')[0].set('completed', false);
assert.equal(this.get('todoList.completed'), true, 'The todoList remains complete until the +clicked+ action is called');
pickupGroceriesItem.click();
assert.equal(this.get('todoList.completed'), false, 'The todoList is no longer complete');
});
<h1>Welcome to {{appName}}</h1>
<br>
<br>
{{outlet}}
<br>
<br>
{{#each todoLists as |list| }}
{{todo-list list=list}}
{{/each}}
<div class="todo-list-item" {{action 'clicked'}}>
{{#if model.completed}}✔{{else}}☐{{/if}} {{model.name}}
</div>
<div class="todo-list">
<h2>{{list.name}}</h2>
{{#each list.items as |item|}}
{{todo-list-item model=item clicked=(action 'clicked')}}
{{/each}}
</div>
import Resolver from '../../resolver';
import config from '../../config/environment';
const resolver = Resolver.create();
resolver.namespace = {
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix
};
export default resolver;
import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
moduleForComponent('todo-list', 'Integration | Component | todo list', {
integration: true,
beforeEach(){
this.set('todoList',
Ember.Object.create({completed: false, name: 'Personal', items: Ember.A([
Ember.Object.create({completed: false, name: 'Pick up groceries'}),
Ember.Object.create({completed: false, name: 'Feed the dog'})
])})
);
}
});
// Interacting with the real todo-list-item component shows how this test
// may be written if we tested the entire component stack. But what happens
// when the todo-list-item component has already been tested on its own?
//
// When the todo-list-item component is dead simple it is a small risk, but
// what if it were more complex and required a lot of setup? Or, what if the
// todo-list-item component in several other components? Would we want each
// component to have to set up and exercise the todo-list-item component
// functionality that was already tested in its own component test?
test('it marks the list as complete when all todo-list-item components are completed', function(assert) {
this.render(hbs`{{todo-list list=todoList}}`);
let pickupGroceriesItem = this.$(".todo-list-item:contains('☐ Pick up groceries')");
let feedTheDogItem = this.$(".todo-list-item:contains('☐ Feed the dog')");
assert.equal(this.get('todoList.completed'), false, 'The todoList is incomplete since no item has been clicked on to call the +clicked+ action');
// clicking on a todo list item completes it
pickupGroceriesItem.click();
assert.equal(this.get('todoList.completed'), false, 'The todoList is still incomplete since no item has been clicked on to call the +clicked+ action');
// when all items are completed
feedTheDogItem.click();
assert.equal(this.get('todoList.completed'), true, 'The todoList is completed now that the +clicked+ action has been called by clicking on a todo item');
// incomplete the last completed item
feedTheDogItem.click();
assert.equal(this.get('todoList.completed'), false, 'The todoList is no longer complete');
});
// This test takes a different approach we override the component and template.
// This is so when the todo-list-item component is rendered it the stubbed out
// component defined in this test. If the actual todo-list-item component this
// would be a way to create the simplest possible stubbed out component that
// would allow usto test the behavior of todo-list that we were interested in.
test('it uses fake a fake component and template to create a simplified DOM element we can interact with', function(assert) {
// This is the key to this test: stubbing out the component and the view.
this.register('component:todo-list-item', Ember.Component.extend());
this.register(
'template:components/todo-list-item',
hbs`<div class="todo-list-item" {{action clicked}}>{{model.name}}</div>`
);
this.render(hbs`{{todo-list list=todoList}}`);
let pickupGroceriesItem = this.$(".todo-list-item:first");
// when all todo list items are completed, the list is also completed
this.get('todoList.items').forEach( item => item.set('completed', true) );
assert.equal(this.get('todoList.completed'), false, 'The todoList is incomplete since no item has been clicked on to call the +clicked+ action');
pickupGroceriesItem.click();
assert.equal(this.get('todoList.completed'), true, 'The todoList is completed now that the +clicked+ action has been called by clicking on a todo item');
// when not all todo list items are completed, the list becomes marked as incomplete
this.get('todoList.items')[0].set('completed', false);
assert.equal(this.get('todoList.completed'), true, 'The todoList remains complete until the +clicked+ action is called');
pickupGroceriesItem.click();
assert.equal(this.get('todoList.completed'), false, 'The todoList is no longer complete');
});
import resolver from './helpers/resolver';
import {
setResolver
} from 'ember-qunit';
setResolver(resolver);
{
"version": "0.11.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": true
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.11.0",
"ember-data": "2.11.0",
"ember-template-compiler": "2.11.0",
"ember-testing": "2.11.0"
},
"addons": {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment