mtrl 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CLAUDE.md +33 -0
  2. package/index.ts +0 -2
  3. package/package.json +3 -1
  4. package/src/components/navigation/index.ts +4 -1
  5. package/src/components/navigation/types.ts +33 -0
  6. package/src/components/snackbar/index.ts +7 -1
  7. package/src/components/snackbar/types.ts +25 -0
  8. package/src/components/switch/index.ts +5 -1
  9. package/src/components/switch/types.ts +13 -0
  10. package/src/components/textfield/index.ts +7 -1
  11. package/src/components/textfield/types.ts +36 -0
  12. package/test/components/badge.test.ts +545 -0
  13. package/test/components/bottom-app-bar.test.ts +303 -0
  14. package/test/components/button.test.ts +233 -0
  15. package/test/components/card.test.ts +560 -0
  16. package/test/components/carousel.test.ts +951 -0
  17. package/test/components/checkbox.test.ts +462 -0
  18. package/test/components/chip.test.ts +692 -0
  19. package/test/components/datepicker.test.ts +1124 -0
  20. package/test/components/dialog.test.ts +990 -0
  21. package/test/components/divider.test.ts +412 -0
  22. package/test/components/extended-fab.test.ts +672 -0
  23. package/test/components/fab.test.ts +561 -0
  24. package/test/components/list.test.ts +365 -0
  25. package/test/components/menu.test.ts +718 -0
  26. package/test/components/navigation.test.ts +186 -0
  27. package/test/components/progress.test.ts +567 -0
  28. package/test/components/radios.test.ts +699 -0
  29. package/test/components/search.test.ts +1135 -0
  30. package/test/components/segmented-button.test.ts +732 -0
  31. package/test/components/sheet.test.ts +641 -0
  32. package/test/components/slider.test.ts +1220 -0
  33. package/test/components/snackbar.test.ts +461 -0
  34. package/test/components/switch.test.ts +452 -0
  35. package/test/components/tabs.test.ts +1369 -0
  36. package/test/components/textfield.test.ts +400 -0
  37. package/test/components/timepicker.test.ts +592 -0
  38. package/test/components/tooltip.test.ts +630 -0
  39. package/test/components/top-app-bar.test.ts +566 -0
  40. package/test/core/dom.attributes.test.ts +148 -0
  41. package/test/core/dom.classes.test.ts +152 -0
  42. package/test/core/dom.events.test.ts +243 -0
  43. package/test/core/emitter.test.ts +141 -0
  44. package/test/core/ripple.test.ts +99 -0
  45. package/test/core/state.store.test.ts +189 -0
  46. package/test/core/utils.normalize.test.ts +61 -0
  47. package/test/core/utils.object.test.ts +120 -0
  48. package/test/setup.ts +451 -0
  49. package/tsconfig.json +2 -2
  50. package/src/components/snackbar/constants.ts +0 -26
  51. package/test/components/button.test.js +0 -170
  52. package/test/components/checkbox.test.js +0 -238
  53. package/test/components/list.test.js +0 -105
  54. package/test/components/menu.test.js +0 -385
  55. package/test/components/navigation.test.js +0 -227
  56. package/test/components/snackbar.test.js +0 -234
  57. package/test/components/switch.test.js +0 -186
  58. package/test/components/textfield.test.js +0 -314
  59. package/test/core/emitter.test.js +0 -141
  60. package/test/core/ripple.test.js +0 -66
@@ -1,385 +0,0 @@
1
- // test/components/menu.test.js
2
- import { describe, test, expect, mock, beforeEach, afterEach } from 'bun:test'
3
- import createMenu from '../../src/components/menu/menu'
4
- import { MENU_ALIGN, MENU_VERTICAL_ALIGN, MENU_EVENTS, MENU_ITEM_TYPES } from '../../src/components/menu/constants'
5
-
6
- // Mock DOM APIs that aren't available in the test environment
7
- beforeEach(() => {
8
- // Mock Element.prototype methods
9
- Element.prototype.getBoundingClientRect = function () {
10
- return {
11
- width: 100,
12
- height: 100,
13
- top: 0,
14
- left: 0,
15
- right: 100,
16
- bottom: 100
17
- }
18
- }
19
-
20
- Element.prototype.closest = function (selector) {
21
- return null // Simple mock that returns null by default
22
- }
23
-
24
- Element.prototype.matches = function (selector) {
25
- return false // Simple mock that returns false by default
26
- }
27
-
28
- // Save original createElement to restore later
29
- const originalCreateElement = document.createElement
30
- document.createElement = function (tag) {
31
- const element = originalCreateElement.call(document, tag)
32
-
33
- // Add closest method for our tests
34
- element.closest = function (selector) {
35
- if (selector.includes('menu-item')) {
36
- return this.classList && this.classList.contains('mtrl-menu-item') ? this : null
37
- }
38
- return null
39
- }
40
-
41
- // Add matches method for our tests
42
- element.matches = function (selector) {
43
- if (selector === ':hover') return false
44
- return this.classList && this.classList.contains(selector.replace('.', ''))
45
- }
46
-
47
- // Mock the querySelectorAll method
48
- element.querySelectorAll = function (selector) {
49
- return [] // Return empty array by default
50
- }
51
-
52
- // Mock the querySelector method
53
- element.querySelector = function (selector) {
54
- return null // Return null by default
55
- }
56
-
57
- return element
58
- }
59
-
60
- // Mock window properties
61
- global.window = {
62
- ...global.window,
63
- innerWidth: 1024,
64
- innerHeight: 768
65
- }
66
-
67
- // Mock event listeners
68
- if (!global.eventListeners) {
69
- global.eventListeners = new Map()
70
- }
71
-
72
- const originalAddEventListener = Element.prototype.addEventListener
73
- Element.prototype.addEventListener = function (event, handler) {
74
- if (!global.eventListeners.has(this)) {
75
- global.eventListeners.set(this, new Map())
76
- }
77
- if (!global.eventListeners.get(this).has(event)) {
78
- global.eventListeners.get(this).set(event, new Set())
79
- }
80
- global.eventListeners.get(this).get(event).add(handler)
81
-
82
- // Call original if it exists
83
- if (originalAddEventListener) {
84
- originalAddEventListener.call(this, event, handler)
85
- }
86
- }
87
-
88
- const originalRemoveEventListener = Element.prototype.removeEventListener
89
- Element.prototype.removeEventListener = function (event, handler) {
90
- if (global.eventListeners.has(this) &&
91
- global.eventListeners.get(this).has(event)) {
92
- global.eventListeners.get(this).get(event).delete(handler)
93
- }
94
-
95
- // Call original if it exists
96
- if (originalRemoveEventListener) {
97
- originalRemoveEventListener.call(this, event, handler)
98
- }
99
- }
100
-
101
- // Mock offsetHeight/offsetWidth
102
- Object.defineProperty(Element.prototype, 'offsetHeight', {
103
- configurable: true,
104
- get: function () { return 100 }
105
- })
106
-
107
- Object.defineProperty(Element.prototype, 'offsetWidth', {
108
- configurable: true,
109
- get: function () { return 100 }
110
- })
111
- })
112
-
113
- afterEach(() => {
114
- // Clean up our mocks
115
- delete Element.prototype.getBoundingClientRect
116
- delete Element.prototype.closest
117
- delete Element.prototype.matches
118
-
119
- document.createElement = document.createElement.__originalFunction || document.createElement
120
-
121
- // Clear event listeners
122
- if (global.eventListeners) {
123
- global.eventListeners.clear()
124
- }
125
- })
126
-
127
- describe('Menu Component', () => {
128
- // Sample menu items for testing
129
- const testItems = [
130
- {
131
- name: 'copy',
132
- text: 'Copy'
133
- },
134
- {
135
- name: 'paste',
136
- text: 'Paste'
137
- },
138
- {
139
- type: 'divider'
140
- },
141
- {
142
- name: 'delete',
143
- text: 'Delete',
144
- disabled: true
145
- }
146
- ]
147
-
148
- // Sample nested menu items
149
- const nestedTestItems = [
150
- {
151
- name: 'file',
152
- text: 'File',
153
- items: [
154
- {
155
- name: 'new',
156
- text: 'New'
157
- },
158
- {
159
- name: 'open',
160
- text: 'Open'
161
- }
162
- ]
163
- },
164
- {
165
- name: 'edit',
166
- text: 'Edit',
167
- items: [
168
- {
169
- name: 'copy',
170
- text: 'Copy'
171
- },
172
- {
173
- name: 'paste',
174
- text: 'Paste'
175
- }
176
- ]
177
- }
178
- ]
179
-
180
- test('should create a menu element', () => {
181
- const menu = createMenu()
182
-
183
- expect(menu.element).toBeDefined()
184
- expect(menu.element.tagName).toBe('DIV')
185
- expect(menu.element.className).toContain('mtrl-menu')
186
- expect(menu.element.getAttribute('role')).toBe('menu')
187
- })
188
-
189
- test('should apply custom class', () => {
190
- const customClass = 'custom-menu'
191
- const menu = createMenu({
192
- class: customClass
193
- })
194
-
195
- expect(menu.element.className).toContain(customClass)
196
- })
197
-
198
- test('should add initial items', () => {
199
- const menu = createMenu({
200
- items: testItems
201
- })
202
-
203
- // Check if items methods exist
204
- expect(typeof menu.getItems).toBe('function')
205
-
206
- // Get items and verify we have a Map
207
- const items = menu.getItems()
208
- expect(items instanceof Map).toBe(true)
209
-
210
- // Verify item names in map
211
- expect(items.has('copy')).toBe(true)
212
- expect(items.has('paste')).toBe(true)
213
- expect(items.has('delete')).toBe(true)
214
- })
215
-
216
- test('should have show/hide methods', () => {
217
- const menu = createMenu()
218
-
219
- // Check for API methods
220
- expect(typeof menu.show).toBe('function')
221
- expect(typeof menu.hide).toBe('function')
222
- expect(typeof menu.isVisible).toBe('function')
223
-
224
- // Test visibility state
225
- expect(menu.isVisible()).toBe(false)
226
-
227
- // Show menu
228
- menu.show()
229
- expect(menu.isVisible()).toBe(true)
230
- expect(menu.element.classList.contains('mtrl-menu--visible')).toBe(true)
231
-
232
- // Hide menu
233
- menu.hide()
234
-
235
- // Note: Due to animations, isVisible() might still return true immediately after hide()
236
- // In a real environment, we'd wait for transitions to complete
237
- })
238
-
239
- test('should have positioning methods', () => {
240
- const menu = createMenu()
241
- const target = document.createElement('button')
242
-
243
- // Check for API method
244
- expect(typeof menu.position).toBe('function')
245
-
246
- // Test with different alignments
247
- const positionConfigs = [
248
- { align: MENU_ALIGN.LEFT, vAlign: MENU_VERTICAL_ALIGN.TOP },
249
- { align: MENU_ALIGN.RIGHT, vAlign: MENU_VERTICAL_ALIGN.BOTTOM },
250
- { align: MENU_ALIGN.CENTER, vAlign: MENU_VERTICAL_ALIGN.MIDDLE }
251
- ]
252
-
253
- positionConfigs.forEach(config => {
254
- try {
255
- menu.position(target, config)
256
- // If we reach here, no error was thrown
257
- expect(true).toBe(true)
258
- } catch (error) {
259
- // If an error occurs, the test should fail
260
- expect(error).toBeUndefined()
261
- }
262
- })
263
- })
264
-
265
- test('should add item dynamically', () => {
266
- const menu = createMenu()
267
-
268
- // Check for API method
269
- expect(typeof menu.addItem).toBe('function')
270
-
271
- // Test adding an item
272
- const newItem = {
273
- name: 'newItem',
274
- text: 'New Item'
275
- }
276
-
277
- menu.addItem(newItem)
278
-
279
- // Verify item was added
280
- const items = menu.getItems()
281
- expect(items.has('newItem')).toBe(true)
282
- })
283
-
284
- test('should remove item dynamically', () => {
285
- const menu = createMenu({
286
- items: testItems
287
- })
288
-
289
- // Check for API method
290
- expect(typeof menu.removeItem).toBe('function')
291
-
292
- // Test removing an item
293
- menu.removeItem('copy')
294
-
295
- // Verify item was removed
296
- const items = menu.getItems()
297
- expect(items.has('copy')).toBe(false)
298
- })
299
-
300
- test('should register event handlers', () => {
301
- const menu = createMenu()
302
-
303
- // Check for API methods
304
- expect(typeof menu.on).toBe('function')
305
- expect(typeof menu.off).toBe('function')
306
-
307
- // Create a mock handler
308
- const mockHandler = mock(() => {})
309
-
310
- // Register handler
311
- menu.on(MENU_EVENTS.SELECT, mockHandler)
312
-
313
- // We can't easily test if the handler is called in this environment
314
- // But we can check that the method works without error
315
- expect(mockHandler.mock.calls.length).toBe(0)
316
-
317
- // Unregister handler
318
- menu.off(MENU_EVENTS.SELECT, mockHandler)
319
- })
320
-
321
- test('should create nested menus for items with children', () => {
322
- // This test would be more complex in a real environment
323
- // For now, just verify the basic menu creation works with nested items
324
-
325
- const menu = createMenu({
326
- items: nestedTestItems
327
- })
328
-
329
- // Verify parent items exist
330
- const items = menu.getItems()
331
- expect(items.has('file')).toBe(true)
332
- expect(items.has('edit')).toBe(true)
333
-
334
- // We can't easily test the submenu creation here
335
- // But we can check that the parent items are created without error
336
- })
337
-
338
- test('should properly clean up resources on destroy', () => {
339
- const menu = createMenu()
340
-
341
- // Check for API method
342
- expect(typeof menu.destroy).toBe('function')
343
-
344
- const parentElement = document.createElement('div')
345
- parentElement.appendChild(menu.element)
346
-
347
- // Destroy the component
348
- menu.destroy()
349
-
350
- // Check if element was removed
351
- expect(parentElement.children.length).toBe(0)
352
- })
353
-
354
- test('should support keyboard navigation', () => {
355
- // Skip detailed keyboard navigation tests due to test environment limitations
356
- // Just verify the API methods exist
357
-
358
- const menu = createMenu()
359
-
360
- // Show the menu to initialize keyboard handlers
361
- menu.show()
362
-
363
- // In a real environment, we would dispatch keydown events and check results
364
- // But here we just verify the basic setup happens without errors
365
-
366
- // Hide and clean up
367
- menu.hide()
368
- })
369
-
370
- test('should handle outside clicks', () => {
371
- // This would typically close the menu
372
- // We can't fully test this behavior in the current environment
373
-
374
- const menu = createMenu()
375
- menu.show()
376
-
377
- // In a real environment, we would:
378
- // 1. Create a click event outside the menu
379
- // 2. Dispatch it
380
- // 3. Verify menu is hidden
381
-
382
- // For now, just ensure our menu API method is called without error
383
- menu.hide()
384
- })
385
- })
@@ -1,227 +0,0 @@
1
- // test/components/navigation.test.js
2
- import { describe, test, expect, mock, beforeEach, afterEach } from 'bun:test'
3
- import createNavigation from '../../src/components/navigation/index'
4
- import { NAV_VARIANTS, NAV_POSITIONS } from '../../src/components/navigation/constants'
5
-
6
- // Mock DOM APIs that aren't available in the test environment
7
- beforeEach(() => {
8
- // Mock closest method on elements
9
- Element.prototype.closest = function (selector) {
10
- return null // Simple mock that returns null
11
- }
12
-
13
- // Expand our mock to handle specific test cases
14
- const originalCreateElement = document.createElement
15
- document.createElement = function (tag) {
16
- const element = originalCreateElement.call(document, tag)
17
-
18
- // Add closest method for our tests
19
- element.closest = function (selector) {
20
- return null // Default to null
21
- }
22
-
23
- // Mock the querySelectorAll method
24
- element.querySelectorAll = function (selector) {
25
- return [] // Return empty array by default
26
- }
27
-
28
- // Mock the querySelector method
29
- element.querySelector = function (selector) {
30
- return null // Return null by default
31
- }
32
-
33
- return element
34
- }
35
- })
36
-
37
- afterEach(() => {
38
- // Clean up our mocks
39
- delete Element.prototype.closest
40
- document.createElement = document.createElement.__originalFunction || document.createElement
41
- })
42
-
43
- describe('Navigation Component', () => {
44
- // Sample items for testing
45
- const testItems = [
46
- {
47
- id: 'home',
48
- icon: '<svg viewBox="0 0 24 24"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>',
49
- label: 'Home'
50
- },
51
- {
52
- id: 'favorites',
53
- icon: '<svg viewBox="0 0 24 24"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>',
54
- label: 'Favorites'
55
- },
56
- {
57
- id: 'settings',
58
- icon: '<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>',
59
- label: 'Settings'
60
- }
61
- ]
62
-
63
- // Sample items with nesting for drawer tests
64
- const nestedItems = [
65
- {
66
- id: 'dashboard',
67
- icon: '<svg viewBox="0 0 24 24"><path d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"/></svg>',
68
- label: 'Dashboard'
69
- },
70
- {
71
- id: 'content',
72
- icon: '<svg viewBox="0 0 24 24"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/></svg>',
73
- label: 'Content',
74
- items: [
75
- {
76
- id: 'articles',
77
- icon: '<svg viewBox="0 0 24 24"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></svg>',
78
- label: 'Articles'
79
- },
80
- {
81
- id: 'media',
82
- icon: '<svg viewBox="0 0 24 24"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></svg>',
83
- label: 'Media'
84
- }
85
- ]
86
- }
87
- ]
88
-
89
- test('should create a navigation element', () => {
90
- const nav = createNavigation()
91
-
92
- expect(nav.element).toBeDefined()
93
- expect(nav.element.tagName).toBe('NAV')
94
- expect(nav.element.className).toContain('mtrl-nav')
95
- })
96
-
97
- test('should apply variant class', () => {
98
- // Test one variant
99
- const variant = NAV_VARIANTS.RAIL
100
- const nav = createNavigation({
101
- variant
102
- })
103
-
104
- expect(nav.config.variant).toBe(variant)
105
- })
106
-
107
- test('should apply position class', () => {
108
- // Test one position
109
- const position = NAV_POSITIONS.LEFT
110
- const nav = createNavigation({
111
- position
112
- })
113
-
114
- expect(nav.config.position).toBe(position)
115
- })
116
-
117
- test('should add initial items', () => {
118
- // Mock getItemPath to avoid closest() issues
119
- const originalGetItemPath = Function.prototype.toString
120
- Function.prototype.toString = function () {
121
- if (this.name === 'getItemPath') {
122
- return 'function getItemPath() { return []; }'
123
- }
124
- return originalGetItemPath.apply(this)
125
- }
126
-
127
- const nav = createNavigation({
128
- items: testItems
129
- })
130
-
131
- // Check if items map exists
132
- expect(nav.items).toBeDefined()
133
-
134
- // Restore original function
135
- Function.prototype.toString = originalGetItemPath
136
- })
137
-
138
- test('should set active item', () => {
139
- // Skip this test for now due to DOM issues
140
- // We would need much more extensive mocking to make it work
141
- console.log('Skipping "should set active item" test due to DOM API limitations in test environment')
142
- })
143
-
144
- test('should add item dynamically', () => {
145
- const nav = createNavigation()
146
-
147
- // Add an item
148
- const newItem = {
149
- id: 'profile',
150
- icon: '<svg viewBox="0 0 24 24"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>',
151
- label: 'Profile'
152
- }
153
-
154
- // Just verify the method exists and can be called
155
- expect(typeof nav.addItem).toBe('function')
156
-
157
- try {
158
- nav.addItem(newItem)
159
- } catch (error) {
160
- // We might get errors due to DOM API limitations
161
- // Just check if we have the API method
162
- }
163
- })
164
-
165
- test('should remove item dynamically', () => {
166
- // Just verify the method exists
167
- const nav = createNavigation()
168
- expect(typeof nav.removeItem).toBe('function')
169
- })
170
-
171
- test('should handle nested items correctly', () => {
172
- // Skip this test for now due to DOM issues
173
- console.log('Skipping "should handle nested items correctly" test due to DOM API limitations in test environment')
174
- })
175
-
176
- test('should support disabled state', () => {
177
- const nav = createNavigation()
178
-
179
- // Check API methods
180
- expect(typeof nav.disable).toBe('function')
181
- expect(typeof nav.enable).toBe('function')
182
-
183
- // Test the API methods
184
- nav.disable()
185
- nav.enable()
186
-
187
- // Test initially disabled through config
188
- const disabledNav = createNavigation({ disabled: true })
189
- expect(disabledNav.config.disabled).toBe(true)
190
- })
191
-
192
- test('should register event handlers', () => {
193
- const nav = createNavigation()
194
-
195
- // Verify event API exists
196
- expect(typeof nav.on).toBe('function')
197
- expect(typeof nav.off).toBe('function')
198
- })
199
-
200
- test('should get item by id', () => {
201
- // Just verify the method exists
202
- const nav = createNavigation()
203
- expect(typeof nav.getItem).toBe('function')
204
- })
205
-
206
- test('should apply custom class', () => {
207
- const customClass = 'custom-nav'
208
- const nav = createNavigation({
209
- class: customClass
210
- })
211
-
212
- expect(nav.element.className).toContain(customClass)
213
- })
214
-
215
- test('should properly clean up resources on destroy', () => {
216
- const nav = createNavigation()
217
-
218
- const parentElement = document.createElement('div')
219
- parentElement.appendChild(nav.element)
220
-
221
- // Destroy the component
222
- nav.destroy()
223
-
224
- // Check if element was removed
225
- expect(parentElement.children.length).toBe(0)
226
- })
227
- })