Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

fix(top-app-bar): Fix JS error when navigation icon is not present. #2751

Merged
merged 4 commits into from
May 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/mdc-top-app-bar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ class MDCTopAppBar extends MDCComponent {

// Get all icons in the toolbar and instantiate the ripples
const icons = [].slice.call(this.root_.querySelectorAll(strings.ACTION_ITEM_SELECTOR));
icons.push(this.navIcon_);
if (this.navIcon_) {
icons.push(this.navIcon_);
}

this.iconRipples_ = icons.map((icon) => {
const ripple = rippleFactory(icon);
Expand Down
29 changes: 22 additions & 7 deletions test/unit/mdc-top-app-bar/mdc-top-app-bar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ function getFixture(removeIcon) {
return html;
}

function getIconsCount(root) {
const selector = strings.ACTION_ITEM_SELECTOR + ',' + strings.NAVIGATION_ICON_SELECTOR;
return root.querySelectorAll(selector).length;
}

class FakeRipple {
constructor(root) {
this.root = root;
Expand All @@ -74,11 +79,11 @@ class FakeRipple {
}
}

function setupTest(removeIcon = false) {
function setupTest(removeIcon = false, rippleFactory = (el) => new FakeRipple(el)) {
const fixture = getFixture(removeIcon);
const root = fixture.querySelector(strings.ROOT_SELECTOR);
const icon = root.querySelector(strings.NAVIGATION_ICON_SELECTOR);
const component = new MDCTopAppBar(root, undefined, (el) => new FakeRipple(el));
const component = new MDCTopAppBar(root, undefined, rippleFactory);

return {root, component, icon};
}
Expand All @@ -89,12 +94,22 @@ test('attachTo initializes and returns an MDCTopAppBar instance', () => {
assert.isTrue(MDCTopAppBar.attachTo(getFixture()) instanceof MDCTopAppBar);
});

test('constructor instantiates icon ripples', () => {
const {root, component} = setupTest();
const selector = strings.ACTION_ITEM_SELECTOR + ',' + strings.NAVIGATION_ICON_SELECTOR;
const totalIcons = root.querySelectorAll(selector).length;
test('constructor instantiates icon ripples for all icons', () => {
const rippleFactory = td.function();
td.when(rippleFactory(td.matchers.anything())).thenReturn((el) => new FakeRipple(el));
const {root} = setupTest(/** removeIcon */ false, rippleFactory);

const totalIcons = getIconsCount(root);
td.verify(rippleFactory(td.matchers.anything()), {times: totalIcons});
Copy link
Contributor

@williamernest williamernest May 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test and the following test are causing warnings in the test runner and CI. Line 99 is mocking this object, and then it's testing that the mocked object got called.

WARN: 'Warning: testdouble.js - td.verify - test double was both stubbed and verified with arguments (anything()), which is redundant and probably unnecessary. (see: https://github.com/testdouble/testdouble.js/blob/master/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with-a-test-double )'

Copy link
Contributor

@kfranqueiro kfranqueiro May 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, good catch. I suppose since we're stubbing the function, inside it we can increment a variable that's local to the test function, and just assert that it has the value we expect afterwards?

});

test('constructor does not instantiate ripple for nav icon when not present', () => {
const rippleFactory = td.function();
td.when(rippleFactory(td.matchers.anything())).thenReturn((el) => new FakeRipple(el));
const {root} = setupTest(/** removeIcon */ true, rippleFactory);

assert.isTrue(component.iconRipples_.length === totalIcons);
const totalIcons = getIconsCount(root);
td.verify(rippleFactory(td.matchers.anything()), {times: totalIcons});
});

test('destroy destroys icon ripples', () => {
Expand Down