Skip to content

Commit

Permalink
Expose addAtom action. Refactor tests for greater clarity
Browse files Browse the repository at this point in the history
Do not try/catch destroying the editor

Change usage of var to let.
  • Loading branch information
bantic committed Apr 19, 2016
1 parent f553a4d commit edbb8fe
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 97 deletions.
23 changes: 20 additions & 3 deletions addon/components/mobiledoc-editor/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ export default Component.extend({
this._addCard(cardName, payload);
},

addAtom(atomName, text='', payload={}) {
this._addAtom(atomName, text, payload);
},

addCardInEditMode(cardName, payload={}) {
let editMode = true;
this._addCard(cardName, payload, editMode);
Expand Down Expand Up @@ -264,9 +268,7 @@ export default Component.extend({

willDestroyElement() {
let editor = this.get('editor');
try {
editor.destroy();
} catch(e) {}
editor.destroy();
},

postDidChange(editor) {
Expand Down Expand Up @@ -298,6 +300,21 @@ export default Component.extend({
this.sendAction(DID_CREATE_EDITOR_ACTION, editor);
},

_addAtom(atomName, text, payload) {
let editor = this.get('editor');
if (!editor.hasCursor()) { return; }

let { range } = editor;
editor.run(postEditor => {
let atom = editor.builder.createAtom(atomName, text, payload);
let position = editor.range.head;
if (!range.isCollapsed) {
position = postEditor.deleteRange(range);
}
postEditor.insertMarkers(position, [atom]);
});
},

_addCard(cardName, payload, editMode=false) {
let editor = this.get('editor');
let section = editor.activeSection;
Expand Down
3 changes: 2 additions & 1 deletion addon/components/mobiledoc-editor/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
toggleMarkup=(action 'toggleMarkup')
toggleLink=(action 'toggleLink')
addCard=(action 'addCard')
addAtom=(action 'addAtom')
addCardInEditMode=(action 'addCardInEditMode')
toggleSection=(action 'toggleSection')
createListSection=(action 'createListSection')
Expand All @@ -25,7 +26,7 @@
{{#each componentCards as |card|}}
{{#ember-wormhole to=card.destinationElementId}}
{{! LEGACY: Payload is passed as the legacy "data" attr below. This
should be removed before 1.0 }}
is deprecated and should be removed before 1.0 }}
{{component card.cardName
editor=editor
postModel=card.postModel
Expand Down
2 changes: 1 addition & 1 deletion tests/helpers/resolver.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Resolver from 'ember/resolver';
import config from '../../config/environment';

var resolver = Resolver.create();
let resolver = Resolver.create();

resolver.namespace = {
modulePrefix: config.modulePrefix,
Expand Down
4 changes: 2 additions & 2 deletions tests/helpers/start-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import Application from '../../app';
import config from '../../config/environment';

export default function startApp(attrs) {
var application;
let application;

var attributes = Ember.merge({}, config.APP);
let attributes = Ember.merge({}, config.APP);
attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;

Ember.run(function() {
Expand Down
174 changes: 90 additions & 84 deletions tests/integration/components/mobiledoc-editor/component-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,30 @@ import {
simpleMobileDoc, linkMobileDoc, mobiledocWithCard
} from '../../../helpers/create-mobiledoc';

const COMPONENT_CARD_EXPECTED_PROPS = ['env', 'editCard', 'saveCard', 'cancelCard', 'removeCard'];
let { Component } = Ember;

const COMPONENT_CARD_EXPECTED_PROPS = ['env', 'editCard', 'saveCard', 'cancelCard', 'removeCard', 'postModel'];

moduleForComponent('mobiledoc-editor', 'Integration | Component | mobiledoc editor', {
integration: true
integration: true,
beforeEach() {
this.registerAtomComponent = (atomName, template, componentClass=Component.extend({tagName: 'span'})) => {
this.registry.register(`component:${atomName}`, componentClass);
this.registry.register(`template:components/${atomName}`, template);
return createComponentAtom(atomName);
};
this.registerCardComponent = (cardName, template, componentClass=Component.extend()) => {
this.registry.register(`component:${cardName}`, componentClass);
this.registry.register(`template:components/${cardName}`, template);
return createComponentCard(cardName);
};
this.registerCardComponentWithEditor = (cardName, template, componentClass, editorTemplate, editorClass=Component.extend()) => {
let card = this.registerCardComponent(cardName, template, componentClass);
this.registry.register(`component:${cardName}-editor`, editorClass);
this.registry.register(`template:components/${cardName}-editor`, editorTemplate);
return card;
};
}
});

test('it boots the mobiledoc editor', function(assert) {
Expand Down Expand Up @@ -115,16 +135,13 @@ test('wraps component-card adding in runloop correctly', function(assert) {

this.set('mobiledoc', mobiledoc);
this.on('didCreateEditor', (_editor) => editor = _editor);
this.registry.register('template:components/demo-card', hbs`
let card = this.registerCardComponent('demo-card', hbs`
<div id="demo-card">demo-card</div>
`);
this.set('cards', [createComponentCard('demo-card')]);
this.set('mobiledoc', simpleMobileDoc(''));
`);
this.set('cards', [card]);
this.set('mobiledoc', simpleMobileDoc());
this.render(hbs`
{{#mobiledoc-editor
did-create-editor=(action "didCreateEditor")
mobiledoc=mobiledoc
cards=cards as |editor|}}
{{#mobiledoc-editor did-create-editor=(action 'didCreateEditor') mobiledoc=mobiledoc cards=cards as |editor|}}
{{/mobiledoc-editor}}
`);

Expand Down Expand Up @@ -412,36 +429,16 @@ test('it adds a component in display mode to the mobiledoc editor', function(ass
assert.ok(this.$(`#demo-card-editor`).length, 'Card changed to edit mode');
});

test('exposes the `postModel` on the card component', function(assert) {
assert.expect(2);
this.registry.register('component:demo-card', Ember.Component.extend({
init() {
this._super(...arguments);
assert.ok(!!this.get('postModel'), 'card is passed postModel');
}
}));
this.registry.register('template:components/demo-card',
hbs`<div id="demo-card"></div>`);
this.set('cards', [createComponentCard('demo-card')]);
this.render(hbs`
{{#mobiledoc-editor cards=cards as |editor|}}
<button id='add-card' {{action editor.addCard 'demo-card'}}></button>
{{/mobiledoc-editor}}
`);

this.$('button#add-card').click();
assert.ok(this.$(`#demo-card`).length, 'Card added in display mode');
});

test('it adds a card and removes an active blank section', function(assert) {
assert.expect(4);

this.registry.register('template:components/demo-card', hbs`
let editor;
let card = this.registerCardComponent('demo-card', hbs`
<div id="demo-card"><button id='edit-card' {{action editCard}}></button></div>
`);
this.set('cards', [ createComponentCard('demo-card') ]);
this.set('mobiledoc', simpleMobileDoc(''));
this.on('didCreateEditor', (editor) => { this.editor = editor; });
this.set('cards', [card]);
this.set('mobiledoc', simpleMobileDoc());
this.on('didCreateEditor', (_editor) => editor = _editor);
this.render(hbs`
{{#mobiledoc-editor mobiledoc=mobiledoc cards=cards did-create-editor=(action "didCreateEditor") as |editor|}}
<button id='add-card' {{action editor.addCard 'demo-card'}}></button>
Expand All @@ -450,7 +447,7 @@ test('it adds a card and removes an active blank section', function(assert) {

assert.equal(this.$('.mobiledoc-editor p').length, 1, 'blank section exists');
assert.equal(this.$('#demo-card').length, 0, 'no card section exists');
this.editor.selectRange(new MobiledocKit.Range(this.editor.post.headPosition()));
editor.selectRange(new MobiledocKit.Range(editor.post.headPosition()));
this.$('button#add-card').click();

assert.equal(this.$('.mobiledoc-editor p').length, 0, 'no blank section');
Expand All @@ -459,26 +456,21 @@ test('it adds a card and removes an active blank section', function(assert) {

test('it adds a card and focuses the cursor at the end of the card', function(assert) {
assert.expect(6);
this.registry.register('template:components/demo-card', hbs`

let card = this.registerCardComponent('demo-card', hbs`
<div id="demo-card"><button id='edit-card' {{action editCard}}></button></div>
`);
this.set('cards', [
createComponentCard('demo-card')
]);
this.set('cards', [card]);
let editor;
this.on('expose-editor', (hash) => {
editor = hash.editor;
});
this.set('mobiledoc', simpleMobileDoc(''));
this.on('didCreateEditor', (_editor) => editor = _editor);
this.set('mobiledoc', simpleMobileDoc());
this.render(hbs`
{{#mobiledoc-editor mobiledoc=mobiledoc cards=cards as |editor|}}
{{#mobiledoc-editor did-create-editor=(action 'didCreateEditor') mobiledoc=mobiledoc cards=cards as |editor|}}
<button id='add-card' {{action editor.addCard 'demo-card'}}></button>
<button id='get-editor' {{action 'expose-editor' editor}}></button>
{{/mobiledoc-editor}}
`);

moveCursorTo(this, '.mobiledoc-editor p');
this.$('button#get-editor').click();
this.$('button#add-card').click();
assert.equal(this.$('#demo-card').length, 1, 'card section exists');

Expand All @@ -503,9 +495,7 @@ test('it has `addCardInEditMode` action to add card in edit mode', function(asse

this.render(hbs`
{{#mobiledoc-editor cards=cards as |editor|}}
<button id='add-card'
{{action editor.addCardInEditMode 'demo-card'}}>
</button>
<button id='add-card' {{action editor.addCardInEditMode 'demo-card'}}>Add Card</button>
{{/mobiledoc-editor}}
`);

Expand All @@ -525,9 +515,8 @@ test(`sets ${COMPONENT_CARD_EXPECTED_PROPS.join(',')} properties on card compone
});
}
});
this.registry.register('component:demo-card', Component);
this.registry.register('template:components/demo-card', hbs`<div id="demo-card"></div>`);
this.set('cards', [createComponentCard('demo-card')]);
let card = this.registerCardComponent('demo-card', hbs`<div id='demo-card'></div>`, Component);
this.set('cards', [card]);
this.set('mobiledoc', mobiledocWithCard('demo-card'));

this.render(hbs`
Expand All @@ -545,9 +534,8 @@ test('component card `env` property exposes `isInEditor`', function(assert) {
env = this.get('env');
}
});
this.registry.register('component:demo-card', Component);
this.registry.register('template:components/demo-card', hbs`<div id="demo-card"></div>`);
this.set('cards', [createComponentCard('demo-card')]);
let card = this.registerCardComponent('demo-card', hbs`<div id='demo-card'></div>`, Component);
this.set('cards', [card]);
this.set('mobiledoc', mobiledocWithCard('demo-card'));

this.render(hbs`
Expand Down Expand Up @@ -575,15 +563,14 @@ test('(deprecated) `addCard` passes `data`, breaks reference to original payload
}
});

this.registry.register('component:demo-card', DemoCardComponent);
this.registry.register('template:components/demo-card', hbs`
let card = this.registerCardComponent('demo-card', hbs`
<div id="demo-card">
{{data.foo}}
<button id='mutate-payload' {{action 'mutatePayload'}}></button>
</div>
`);
`, DemoCardComponent);

this.set('cards', [createComponentCard('demo-card')]);
this.set('cards', [card]);
let payload = {foo: 'bar'};
this.set('payload', payload);

Expand Down Expand Up @@ -628,15 +615,14 @@ test('`addCard` passes `payload`, breaks reference to original payload', functio
}
});

this.registry.register('component:demo-card', DemoCardComponent);
this.registry.register('template:components/demo-card', hbs`
let card = this.registerCardComponent('demo-card', hbs`
<div id="demo-card">
{{payload.foo}}
<button id='mutate-payload' {{action 'mutatePayload'}}></button>
</div>
`);
`, DemoCardComponent);

this.set('cards', [createComponentCard('demo-card')]);
this.set('cards', [card]);
let payload = {foo: 'bar'};
this.set('payload', payload);

Expand Down Expand Up @@ -809,33 +795,51 @@ test('#activeSectionTagNames is correct when a card is selected', function(asser
});
});

test('exposes `addAtom` action to add an atom', function(assert) {
let mobiledoc = simpleMobileDoc('howdy');
this.set('mobiledoc', mobiledoc);

this.registerAtomComponent('ember-atom', hbs`I AM AN ATOM`);
this.set('atoms', [createComponentAtom('ember-atom')]);
this.set('atomText', 'atom text');
this.set('atomPayload', {foo: 'bar'});
this.on('onChange', (_mobiledoc) => mobiledoc = _mobiledoc);
this.render(hbs`
{{#mobiledoc-editor on-change=(action 'onChange') mobiledoc=mobiledoc atoms=atoms as |editor|}}
<button id='add-atom' {{action editor.addAtom 'ember-atom' atomText atomPayload}}>Add Ember Atom</button>
{{/mobiledoc-editor}}
`);

let button = this.$('button#add-atom');
assert.ok(button.length, 'precond - has button');
assert.ok(!this.$('span:contains(I AM AN ATOM)').length, 'precond - no atom');
button.click();

assert.ok(this.$('span:contains(I AM AN ATOM)').length, 'atom is added after clicking');

let atom = mobiledoc.atoms[0];
let [ name, text, payload ] = atom;
assert.equal(name, 'ember-atom', 'correct atom name in mobiledoc');
assert.equal(text, 'atom text', 'correct atom text in mobiledoc');
assert.deepEqual(payload, {foo: 'bar'}, 'correct atom payload in mobiledoc');
});

test('wraps component-atom adding in runloop correctly', function(assert) {
assert.expect(3);
let mobiledoc = simpleMobileDoc('Howdy');
let editor;

this.set('mobiledoc', mobiledoc);
this.register('component:gather-editor', Ember.Component.extend({
didRender() {
editor = this.get('editor');
}
}));
this.registry.register('template:components/demo-atom', hbs`
<span id="demo-atom">demo-atom</span>
`);
this.set('atoms', [createComponentAtom('demo-atom')]);
this.set('mobiledoc', simpleMobileDoc(''));
this.on('didCreateEditor', (_editor) => editor = _editor);
let atom = this.registerAtomComponent('demo-atom', hbs`<span id='demo-atom'>demo-atom</span>`);
this.set('atoms', [atom]);
this.set('mobiledoc', simpleMobileDoc());
this.render(hbs`
{{#mobiledoc-editor mobiledoc=mobiledoc atoms=atoms as |editor|}}
{{gather-editor editor=editor.editor}}
{{#mobiledoc-editor did-create-editor=(action 'didCreateEditor') mobiledoc=mobiledoc atoms=atoms as |editor|}}
{{/mobiledoc-editor}}
`);

// Add an atom without being in a runloop
assert.ok(!Ember.run.currentRunLoop, 'precond - no run loop');
editor.run((postEditor) => {
moveCursorTo(this, 'p:first');
let position = editor.cursor.offsets.head;
let position = editor.range.head;
let atom = postEditor.builder.createAtom('demo-atom', 'value', {});
postEditor.insertMarkers(position, [atom]);
});
Expand All @@ -859,10 +863,11 @@ test('throws on unknown atom when `unknownAtomHandler` is not passed', function(
]
});
this.set('unknownAtomHandler', undefined);
this.set('atoms', []);

assert.throws(() => {
this.render(hbs`
{{#mobiledoc-editor mobiledoc=mobiledoc
{{#mobiledoc-editor mobiledoc=mobiledoc atoms=atoms
options=(hash unknownAtomHandler=unknownAtomHandler) as |editor|}}
{{/mobiledoc-editor}}
`);
Expand Down Expand Up @@ -894,9 +899,10 @@ test('calls `unknownAtomHandler` when it renders an unknown atom', function(asse
]
});

this.set('atoms', []);
this.render(hbs`
{{#mobiledoc-editor mobiledoc=mobiledoc
{{#mobiledoc-editor mobiledoc=mobiledoc atoms=atoms
options=(hash unknownAtomHandler=unknownAtomHandler) as |editor|}}
{{/mobiledoc-editor}}
`);
});
});
2 changes: 1 addition & 1 deletion tests/unit/helpers/hash-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ module('Unit | Helper | hash');

// Replace this with your real tests.
test('it works', function(assert) {
var result = hash([], { foo: 'bar' });
let result = hash([], { foo: 'bar' });
assert.ok(result.foo, 'hash contains arguments');
});
Loading

0 comments on commit edbb8fe

Please sign in to comment.