Skip to content

Commit

Permalink
Merge pull request #79 from plumelo/feature/empty_items_fixes
Browse files Browse the repository at this point in the history
Empty items fixes
  • Loading branch information
nomego authored Apr 2, 2019
2 parents 8b99f64 + 7af850d commit 9eef07b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 24 deletions.
4 changes: 2 additions & 2 deletions cosmoz-data-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@

// reset queue to 0 or maintain selection
let index = 0;
if (this.maintainSelection && this._previouslySelectedItem != null) {
if (items.length > 0 && this.maintainSelection && this._previouslySelectedItem != null) {
// search for previously selected item by reference
index = items.indexOf(this._previouslySelectedItem);

Expand Down Expand Up @@ -595,7 +595,7 @@
return {
prevDisabled: index < 1,
nextDisabled: index + 1 >= this.items.length,
[this.indexAs]: Math.min(Math.max(index, 0), this.items.length - 1)
[this.indexAs]: Math.max(Math.min(index, this.items.length - 1), 0)
};
}

Expand Down
66 changes: 44 additions & 22 deletions test/spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,22 @@
<template>
<cosmoz-data-nav>
<template strip-whitespace>
<span>id: [[ item.id ]],</span>
<span>index: [[ index ]]</span>
<span>[[ item.data ]]</span>
<input type="button" value="Next" cosmoz-data-nav-select="+1">
<input type="button" value="Prev" cosmoz-data-nav-select="-1">
<div class="slide">
<span>id: [[ item.id ]],</span>
<span>index: [[ index ]]</span>
<span>[[ item.data ]]</span>
<input type="button" value="Next" cosmoz-data-nav-select="+1">
<input type="button" value="Prev" cosmoz-data-nav-select="-1">
</div>
</template>
</cosmoz-data-nav>
</template>
</test-fixture>

<script>
const {flushRenderQueue} = window;
const selectedSlide = nav => nav.querySelector('div.selected .slide');

describe('cosmoz-data-nav', () => {
describe('constructor', () => {
it('renders', () => {
Expand Down Expand Up @@ -85,11 +89,12 @@

context('properties', () => {
let nav;
beforeEach(() => {
beforeEach(done => {
nav = fixture('basic');
nav._templatesObserver.flush();
nav.items = [{id: 1}, {id: 2}, {id: 3}];
flushRenderQueue(nav);
setTimeout(done, 50);
});

describe('animating', () => {
Expand Down Expand Up @@ -142,22 +147,22 @@
nav.items = [{id: 'a'}, {id: 'b'}, {id: 'c'}];
flushRenderQueue(nav);

expect(nav.querySelector('div.selected').textContent).to.equal('id: a,index: 0');
expect(selectedSlide(nav).textContent).to.equal('id: a,index: 0');
});

it('does not update the view when an item changes', () => {
const item = {id: 'a', data: 'somedata'};
nav.items = [item];
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: a,index: 0somedata');
expect(selectedSlide(nav).textContent).to.equal('id: a,index: 0somedata');

// attempt #1: updating a reference directly does not update the view
// this is expected as the data-nav has no way of knowing that data was updated
item.data = 'newdata';
expect(nav.items[0]).to.have.property('data', 'newdata');

expect(() => {
expect(nav.querySelector('div.selected').textContent).to.equal('id: a,index: 0newdata');
expect(selectedSlide(nav).textContent).to.equal('id: a,index: 0newdata');
}).throws('expected \'id: a,index: 0somedata\' to equal \'id: a,index: 0newdata\'');


Expand All @@ -168,7 +173,7 @@
expect(nav.items[0]).to.have.property('data', 'otherdata');

expect(() => {
expect(nav.querySelector('div.selected').textContent).to.equal('id: a,index: 0otherdata');
expect(selectedSlide(nav).textContent).to.equal('id: a,index: 0otherdata');
}).throws('expected \'id: a,index: 0somedata\' to equal \'id: a,index: 0otherdata\'');

// attempt #3: try to force render
Expand All @@ -182,7 +187,7 @@
flushRenderQueue(nav);

expect(() => {
expect(nav.querySelector('div.selected').textContent).to.equal('id: a,index: 0freshdata');
expect(selectedSlide(nav).textContent).to.equal('id: a,index: 0freshdata');
}).throws('expected \'id: a,index: 0somedata\' to equal \'id: a,index: 0freshdata\'');
});
});
Expand All @@ -193,12 +198,12 @@
nav.items = [{id: 'a'}, {id: 'b'}, {id: 'c'}];
nav.selected = 1;
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: b,index: 1');
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 1');

nav.items = [{id: 'c'}, {id: 'd'}, {id: 'e'}];
expect(nav.selected).to.equal(0);
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: c,index: 0');
expect(selectedSlide(nav).textContent).to.equal('id: c,index: 0');
});
});

Expand All @@ -212,37 +217,54 @@
nav.items = [{id: 'a'}, item, {id: 'c'}];
nav.selected = 1;
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: b,index: 1somedata');
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 1somedata');

item.data = 'otherdata';
nav.items = [{id: 'a'}, {id: 'd'}, {id: 'e'}, item];
expect(nav.selected).to.equal(3);
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: b,index: 3otherdata');
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 3otherdata');
});

it('on `items` change, updates `selected` to match the last selected item, by id', () => {
nav.items = [{id: 'a'}, {id: 'b', data: 'somedata'}, {id: 'c'}];
nav.selected = 1;
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: b,index: 1somedata');
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 1somedata');

nav.items = [{id: 'a'}, {id: 'd'}, {id: 'e'}, {id: 'b', data: 'otherdata'}];
expect(nav.selected).to.equal(3);
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: b,index: 3otherdata');
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 3otherdata');
});

it('on `items` change, maintains `selected` to it\'s current value, if the last selected item is no longer present, by reference or by id', () => {
nav.items = [{id: 'a'}, {id: 'b'}, {id: 'c'}];
nav.selected = 1;
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: b,index: 1');
expect(selectedSlide(nav).textContent).to.equal('id: b,index: 1');

nav.items = [{id: 'a'}, {id: 'd'}, {id: 'e'}];
expect(nav.selected).to.equal(1);
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: d,index: 1');
expect(selectedSlide(nav).textContent).to.equal('id: d,index: 1');
});

it('resets selected to 0 when `items` is empty', () => {
nav.items = [{id: 'a'}, {id: 'b'}, {id: 'c'}];
nav.selected = 2;
flushRenderQueue(nav);
expect(selectedSlide(nav).textContent).to.equal('id: c,index: 2');

nav.items = [];
expect(nav.selected).to.equal(0);
flushRenderQueue(nav);
expect(selectedSlide(nav).textContent).to.equal('id: c,index: 2');

nav.items = [{id: 'd'}, {id: 'e'}, {id: 'f'}];
expect(nav.selected).to.equal(0);
flushRenderQueue(nav);
expect(selectedSlide(nav).textContent).to.equal('id: d,index: 0');
});

context('when idPath is set', () => {
Expand All @@ -251,12 +273,12 @@
nav.items = [{deep: {id: 'a'}}, {deep: {id: 'b'}, data: 'somedata'}, {deep: {id: 'c'}}];
nav.selected = 1;
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: ,index: 1somedata');
expect(selectedSlide(nav).textContent).to.equal('id: ,index: 1somedata');

nav.items = [{deep: {id: 'a'}}, {deep: {id: 'd'}}, {deep: {id: 'e'}}, {deep: {id: 'b'}, data: 'otherdata'}];
expect(nav.selected).to.equal(3);
flushRenderQueue(nav);
expect(nav.querySelector('div.selected').textContent).to.equal('id: ,index: 3otherdata');
expect(selectedSlide(nav).textContent).to.equal('id: ,index: 3otherdata');
});
});
});
Expand Down Expand Up @@ -287,7 +309,7 @@
nav.selected = 1;

expect(nav.selected).to.equal(1);
expect(nav.querySelector('div.selected').textContent).to.equal('id: 2,index: 1');
expect(selectedSlide(nav).textContent).to.equal('id: 2,index: 1');
});
});

Expand Down

0 comments on commit 9eef07b

Please sign in to comment.