From 43b9ff439386e4bf3dae76a03ad8d18a68c59d42 Mon Sep 17 00:00:00 2001 From: asakusuma Date: Wed, 11 May 2016 11:48:38 -0700 Subject: [PATCH] [FEATURE ember-improved-instrumentation] Add link-to instrumentation --- FEATURES.md | 1 + .../ember-htmlbars/lib/components/link-to.js | 19 ++++- .../ember-routing/lib/services/routing.js | 2 + .../tests/system/event_dispatcher_test.js | 11 ++- packages/ember/tests/helpers/link_to_test.js | 75 ++++++++++++++++++- .../ember/tests/view_instrumentation_test.js | 9 +-- 6 files changed, 101 insertions(+), 16 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index a3aaa73e531..d888fd8a87b 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -56,3 +56,4 @@ for a detailed explanation. - `interaction.` for events handled by a component. - `interaction.ember-action` for closure actions. + - `interaction.link-to` for link-to execution. diff --git a/packages/ember-htmlbars/lib/components/link-to.js b/packages/ember-htmlbars/lib/components/link-to.js index f73855854f7..f99f7c061e8 100644 --- a/packages/ember-htmlbars/lib/components/link-to.js +++ b/packages/ember-htmlbars/lib/components/link-to.js @@ -323,6 +323,8 @@ import 'ember-runtime/system/service'; // creates inject.service import ControllerMixin from 'ember-runtime/mixins/controller'; import layout from '../templates/link-to'; import EmberComponent, { HAS_BLOCK } from '../component'; +import { flaggedInstrument } from 'ember-metal/instrumentation'; + /** `Ember.LinkComponent` renders an element whose `click` event triggers a @@ -641,13 +643,24 @@ let LinkComponent = EmberComponent.extend({ return false; } - let routing = get(this, '_routing'); let qualifiedRouteName = get(this, 'qualifiedRouteName'); let models = get(this, 'models'); - let queryParamValues = get(this, 'queryParams.values'); + let queryParams = get(this, 'queryParams.values'); let shouldReplace = get(this, 'replace'); - routing.transitionTo(qualifiedRouteName, models, queryParamValues, shouldReplace); + let payload = { + queryParams, + routeName: qualifiedRouteName + }; + + flaggedInstrument('interaction.link-to', payload, this._generateTransition(payload, qualifiedRouteName, models, queryParams, shouldReplace)); + }, + + _generateTransition(payload, qualifiedRouteName, models, queryParams, shouldReplace) { + let routing = get(this, '_routing'); + return () => { + payload.transition = routing.transitionTo(qualifiedRouteName, models, queryParams, shouldReplace); + }; }, queryParams: null, diff --git a/packages/ember-routing/lib/services/routing.js b/packages/ember-routing/lib/services/routing.js index 43d56c70366..036104787f5 100644 --- a/packages/ember-routing/lib/services/routing.js +++ b/packages/ember-routing/lib/services/routing.js @@ -45,6 +45,8 @@ export default Service.extend({ if (shouldReplace) { transition.method('replace'); } + + return transition; }, normalizeQueryParams(routeName, models, queryParams) { diff --git a/packages/ember-views/tests/system/event_dispatcher_test.js b/packages/ember-views/tests/system/event_dispatcher_test.js index 39547f5ed6d..bfc3f5203fd 100644 --- a/packages/ember-views/tests/system/event_dispatcher_test.js +++ b/packages/ember-views/tests/system/event_dispatcher_test.js @@ -16,7 +16,7 @@ import { runAppend, runDestroy } from 'ember-runtime/tests/utils'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; -import { subscribe, unsubscribe } from 'ember-metal/instrumentation'; +import { subscribe, reset } from 'ember-metal/instrumentation'; var owner, view, originalViewKeyword; var dispatcher; @@ -42,7 +42,7 @@ QUnit.module('EventDispatcher', { teardown() { runDestroy(view); runDestroy(owner); - + reset(); resetKeyword('view', originalViewKeyword); } }); @@ -66,7 +66,7 @@ if (isEnabled('ember-improved-instrumentation')) { equal(clicked, 1, 'precond - The click handler was invoked'); let clickInstrumented = 0; - let clickSubscriber = subscribe('interaction.click', { + subscribe('interaction.click', { before() { clickInstrumented++; equal(clicked, 1, 'invoked before event is handled'); @@ -78,7 +78,7 @@ if (isEnabled('ember-improved-instrumentation')) { }); let keypressInstrumented = 0; - let keypressSubscriber = subscribe('interaction.keypress', { + subscribe('interaction.keypress', { before() { keypressInstrumented++; }, @@ -94,8 +94,7 @@ if (isEnabled('ember-improved-instrumentation')) { equal(clickInstrumented, 2, 'The click was instrumented'); strictEqual(keypressInstrumented, 0, 'The keypress was not instrumented'); } finally { - unsubscribe(clickSubscriber); - unsubscribe(keypressSubscriber); + reset(); } }); } diff --git a/packages/ember/tests/helpers/link_to_test.js b/packages/ember/tests/helpers/link_to_test.js index a7f8ab6e0c0..2712e1e1c5a 100644 --- a/packages/ember/tests/helpers/link_to_test.js +++ b/packages/ember/tests/helpers/link_to_test.js @@ -4,6 +4,7 @@ import Controller from 'ember-runtime/controllers/controller'; import { set } from 'ember-metal/property_set'; import Route from 'ember-routing/system/route'; import run from 'ember-metal/run_loop'; +import { subscribe, reset } from 'ember-metal/instrumentation'; import isEnabled from 'ember-metal/features'; import alias from 'ember-metal/alias'; import Application from 'ember-application/system/application'; @@ -76,6 +77,7 @@ function sharedSetup() { function sharedTeardown() { run(function() { App.destroy(); }); setTemplates({}); + reset(); } import { test } from 'ember-glimmer/tests/utils/skip-if-glimmer'; @@ -167,6 +169,78 @@ QUnit.test('The {{link-to}} helper moves into the named route', function() { equal(jQuery('#home-link:not(.active)', '#qunit-fixture').length, 1, 'The other link was rendered without active class'); }); +if (isEnabled('ember-improved-instrumentation')) { + QUnit.test('The {{link-to}} helper fires an interaction event', function(assert) { + assert.expect(2); + Router.map(function(match) { + this.route('about'); + }); + + bootApplication(); + + run(function() { + router.handleURL('/'); + }); + + subscribe('interaction.link-to', { + before() { + assert.ok(true, 'instrumentation subscriber was called'); + }, + after() { + assert.ok(true, 'instrumentation subscriber was called'); + } + }); + + jQuery('#about-link', '#qunit-fixture').click(); + }); + + QUnit.test('The {{link-to}} helper interaction event includes the route name', function(assert) { + assert.expect(2); + Router.map(function(match) { + this.route('about'); + }); + + bootApplication(); + + run(function() { + router.handleURL('/'); + }); + + subscribe('interaction.link-to', { + before(name, timestamp, { routeName }) { + assert.equal(routeName, 'about', 'instrumentation subscriber was passed route name'); + }, + after(name, timestamp, { routeName }) { + assert.equal(routeName, 'about', 'instrumentation subscriber was passed route name'); + } + }); + + jQuery('#about-link', '#qunit-fixture').click(); + }); + + QUnit.test('The {{link-to}} helper interaction event includes the transition in the after hook', function(assert) { + assert.expect(1); + Router.map(function(match) { + this.route('about'); + }); + + bootApplication(); + + run(function() { + router.handleURL('/'); + }); + + subscribe('interaction.link-to', { + before() {}, + after(name, timestamp, { transition }) { + assert.equal(transition.targetName, 'about', 'instrumentation subscriber was passed route name'); + } + }); + + jQuery('#about-link', '#qunit-fixture').click(); + }); +} + QUnit.test('The {{link-to}} helper supports URL replacement', function() { setTemplate('index', compile(`

Home

{{#link-to 'about' id='about-link' replace=true}}About{{/link-to}}`)); @@ -1757,4 +1831,3 @@ QUnit.test('GJ: {{link-to}} to a parent root model hook which performs a `transi shouldBeActive('#parent-link'); }); - diff --git a/packages/ember/tests/view_instrumentation_test.js b/packages/ember/tests/view_instrumentation_test.js index d4bfdce5109..73d6fe9fbf9 100644 --- a/packages/ember/tests/view_instrumentation_test.js +++ b/packages/ember/tests/view_instrumentation_test.js @@ -1,7 +1,7 @@ import run from 'ember-metal/run_loop'; import $ from 'ember-views/system/jquery'; import Application from 'ember-application/system/application'; -import { subscribe, unsubscribe } from 'ember-metal/instrumentation'; +import { subscribe, reset } from 'ember-metal/instrumentation'; import { compile } from 'ember-template-compiler/tests/utils/helpers'; import { setTemplates, set as setTemplate } from 'ember-templates/template_registry'; import { test, testModule } from 'ember-glimmer/tests/utils/skip-if-glimmer'; @@ -24,7 +24,6 @@ function handleURL(path) { return run(router, 'handleURL', path); } -let subscriber; testModule('View Instrumentation', { setup() { run(function() { @@ -43,9 +42,7 @@ testModule('View Instrumentation', { }, teardown() { - if (subscriber) { - unsubscribe(subscriber); - } + reset(); run(App, 'destroy'); App = null; setTemplates({}); @@ -54,7 +51,7 @@ testModule('View Instrumentation', { test('Nodes without view instances are instrumented', function(assert) { var called = false; - subscriber = subscribe('render', { + subscribe('render', { before() { called = true; },