Implement extension registration from an extension.json file
[mediawiki.git] / tests / qunit / suites / resources / jquery / jquery.makeCollapsible.test.js
blob804058193bf99d9233b3ae16f185724cb270cc91
1 ( function ( mw, $ ) {
2         var loremIpsum = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.';
4         QUnit.module( 'jquery.makeCollapsible', QUnit.newMwEnvironment( {
5                 setup: function () {
6                         this.clock = this.sandbox.useFakeTimers();
7                 }
8         } ) );
10         function prepareCollapsible( html, options ) {
11                 return $( $.parseHTML( html ) )
12                         .appendTo( '#qunit-fixture' )
13                         // options might be undefined here - this is okay
14                         .makeCollapsible( options );
15         }
17         // This test is first because if it fails, then almost all of the latter tests are meaningless.
18         QUnit.test( 'testing hooks/triggers', 4, function ( assert ) {
19                 var test = this,
20                         $collapsible = prepareCollapsible(
21                                 '<div class="mw-collapsible">' + loremIpsum + '</div>'
22                         ),
23                         $content = $collapsible.find( '.mw-collapsible-content' ),
24                         $toggle = $collapsible.find( '.mw-collapsible-toggle' );
26                 // In one full collapse-expand cycle, each event will be fired once
28                 // On collapse...
29                 $collapsible.on( 'beforeCollapse.mw-collapsible', function () {
30                         assert.assertTrue( $content.is( ':visible' ), 'first beforeCollapseExpand: content is visible' );
31                 } );
32                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
33                         assert.assertTrue( $content.is( ':hidden' ), 'first afterCollapseExpand: content is hidden' );
35                         // On expand...
36                         $collapsible.on( 'beforeExpand.mw-collapsible', function () {
37                                 assert.assertTrue( $content.is( ':hidden' ), 'second beforeCollapseExpand: content is hidden' );
38                         } );
39                         $collapsible.on( 'afterExpand.mw-collapsible', function () {
40                                 assert.assertTrue( $content.is( ':visible' ), 'second afterCollapseExpand: content is visible' );
41                         } );
43                         // ...expanding happens here
44                         $toggle.trigger( 'click' );
45                         test.clock.tick( 500 );
46                 } );
48                 // ...collapsing happens here
49                 $toggle.trigger( 'click' );
50                 test.clock.tick( 500 );
51         } );
53         QUnit.test( 'basic operation (<div>)', 5, function ( assert ) {
54                 var test = this,
55                         $collapsible = prepareCollapsible(
56                                 '<div class="mw-collapsible">' + loremIpsum + '</div>'
57                         ),
58                         $content = $collapsible.find( '.mw-collapsible-content' ),
59                         $toggle = $collapsible.find( '.mw-collapsible-toggle' );
61                 assert.equal( $content.length, 1, 'content is present' );
62                 assert.equal( $content.find( $toggle ).length, 0, 'toggle is not a descendant of content' );
64                 assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
66                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
67                         assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' );
69                         $collapsible.on( 'afterExpand.mw-collapsible', function () {
70                                 assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
71                         } );
73                         $toggle.trigger( 'click' );
74                         test.clock.tick( 500 );
75                 } );
77                 $toggle.trigger( 'click' );
78                 test.clock.tick( 500 );
79         } );
81         QUnit.test( 'basic operation (<table>)', 7, function ( assert ) {
82                 var test = this,
83                         $collapsible = prepareCollapsible(
84                                 '<table class="mw-collapsible">' +
85                                         '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
86                                         '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
87                                         '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
88                                 '</table>'
89                         ),
90                         $headerRow = $collapsible.find( 'tr:first' ),
91                         $contentRow = $collapsible.find( 'tr:last' ),
92                         $toggle = $headerRow.find( 'td:last .mw-collapsible-toggle' );
94                 assert.equal( $toggle.length, 1, 'toggle is added to last cell of first row' );
96                 assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' );
97                 assert.assertTrue( $contentRow.is( ':visible' ), 'contentRow is visible' );
99                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
100                         assert.assertTrue( $headerRow.is( ':visible' ), 'after collapsing: headerRow is still visible' );
101                         assert.assertTrue( $contentRow.is( ':hidden' ), 'after collapsing: contentRow is hidden' );
103                         $collapsible.on( 'afterExpand.mw-collapsible', function () {
104                                 assert.assertTrue( $headerRow.is( ':visible' ), 'after expanding: headerRow is still visible' );
105                                 assert.assertTrue( $contentRow.is( ':visible' ), 'after expanding: contentRow is visible' );
106                         } );
108                         $toggle.trigger( 'click' );
109                         test.clock.tick( 500 );
110                 } );
112                 $toggle.trigger( 'click' );
113                 test.clock.tick( 500 );
114         } );
116         function tableWithCaptionTest( $collapsible, test, assert ) {
117                 var $caption = $collapsible.find( 'caption' ),
118                         $headerRow = $collapsible.find( 'tr:first' ),
119                         $contentRow = $collapsible.find( 'tr:last' ),
120                         $toggle = $caption.find( '.mw-collapsible-toggle' );
122                 assert.equal( $toggle.length, 1, 'toggle is added to the end of the caption' );
124                 assert.assertTrue( $caption.is( ':visible' ), 'caption is visible' );
125                 assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' );
126                 assert.assertTrue( $contentRow.is( ':visible' ), 'contentRow is visible' );
128                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
129                         assert.assertTrue( $caption.is( ':visible' ), 'after collapsing: caption is still visible' );
130                         assert.assertTrue( $headerRow.is( ':hidden' ), 'after collapsing: headerRow is hidden' );
131                         assert.assertTrue( $contentRow.is( ':hidden' ), 'after collapsing: contentRow is hidden' );
133                         $collapsible.on( 'afterExpand.mw-collapsible', function () {
134                                 assert.assertTrue( $caption.is( ':visible' ), 'after expanding: caption is still visible' );
135                                 assert.assertTrue( $headerRow.is( ':visible' ), 'after expanding: headerRow is visible' );
136                                 assert.assertTrue( $contentRow.is( ':visible' ), 'after expanding: contentRow is visible' );
137                         } );
139                         $toggle.trigger( 'click' );
140                         test.clock.tick( 500 );
141                 } );
143                 $toggle.trigger( 'click' );
144                 test.clock.tick( 500 );
145         }
147         QUnit.test( 'basic operation (<table> with caption)', 10, function ( assert ) {
148                 tableWithCaptionTest( prepareCollapsible(
149                         '<table class="mw-collapsible">' +
150                                 '<caption>' + loremIpsum + '</caption>' +
151                                 '<tr><th>' + loremIpsum + '</th><th>' + loremIpsum + '</th></tr>' +
152                                 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
153                                 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
154                         '</table>'
155                 ), this, assert );
156         } );
158         QUnit.test( 'basic operation (<table> with caption and <thead>)', 10, function ( assert ) {
159                 tableWithCaptionTest( prepareCollapsible(
160                         '<table class="mw-collapsible">' +
161                                 '<caption>' + loremIpsum + '</caption>' +
162                                 '<thead><tr><th>' + loremIpsum + '</th><th>' + loremIpsum + '</th></tr></thead>' +
163                                 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
164                                 '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
165                         '</table>'
166                 ), this, assert );
167         } );
169         function listTest( listType, test, assert ) {
170                 var $collapsible = prepareCollapsible(
171                                 '<' + listType + ' class="mw-collapsible">' +
172                                         '<li>' + loremIpsum + '</li>' +
173                                         '<li>' + loremIpsum + '</li>' +
174                                 '</' + listType + '>'
175                         ),
176                         $toggleItem = $collapsible.find( 'li.mw-collapsible-toggle-li:first-child' ),
177                         $contentItem = $collapsible.find( 'li:last' ),
178                         $toggle = $toggleItem.find( '.mw-collapsible-toggle' );
180                 assert.equal( $toggle.length, 1, 'toggle is present, added inside new zeroth list item' );
182                 assert.assertTrue( $toggleItem.is( ':visible' ), 'toggleItem is visible' );
183                 assert.assertTrue( $contentItem.is( ':visible' ), 'contentItem is visible' );
185                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
186                         assert.assertTrue( $toggleItem.is( ':visible' ), 'after collapsing: toggleItem is still visible' );
187                         assert.assertTrue( $contentItem.is( ':hidden' ), 'after collapsing: contentItem is hidden' );
189                         $collapsible.on( 'afterExpand.mw-collapsible', function () {
190                                 assert.assertTrue( $toggleItem.is( ':visible' ), 'after expanding: toggleItem is still visible' );
191                                 assert.assertTrue( $contentItem.is( ':visible' ), 'after expanding: contentItem is visible' );
192                         } );
194                         $toggle.trigger( 'click' );
195                         test.clock.tick( 500 );
196                 } );
198                 $toggle.trigger( 'click' );
199                 test.clock.tick( 500 );
200         }
202         QUnit.test( 'basic operation (<ul>)', 7, function ( assert ) {
203                 listTest( 'ul', this, assert );
204         } );
206         QUnit.test( 'basic operation (<ol>)', 7, function ( assert ) {
207                 listTest( 'ol', this, assert );
208         } );
210         QUnit.test( 'basic operation when synchronous (options.instantHide)', 2, function ( assert ) {
211                 var $collapsible = prepareCollapsible(
212                                 '<div class="mw-collapsible">' + loremIpsum + '</div>',
213                                 { instantHide: true }
214                         ),
215                         $content = $collapsible.find( '.mw-collapsible-content' );
217                 assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
219                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
221                 assert.assertTrue( $content.is( ':hidden' ), 'after collapsing: content is hidden' );
222         } );
224         QUnit.test( 'mw-made-collapsible data added', 1, function ( assert ) {
225                 var $collapsible = prepareCollapsible(
226                                 '<div>' + loremIpsum + '</div>'
227                         );
229                 assert.equal( $collapsible.data( 'mw-made-collapsible' ), true, 'mw-made-collapsible data present' );
230         } );
232         QUnit.test( 'mw-collapsible added when missing', 1, function ( assert ) {
233                 var $collapsible = prepareCollapsible(
234                                 '<div>' + loremIpsum + '</div>'
235                         );
237                 assert.assertTrue( $collapsible.hasClass( 'mw-collapsible' ), 'mw-collapsible class present' );
238         } );
240         QUnit.test( 'mw-collapsed added when missing', 1, function ( assert ) {
241                 var $collapsible = prepareCollapsible(
242                         '<div>' + loremIpsum + '</div>',
243                                 { collapsed: true }
244                         );
246                 assert.assertTrue( $collapsible.hasClass( 'mw-collapsed' ), 'mw-collapsed class present' );
247         } );
249         QUnit.test( 'initial collapse (mw-collapsed class)', 2, function ( assert ) {
250                 var $collapsible = prepareCollapsible(
251                                 '<div class="mw-collapsible mw-collapsed">' + loremIpsum + '</div>'
252                         ),
253                         $content = $collapsible.find( '.mw-collapsible-content' );
255                 // Synchronous - mw-collapsed should cause instantHide: true to be used on initial collapsing
256                 assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' );
258                 $collapsible.on( 'afterExpand.mw-collapsible', function () {
259                         assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
260                 } );
262                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
263                 this.clock.tick( 500 );
264         } );
266         QUnit.test( 'initial collapse (options.collapsed)', 2, function ( assert ) {
267                 var $collapsible = prepareCollapsible(
268                                 '<div class="mw-collapsible">' + loremIpsum + '</div>',
269                                 { collapsed: true }
270                         ),
271                         $content = $collapsible.find( '.mw-collapsible-content' );
273                 // Synchronous - collapsed: true should cause instantHide: true to be used on initial collapsing
274                 assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' );
276                 $collapsible.on( 'afterExpand.mw-collapsible', function () {
277                         assert.assertTrue( $content.is( ':visible' ), 'after expanding: content is visible' );
278                 } );
280                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
281                 this.clock.tick( 500 );
282         } );
284         QUnit.test( 'clicks on links inside toggler pass through (options.linksPassthru)', 2, function ( assert ) {
285                 var $collapsible = prepareCollapsible(
286                                 '<div class="mw-collapsible">' +
287                                         '<div class="mw-collapsible-toggle">' +
288                                                 'Toggle <a href="#top">toggle</a> toggle <b>toggle</b>' +
289                                         '</div>' +
290                                         '<div class="mw-collapsible-content">' + loremIpsum + '</div>' +
291                                 '</div>',
292                                 // Can't do asynchronous because we're testing that the event *doesn't* happen
293                                 { instantHide: true }
294                         ),
295                         $content = $collapsible.find( '.mw-collapsible-content' );
297                 $collapsible.find( '.mw-collapsible-toggle a' ).trigger( 'click' );
298                 assert.assertTrue( $content.is( ':visible' ), 'click event on link inside toggle passes through (content not toggled)' );
300                 $collapsible.find( '.mw-collapsible-toggle b' ).trigger( 'click' );
301                 assert.assertTrue( $content.is( ':hidden' ), 'click event on non-link inside toggle toggles content' );
302         } );
304         QUnit.test( 'collapse/expand text (data-collapsetext, data-expandtext)', 2, function ( assert ) {
305                 var $collapsible = prepareCollapsible(
306                                 '<div class="mw-collapsible" data-collapsetext="Collapse me!" data-expandtext="Expand me!">' +
307                                         loremIpsum +
308                                 '</div>'
309                         ),
310                         $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
312                 assert.equal( $toggleLink.text(), 'Collapse me!', 'data-collapsetext is respected' );
314                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
315                         assert.equal( $toggleLink.text(), 'Expand me!', 'data-expandtext is respected' );
316                 } );
318                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
319                 this.clock.tick( 500 );
320         } );
322         QUnit.test( 'collapse/expand text (options.collapseText, options.expandText)', 2, function ( assert ) {
323                 var $collapsible = prepareCollapsible(
324                                 '<div class="mw-collapsible">' + loremIpsum + '</div>',
325                                 { collapseText: 'Collapse me!', expandText: 'Expand me!' }
326                         ),
327                         $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
329                 assert.equal( $toggleLink.text(), 'Collapse me!', 'options.collapseText is respected' );
331                 $collapsible.on( 'afterCollapse.mw-collapsible', function () {
332                         assert.equal( $toggleLink.text(), 'Expand me!', 'options.expandText is respected' );
333                 } );
335                 $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
336                 this.clock.tick( 500 );
337         } );
339 }( mediaWiki, jQuery ) );