Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comparator functionality #102

Merged
merged 4 commits into from
Feb 15, 2017
Merged

Comparator functionality #102

merged 4 commits into from
Feb 15, 2017

Conversation

frosetti
Copy link
Contributor

This project uses semver, please check the scope of this pr:

  • #patch# - backwards-compatible bug fix
  • #minor# - adding functionality in a backwards-compatible manner
  • #major# - incompatible API change

CHANGELOG

  • Added a default comparator which can be overridden with a custom comparator.
  • Added tests for three scenarios of clicking
  • Modified frost-list template to have a hook at the top of the container for easier testing of items below it.

@coveralls
Copy link

coveralls commented Feb 15, 2017

Coverage Status

Coverage increased (+71.7%) to 74.038% when pulling 80534ac on frosetti:fr/itemComparator into 64c4496 on ciena-frost:master.

expandedItem => itemComparator(expandedItem, item)) >= 0)
set(item, 'isSelected',
isEmpty(selectedItems) ? false : selectedItems.findIndex(
selectedItem => itemComparator(selectedItem, item)) >= 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

ItemComparator should return a boolean, not an index, so you should go with something more like this:

set(item, 'isSelected', isEmpty(selectedItems) ? false : selectedItems.some(selectedItem => itemComparator(selectedItem, item)))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I switched it over to use the .some function now.

const isSelected = !isCurrentlySelected
if (isSelected) {
selectedItems.pushObject(item)
} else {
selectedItems.removeObject(item)
selectedItems.removeAt(index)
// selectedItems.removeObject(item)
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove obsolete code, if we do want to keep your updated code. You already have the item, so I'm not sure what we gain by switching to .removeAt().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed it.

@@ -88,7 +93,8 @@ export default {

// If an endpoint was already selected remove selected items that were
// in the previous range but aren't in the new range
const previousEndpoint = items.indexOf(rangeState['endpoint'])
// const previousEndpoint = items.indexOf(rangeState['endpoint'])
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove obsolete code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed it.

const isCurrentlySelected = selectedItems.indexOf(item) >= 0
specific (selectedItems, item, rangeState, itemComparator) {
const index = selectedItems.findIndex(selectedItem => itemComparator(selectedItem, item))
const isCurrentlySelected = (index >= 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

You could just do this instead, so you don't have to .splice() later on:

const isCurrentlySelected = selectedItems.some(selectedItem => itemComparator(selectedItem, item))
...
selectedItems.removeObject(item)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can't use .removeObject in most places where you use a comparator as the objects are not guaranteed to be the same even if they have the same contents.

).to.eql(true)
describe('when doing basic click', function () {
beforeEach(function () {
this.$(hook('my-list-item', {index: 0})).click()
Copy link
Contributor

Choose a reason for hiding this comment

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

You should use $hook() when you want a jQuery object rather than wrapping it in this.$().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe I removed out all the this.$

})

it('item 0 is selected', function () {
expect(this.$($hook('my-list-item-container', {index: 0})).hasClass('is-selected')).to.eql(true)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the this.$() here and subsequent tests - it's not doing anything for you.

).to.eql(false)
describe('when doing basic click and all is selected', function () {
beforeEach(function () {
this.$($(hook('my-list-item-container', {index: 0})).find(hook('my-list-selection-checkbox'))).click()
Copy link
Contributor

@TheOtherDude TheOtherDude Feb 15, 2017

Choose a reason for hiding this comment

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

Like above, you should prefer $hook() over $(hook()).

Copy link
Contributor

@TheOtherDude TheOtherDude Feb 15, 2017

Choose a reason for hiding this comment

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

Also, we should try to just pass the index to the selection checkbox so you can select it with $hook('my-list-selection-checkbox', {index: 0})

This should do the trick in the frost-list-item-selection template:

{{! Template for the frost-list-item-selection component }}

{{frost-checkbox
  checked=isSelected
  hook=(concat hookPrefix '-checkbox')
  hookQualifiers=hookQualifiers
  size='medium'
}}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was unable to get that to work in that template but I did get it to work in
{{frost-list-item-selection
hook=(concat hookPrefix '-selection')
hookQualifiers=(hash index=index)
model=model
onSelect=(action '_select')
}}

{{if (is-lead-selection _items model) ' is-lead-selection'}}
'>
{{if (is-lead-selection _items model) ' is-lead-selection'}}'
data-test={{hook (concat hook '-item-container') index=index }}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd remove a couple spaces here so that data-test aligns with {{if ...}}.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's aligned now.

@frosetti
Copy link
Contributor Author

frosetti commented Feb 15, 2017

Don't merge this yet. I have to adjust the expanded items to use the comparator.
Added expanded item comparator and test for it.

@coveralls
Copy link

coveralls commented Feb 15, 2017

Coverage Status

Coverage increased (+71.7%) to 74.038% when pulling 67d33dd on frosetti:fr/itemComparator into 64c4496 on ciena-frost:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+71.7%) to 74.038% when pulling 67d33dd on frosetti:fr/itemComparator into 64c4496 on ciena-frost:master.

@@ -143,11 +143,11 @@ describe(test.label, function () {
})

it('item 0 is selected', function () {
expect(this.$($hook('my-list-item-container', {index: 0})).hasClass('is-selected')).to.eql(true)
expect($($hook('my-list-item-container', {index: 0})).hasClass('is-selected')).to.eql(true)
Copy link
Contributor

Choose a reason for hiding this comment

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

You are still wrapping these in an extra $().

And it's minor, but since you're going to change this anyway, you could take advantage of jquery-chai and write:

expect($hook('my-list-item-container', {index: 0})).to.have.class('is-selected')

That way you get a better failure message instead of false does not deeply equal true.

@coveralls
Copy link

coveralls commented Feb 15, 2017

Coverage Status

Coverage increased (+78.2%) to 80.531% when pulling 5b31f45 on frosetti:fr/itemComparator into 64c4496 on ciena-frost:master.

@TheOtherDude TheOtherDude merged commit dd8fef1 into ciena-frost:master Feb 15, 2017
const _rangeState = this.get('_rangeState')

// Selects are proccessed in order of precedence: specific, range, basic
if (isSpecificSelect) {
selection.specific(clonedSelectedItems, item, _rangeState)
selection.specific(clonedSelectedItems, item, _rangeState, this.get('itemComparator'))
Copy link
Contributor

Choose a reason for hiding this comment

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

Future note, best to store this against a const and then refer for each usage (when more than one usage is present)

{{if (is-lead-selection _items model) ' is-lead-selection'}}
'>
{{if (is-lead-selection _items model) ' is-lead-selection'}}'
data-test={{hook (concat hook '-item-container') index=index }}
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor - it's clearer if the concat uses hookPrefix to delineate

@sglanzer-deprecated
Copy link
Contributor

Very nice PR - well done 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants