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

Refactor Modal.dispose and add test #27455

Merged
merged 2 commits into from
Oct 30, 2018
Merged

Refactor Modal.dispose and add test #27455

merged 2 commits into from
Oct 30, 2018

Conversation

iamandrewluca
Copy link
Contributor

@iamandrewluca iamandrewluca commented Oct 16, 2018

Having variables initialised from start _isTransitioning is better.
Would be better to add an no-undef eslint rule to check for undefined variables use.
Reordered variables by priority at show and hide function entrance.

  • fix Modal.dispose method
  • add test for Modal.dispose
  • add _isTransitioning default value

no-undef - this rule is enabled by default, but does not what we want
no-use-before-define - kind of does what we want, but does not work for class members

Resolves #27456

@iamandrewluca iamandrewluca changed the title Add _isTransitioning default value Add _isTransitioning default value for Modal Oct 17, 2018
@Johann-S
Copy link
Member

It seems your change decrease our coverage 🤔 can you investigate why ?

Your changes looks good to me 👍

@iamandrewluca
Copy link
Contributor Author

iamandrewluca commented Oct 17, 2018

@Johann-S I don't have so much experience with coveralls, what does this means?
I think a test for dispose should be added.

image

ps: good talk https://www.youtube.com/watch?v=O2tsvUJT09U

@Johann-S
Copy link
Member

Yep we have a lot of unit test we should add 😄
Coveralls show you where you have increased/decreased the coverage.

We don't want a 100% of coverage but at least 90% would be great 👍

@iamandrewluca
Copy link
Contributor Author

iamandrewluca commented Oct 18, 2018

@Johann-S what does this selector match?

$(window, document, this._element, this._backdrop).off(EVENT_KEY)

I want to test that line, but don't understand on what element event is turned off.
Is that a nested selector, or parallel selector?
Couldn't find any docs.

@iamandrewluca iamandrewluca changed the title Add _isTransitioning default value for Modal refactor(Modal): add _isTransitioning default value for Modal Oct 18, 2018
@Johann-S
Copy link
Member

@iamandrewluca this line remove all the event listeners we attached during the use of our modal

@iamandrewluca
Copy link
Contributor Author

@Johann-S yes, I understand this.
But it removes listeners on each one? window document element and backdrop? Or that will search for backdrop inside element inside document inside window? jQuery does not have such docs for multiple arguments constructor. It only has that one with context, but it works in reverse order of arguments.

jQuery(element1, element2)

This will try to find element1 inside element2.

@Johann-S
Copy link
Member

Yep for me it should remove the event listeners on each elements and that's what we should check


var $modal = $('<div id="modal-test"/>')
.bootstrapModal('show')
.bootstrapModal('hide')
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand the need to use show/hide methods here 🤔

var $modal = $('<div id="modal-test"/>').bootstrapModal()

assert.ok(typeof $modal.data('bs.modal') !== 'undefined', 'modal created')

$modal.bootstrapModal('dispose')

assert.ok(typeof $modal.data('bs.modal') === 'undefined', 'modal data object was disposed')

If you want to go further you can use a SinonJS spy to be sure dispose is called

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From start bs.modal is undefined, then is set on show, then is removed again on hide

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Disposing modal in show state is ambiguous. All listeners are removed, and you're stuck with an open modal on page.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

image

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean I have just to call $('#myModal').modal() ?
This 2 are the same

$('#myModal').modal() // will call `show` method
$('#myModal').modal('show') // will call `show` method

On tests page I get an error if I don't hide modal before dispose, when trying to click on something

QUnit.test('should dispose modal', function (assert) {
  assert.expect(1)
  var done = assert.async()

  var $modal = $('<div id="modal-test"/>')
    .bootstrapModal()
    .bootstrapModal('dispose')

  assert.ok(typeof $modal.data('bs.modal') === 'undefined', 'modal data object was disposed')
  done()
})

image

Also if I don't hide, body will have the padding added when there is overflow.

Copy link
Member

Choose a reason for hiding this comment

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

Tested that :

  QUnit.test('should dispose modal', function (assert) {
    assert.expect(2)
    var $el = $('<div id="modal-test"/>')
    $el.bootstrapModal()

    assert.ok($el.data('bs.modal') !== undefined)

    $el.bootstrapModal('dispose')

    assert.ok($el.data('bs.modal') === undefined)
  })

and it works fine on our unit tests

Copy link
Contributor Author

@iamandrewluca iamandrewluca Oct 24, 2018

Choose a reason for hiding this comment

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

Tried to click any input on the tests page? you will get an error, and also body padding is added.
Tests are passing, but tests page looks weird.

Copy link
Member

Choose a reason for hiding this comment

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

That's not the purpose here, we test if our dispose methods do the job that's all, so we just have to check if the data is removed and if the listeners too.

I did the first check (check if the data is removed).
We did that on other tests for our Modal and it's fine.

Copy link
Member

Choose a reason for hiding this comment

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

If you want we can discuss about that on the Bootstrap Slack 😉

@twbs twbs deleted a comment from iamandrewluca Oct 22, 2018
@twbs twbs deleted a comment from iamandrewluca Oct 22, 2018
@iamandrewluca iamandrewluca changed the title refactor(Modal): add _isTransitioning default value for Modal WIP: Add test for dispose method Oct 29, 2018
@iamandrewluca iamandrewluca changed the title WIP: Add test for dispose method WIP: Add test for Modal.dispose method Oct 29, 2018
@iamandrewluca iamandrewluca changed the title WIP: Add test for Modal.dispose method Add test for Modal.dispose method Oct 30, 2018
Having variables initialised from start `_isTransitioning` is better.
Would be better to add an eslint rule to check for undeclared variables use.
Reordered enter checks for `show` and `hide` by priority.
@iamandrewluca
Copy link
Contributor Author

iamandrewluca commented Oct 30, 2018

@Johann-S Done.
Some notes:

  • this is not valid jQuery
    $(window, document, this._element, this._backdrop).off(EVENT_KEY)
  • this._backdrop does not have any events attached to it. this._dialog has.
  • After dispose only Event.CLICK_DATA_API should remain on page

ps: my next PR also will be on modal improvement 😏 (about fixed, sticky elements)

@iamandrewluca iamandrewluca changed the title Add test for Modal.dispose method Refactor Modal.dispose and add test Oct 30, 2018
js/src/modal.js Outdated Show resolved Hide resolved
].join('')).appendTo('#qunit-fixture')

$modal.on('shown.bs.modal', function () {
var data = $(this).data()
Copy link
Member

Choose a reason for hiding this comment

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

var modal = $(this).data('bs.modal')

js/src/modal.js Outdated
@@ -197,7 +198,21 @@ class Modal {
dispose() {
$.removeData(this._element, DATA_KEY)

$(window, document, this._element, this._backdrop).off(EVENT_KEY)
/**
Copy link
Member

Choose a reason for hiding this comment

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

Can you remove this comment please ? We don't need to keep the history in comment, we have git which handle that for us 😉


assert.ok(typeof data['bs.modal'] === 'undefined', 'modal data object was disposed')

const modalEvents = [window, document, element, dialog]
Copy link
Member

Choose a reason for hiding this comment

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

Instead of doing that, you should use SinonJS spy to be sure we call .off on those elements

@Johann-S Johann-S merged commit bd28519 into twbs:v4-dev Oct 30, 2018
@mdo mdo mentioned this pull request Oct 30, 2018
@iamandrewluca iamandrewluca deleted the patch-1 branch October 30, 2018 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants