UNPKG

bootstrap-vue-3

Version:

Early (but lovely) implementation of Vue 3, Bootstrap 5 and Typescript

1,435 lines (1,239 loc) 38 kB
import {enableAutoUnmount, mount} from '@vue/test-utils' import {afterEach, beforeEach, describe, expect, it, vitest} from 'vitest' import {nextTick} from 'vue' import {createContainer, waitRAF} from '../../../tests/utils' import BFormCheckbox from './BFormCheckbox.vue' describe('form-checkbox', () => { enableAutoUnmount(afterEach) // --- Custom checkbox structure, class and attributes tests --- it('default has structure <div><input><label></label></div>', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) expect(wrapper).toBeDefined() expect(wrapper.element.tagName).toBe('DIV') const $children = wrapper.element.children expect($children.length).toEqual(2) expect($children[0].tagName).toEqual('INPUT') expect($children[1].tagName).toEqual('LABEL') }) it('default has wrapper class form-check and custom-checkbox', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) expect(wrapper.classes().length).toEqual(1) expect(wrapper.classes()).toContain('form-check') }) it('default has input type checkbox', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('type')).toBeDefined() expect($input.attributes('type')).toEqual('checkbox') }) it('default does not have aria-label attribute on input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) expect(wrapper.get('input').attributes('aria-label')).toBeUndefined() }) it('has aria-label attribute on input when aria-label provided', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, ariaLabel: 'bar', }, slots: { default: 'foo', }, }) expect(wrapper.get('input').attributes('aria-label')).toBe('bar') }) it('default has input class form-check-input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.classes().length).toEqual(1) expect($input.classes()).toContain('form-check-input') expect($input.classes()).not.toContain('position-static') }) it('default has label class form-check-label', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label.classes().length).toEqual(1) expect($label.classes()).toContain('form-check-label') }) it('has default slot content in label', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label.text()).toEqual('foobar') }) it('has default has label when slot content not set', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, }) const $label = wrapper.get('label') expect($label.text()).toEqual('') }) it('default has no disabled attribute on input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('disabled')).toBeUndefined() }) it('has disabled attribute on input when prop disabled set', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, disabled: true, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('disabled')).toBeDefined() }) it('default has no required attribute on input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('required')).toBeUndefined() }) it('does not have required attribute on input when prop required set and name prop not provided', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, required: true, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('required')).toBeUndefined() }) it('has required attribute on input when prop required and name set', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, name: 'test', required: true, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('required')).toBeDefined() }) it('default has no name attribute on input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('name')).toBeUndefined() }) it('has name attribute on input when name prop set', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, name: 'test', }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('name')).toBeDefined() expect($input.attributes('name')).toEqual('test') }) it('default has no form attribute on input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('form')).toBeUndefined() }) it('has form attribute on input when form prop set', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, form: 'test', }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('form')).toBeDefined() expect($input.attributes('form')).toEqual('test') }) it('has custom attributes transferred to input element', () => { const wrapper = mount(BFormCheckbox, { props: { id: 'foo', foo: 'bar', }, }) const $input = wrapper.get('input') expect($input.attributes('foo')).toBeDefined() expect($input.attributes('foo')).toEqual('bar') }) it('default has class form-check-inline when prop inline=true', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, inline: true, }, slots: { default: 'foobar', }, }) expect(wrapper.classes().length).toEqual(2) expect(wrapper.classes()).toContain('form-check') expect(wrapper.classes()).toContain('form-check-inline') }) it('default has no input validation classes by default', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.classes()).not.toContain('is-invalid') expect($input.classes()).not.toContain('is-valid') }) it('default has no input validation classes when state=undefined', () => { const wrapper = mount(BFormCheckbox, { props: { state: undefined, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.classes()).not.toContain('is-invalid') expect($input.classes()).not.toContain('is-valid') }) it('default has input validation class is-valid when state=true', () => { const wrapper = mount(BFormCheckbox, { props: { state: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.classes()).not.toContain('is-invalid') expect($input.classes()).toContain('is-valid') }) it('default has input validation class is-invalid when state=false', () => { const wrapper = mount(BFormCheckbox, { props: { state: false, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.classes()).toContain('is-invalid') expect($input.classes()).not.toContain('is-valid') }) it('has id attribute on input when id prop set', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, id: 'test', }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('id')).toBeDefined() expect($input.attributes('id')).toEqual('test') }) it('default has id attribute on input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('id')).toBeDefined() }) it('has for attribute on label when id prop set', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, id: 'test', }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label.attributes('for')).toBeDefined() expect($label.attributes('for')).toEqual('test') }) it('default has for attribute on label equal to id property of input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('id')).toBeDefined() const $label = wrapper.get('label') expect($label.attributes('for')).toBeDefined() expect($input.attributes('id')).toEqual($label.attributes('for')) }) it('default has unique id attribute on input', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const wrapper2 = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') const $input2 = wrapper2.get('input') expect($input.attributes('id')).toBeDefined() expect($input2.attributes('id')).toBeDefined() expect($input.attributes('id')).not.toEqual($input2.attributes('id')) }) // --- plain styling --- it('plain has structure <div><input><label></label></div>', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) expect(wrapper).toBeDefined() expect(wrapper.element.tagName).toBe('DIV') const $children = wrapper.element.children expect($children.length).toEqual(2) expect($children[0].tagName).toEqual('INPUT') expect($children[1].tagName).toEqual('LABEL') }) it('plain has no wrapper class form-check', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) expect(wrapper.classes().length).toEqual(0) expect(wrapper.classes()).not.toContain('form-check') }) it('plain has input type checkbox', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('type')).toBeDefined() expect($input.attributes('type')).toEqual('checkbox') }) it('plain has no input class form-check-input', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.classes().length).toEqual(0) expect($input.classes()).not.toContain('form-check-input') }) it('plain has no label class form-check-label', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label.classes()).not.toContain('form-check-label') expect($label.classes().length).toEqual(0) }) it('plain has default slot content in label', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label.text()).toEqual('foobar') }) it('plain does not have class position-static when label provided', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: false, }, slots: { default: 'foobar', }, }) expect(wrapper.get('input').classes()).not.toContain('position-static') }) it('plain has no label when no default slot content', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: false, }, }) expect(wrapper.find('label').exists()).toBe(false) }) it('plain has class form-check-inline when prop inline=true', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: false, inline: true, }, slots: { default: 'foobar', }, }) expect(wrapper.classes()).toContain('form-check-inline') }) it('plain has no input validation classes by default', () => { const wrapper = mount(BFormCheckbox, { props: { plain: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.classes()).not.toContain('is-invalid') expect($input.classes()).not.toContain('is-valid') }) it('plain has no input validation classes when state=undefined', () => { const wrapper = mount(BFormCheckbox, { props: { state: undefined, plain: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.classes()).not.toContain('is-invalid') expect($input.classes()).not.toContain('is-valid') }) it('plain has input validation class is-valid when state=true', () => { const wrapper = mount(BFormCheckbox, { props: { state: true, plain: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.classes()).not.toContain('is-invalid') expect($input.classes()).toContain('is-valid') }) it('plain has input validation class is-invalid when state=false', () => { const wrapper = mount(BFormCheckbox, { props: { state: false, plain: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.classes()).toContain('is-invalid') expect($input.classes()).not.toContain('is-valid') }) // --- Switch styling - stand alone --- it('switch has structure <div><input><label></label></div>', () => { const wrapper = mount(BFormCheckbox, { props: { switch: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) expect(wrapper).toBeDefined() expect(wrapper.element.tagName).toBe('DIV') const $children = wrapper.element.children expect($children.length).toEqual(2) expect($children[0].tagName).toEqual('INPUT') expect($children[1].tagName).toEqual('LABEL') }) it('switch has wrapper classes form-check and form-switch', () => { const wrapper = mount(BFormCheckbox, { props: { switch: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) expect(wrapper.classes().length).toEqual(2) expect(wrapper.classes()).toContain('form-check') expect(wrapper.classes()).toContain('form-switch') }) it('switch has input type checkbox', () => { const wrapper = mount(BFormCheckbox, { props: { switch: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.attributes('type')).toBeDefined() expect($input.attributes('type')).toEqual('checkbox') }) it('switch has input class form-check-input', () => { const wrapper = mount(BFormCheckbox, { props: { switch: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.classes().length).toEqual(1) expect($input.classes()).toContain('form-check-input') }) it('switch has label class form-check-label', () => { const wrapper = mount(BFormCheckbox, { props: { switch: true, modelValue: false, }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label.classes().length).toEqual(1) expect($label.classes()).toContain('form-check-label') }) // --- Button styling - stand-alone mode --- it('stand-alone button has structure <div><input><label></label></div>', () => { const wrapper = mount(BFormCheckbox, { props: { button: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) expect(wrapper).toBeDefined() expect(wrapper.element.tagName).toBe('DIV') const $children = wrapper.element.children expect($children.length).toEqual(2) expect($children[0].tagName).toEqual('INPUT') expect($children[1].tagName).toEqual('LABEL') }) it('stand-alone button has wrapper classes btn-check', () => { const wrapper = mount(BFormCheckbox, { props: { button: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.classes().length).toEqual(1) expect($input.classes()).toContain('btn-check') }) it('stand-alone button has label classes btn and btn-secondary when unchecked', () => { const wrapper = mount(BFormCheckbox, { props: { button: true, modelValue: false, value: 'a', }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label).toBeDefined() expect($label.classes().length).toEqual(2) expect($label.classes()).not.toContain('active') expect($label.classes()).not.toContain('focus') expect($label.classes()).toContain('btn') expect($label.classes()).toContain('btn-secondary') }) it('stand-alone button has label classes btn, btn-secondary and active when checked by default', () => { const wrapper = mount(BFormCheckbox, { props: { button: true, modelValue: 'a', value: 'a', }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label).toBeDefined() expect($label.classes().length).toEqual(3) expect($label.classes()).not.toContain('focus') expect($label.classes()).toContain('btn') expect($label.classes()).toContain('btn-secondary') expect($label.classes()).toContain('active') }) it('stand-alone button has label class active when clicked (checked)', async () => { const wrapper = mount(BFormCheckbox, { props: { button: true, modelValue: false, value: 'a', }, attrs: { 'onUpdate:modelValue': (modelValue) => wrapper.setProps({modelValue}), }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label).toBeDefined() const $input = wrapper.get('input') expect($input).toBeDefined() expect($label.classes().length).toEqual(2) expect($label.classes()).not.toContain('focus') expect($label.classes()).not.toContain('active') expect($label.classes()).toContain('btn') expect($label.classes()).toContain('btn-secondary') await $input.setValue(true) expect($label.classes().length).toEqual(3) expect($label.classes()).toContain('active') expect($label.classes()).toContain('btn') expect($label.classes()).toContain('btn-secondary') }) it('stand-alone button has label class focus when input focused', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { button: true, modelValue: false, value: 'a', }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label).toBeDefined() const $input = wrapper.get('input') expect($label.classes().length).toEqual(2) expect($label.classes()).not.toContain('focus') expect($label.classes()).not.toContain('active') expect($label.classes()).toContain('btn') expect($label.classes()).toContain('btn-secondary') expect($input).toBeDefined() await $input.trigger('focus') expect($label.classes().length).toEqual(3) expect($label.classes()).toContain('focus') await $input.trigger('blur') expect($label.classes().length).toEqual(2) expect($label.classes()).not.toContain('focus') }) it('stand-alone button has label btn-primary when prop btn-variant set to primary', () => { const wrapper = mount(BFormCheckbox, { props: { button: true, buttonVariant: 'primary', modelValue: false, value: 'a', }, slots: { default: 'foobar', }, }) const $label = wrapper.get('label') expect($label).toBeDefined() expect($label.classes().length).toEqual(2) expect($label.classes()).not.toContain('focus') expect($label.classes()).not.toContain('active') expect($label.classes()).not.toContain('btn-secondary') expect($label.classes()).toContain('btn') expect($label.classes()).toContain('btn-primary') }) it('plain has no effect on stand-alone button', () => { const wrapper = mount(BFormCheckbox, { props: { button: true, plain: true, modelValue: '', value: 'a', }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input.classes().length).toEqual(1) expect($input.classes()).toContain('btn-check') }) // --- Indeterminate testing --- it('does not have input indeterminate set by default', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.element.indeterminate).toBe(false) }) it('has input indeterminate set by when indeterminate=true', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, indeterminate: true, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.element.indeterminate).toBe(true) }) it('has input indeterminate set by when indeterminate set to true after mount', async () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, indeterminate: false, }, slots: { default: 'foobar', }, }) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.element.indeterminate).toBe(false) await wrapper.setProps({indeterminate: true}) expect($input.element.indeterminate).toBe(true) await wrapper.setProps({indeterminate: false}) expect($input.element.indeterminate).toBe(false) }) // --- Functionality testing --- it('default has internal modelValue=false when prop modelValue=false', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: false, }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeDefined() expect(wrapper.vm.modelValue).toEqual(false) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.element.checked).toBe(false) }) it('default has internal modelValue=true when prop modelValue=true', () => { const wrapper = mount(BFormCheckbox, { props: { modelValue: true, }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeDefined() expect(wrapper.vm.modelValue).toEqual(true) const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.element.checked).toBe(true) }) it('default has internal modelValue null', () => { const wrapper = mount(BFormCheckbox, { props: { uncheckedValue: 'foo', value: 'bar', }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeUndefined() }) it('default has internal modelValue set to checked prop', () => { const wrapper = mount(BFormCheckbox, { props: { uncheckedValue: 'foo', value: 'bar', modelValue: 'foo', }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeDefined() expect(wrapper.vm.modelValue).toEqual('foo') }) it('default has internal modelValue set to value when checked=value', () => { const wrapper = mount(BFormCheckbox, { props: { uncheckedValue: 'foo', value: 'bar', modelValue: 'bar', }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeDefined() expect(wrapper.vm.modelValue).toEqual('bar') }) it('emits a change event when clicked', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { uncheckedValue: 'foo', value: 'bar', }, attrs: { 'onUpdate:modelValue': (modelValue) => wrapper.setProps({modelValue}), }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeUndefined() expect(wrapper.emitted('change')).toBeUndefined() const $input = wrapper.get('input') expect($input).toBeDefined() await $input.setValue(true) expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(1) expect(wrapper.emitted('change')[0][0]).toEqual('bar') await $input.setValue(false) expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(2) expect(wrapper.emitted('change')[1][0]).toEqual('foo') }) it('emits a change event when label clicked', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { uncheckedValue: 'foo', value: 'bar', }, attrs: { 'onUpdate:modelValue': (modelValue) => wrapper.setProps({modelValue}), }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeUndefined() expect(wrapper.emitted('change')).toBeUndefined() const $label = wrapper.get('label') expect($label).toBeDefined() await $label.trigger('click') expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(1) expect(wrapper.emitted('change')[0][0]).toEqual('bar') await $label.trigger('click') expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(2) expect(wrapper.emitted('change')[1][0]).toEqual('foo') }) it('does not emit a change event when clicked if disabled', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { uncheckedValue: 'foo', value: 'bar', disabled: true, }, attrs: { 'onUpdate:modelValue': (modelValue) => wrapper.setProps({modelValue}), }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeUndefined() expect(wrapper.emitted('change')).toBeUndefined() const $input = wrapper.get('input') expect($input).toBeDefined() await $input.trigger('click') expect(wrapper.emitted('change')).toBeUndefined() }) it('does not emit a change event when label clicked if disabled', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { uncheckedValue: 'foo', value: 'bar', disabled: true, }, attrs: { 'onUpdate:modelValue': (modelValue) => wrapper.setProps({modelValue}), }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeUndefined() expect(wrapper.emitted('change')).toBeUndefined() const $label = wrapper.get('label') expect($label).toBeDefined() await $label.trigger('click') expect(wrapper.emitted('change')).toBeUndefined() }) it('works when v-model bound to an array', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { value: 'bar', modelValue: ['foo'], }, attrs: { 'onUpdate:modelValue': (modelValue) => wrapper.setProps({modelValue}), }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeDefined() expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(1) expect(wrapper.vm.modelValue[0]).toEqual('foo') const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.element.checked).toBe(false) await $input.trigger('click') expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(2) expect(wrapper.vm.modelValue[0]).toEqual('foo') expect(wrapper.vm.modelValue[1]).toEqual('bar') expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(1) expect(wrapper.emitted('change')[0][0]).toEqual(['foo', 'bar']) expect($input).toBeDefined() expect($input.element.checked).toBe(true) await $input.trigger('click') expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(1) expect(wrapper.vm.modelValue[0]).toEqual('foo') expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(2) expect(wrapper.emitted('change')[1][0]).toEqual(['foo']) expect($input).toBeDefined() expect($input.element.checked).toBe(false) await wrapper.setProps({modelValue: []}) expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(0) expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(2) expect($input).toBeDefined() expect($input.element.checked).toBe(false) await $input.trigger('click') expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(1) expect(wrapper.vm.modelValue[0]).toEqual('bar') expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(3) expect(wrapper.emitted('change')[2][0]).toEqual(['bar']) expect($input).toBeDefined() expect($input.element.checked).toBe(true) await $input.trigger('click') expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(0) expect(wrapper.emitted('change')).toBeDefined() expect(wrapper.emitted('change').length).toBe(4) expect(wrapper.emitted('change')[3][0]).toEqual([]) expect($input).toBeDefined() expect($input.element.checked).toBe(false) }) it('should react to model changes when bound to an array', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { value: 'bar', modelValue: ['foo'], }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeDefined() expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(1) expect(wrapper.vm.modelValue[0]).toEqual('foo') const $input = wrapper.get('input') expect($input).toBeDefined() expect($input.element.checked).toBe(false) await wrapper.setProps({modelValue: ['bar', 'foo']}) expect($input).toBeDefined() expect($input.element.checked).toBe(true) expect(wrapper.vm.modelValue).toBeDefined() expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(2) expect(wrapper.vm.modelValue[0]).toEqual('bar') expect(wrapper.vm.modelValue[1]).toEqual('foo') }) it('works when value is an object', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { value: {bar: 1, baz: 2}, modelValue: ['foo'], }, attrs: { 'onUpdate:modelValue': (modelValue) => wrapper.setProps({modelValue}), }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() expect(wrapper.vm.modelValue).toBeDefined() expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(1) expect(wrapper.vm.modelValue[0]).toEqual('foo') const $input = wrapper.get('input') expect($input).toBeDefined() await $input.trigger('click') expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(2) expect(wrapper.vm.modelValue[0]).toEqual('foo') expect(wrapper.vm.modelValue[1]).toEqual({bar: 1, baz: 2}) await $input.trigger('click') expect(Array.isArray(wrapper.vm.modelValue)).toBe(true) expect(wrapper.vm.modelValue.length).toBe(1) expect(wrapper.vm.modelValue[0]).toEqual('foo') }) // These tests are wrapped in a new describe to limit the scope // of the `getBoundingClientRect()` mock describe('prop `autofocus`', () => { const origGetBCR = Element.prototype.getBoundingClientRect beforeEach(() => { // Mock `getBoundingClientRect()` so that the `isVisible(el)` test returns `true` // In our test below, all pagination buttons would normally be visible Element.prototype.getBoundingClientRect = vitest.fn(() => ({ width: 24, height: 24, top: 0, left: 0, bottom: 0, right: 0, })) }) afterEach(() => { // Restore prototype Element.prototype.getBoundingClientRect = origGetBCR }) it('works when true', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { modelValue: false, autofocus: true, }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() await nextTick() await waitRAF() const $input = wrapper.find('input') expect($input.exists()).toBe(true) expect(document).toBeDefined() expect(document.activeElement).toBe($input.element) }) it('does not auto focus when false', async () => { const wrapper = mount(BFormCheckbox, { attachTo: createContainer(), props: { modelValue: false, autofocus: false, }, slots: { default: 'foobar', }, }) expect(wrapper.vm).toBeDefined() await nextTick() await waitRAF() const $input = wrapper.find('input') expect($input.exists()).toBe(true) expect(document).toBeDefined() expect(document.activeElement).not.toBe($input.element) }) }) })