it('can render filter selector', () => {
    let tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} />
            <DxTableFilterRow
              {...{ attrs: { ...defaultProps } }}
            />
          </DxPluginHost>
        );
      },
    });

    expect(tree.find(defaultProps.filterSelectorComponent).exists())
      .toBeFalsy();

    tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} />
            <DxTableFilterRow
              {...{ attrs: { ...defaultProps } }}
              showFilterSelector
            />
          </DxPluginHost>
        );
      },
    });

    expect(tree.find(defaultProps.filterSelectorComponent).exists())
      .toBeTruthy();
  });
  it('should render heading cell on user-defined column and filter row intersection', () => {
    isFilterTableCell.mockImplementation(() => true);

    const tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} />
            <DxTableFilterRow
              {...{ attrs: { ...defaultProps } }}
            />
          </DxPluginHost>
        );
      },
    });

    expect(isFilterTableCell)
      .toBeCalledWith(
        defaultDeps.template.tableCell.tableRow,
        defaultDeps.template.tableCell.tableColumn,
      );

    expect(tree.find(defaultProps.cellComponent).vm.$attrs)
      .toMatchObject({
        ...defaultDeps.template.tableCell,
        column: defaultDeps.template.tableCell.tableColumn.column,
      });
  });
    it('should extend tableBodyRows', () => {
      const tree = mount({
        render() {
          return (
            <DxPluginHost>
              <PluginDepsToComponents deps={defaultDeps} />
              <DxTableEditRow
                {...{ attrs: { ...defaultProps } }}
                rowHeight={120}
              />
            </DxPluginHost>
          );
        },
      });

      expect(getComputedState(tree).tableBodyRows)
        .toBe('tableRowsWithEditing');
      expect(tableRowsWithEditing)
        .toBeCalledWith(
          defaultDeps.getter.tableBodyRows,
          defaultDeps.getter.editingRowIds,
          defaultDeps.getter.addedRows,
          120,
        );
    });
  it('should handle edit cell onValueChange event', () => {
    isEditTableCell.mockImplementation(() => true);
    getRowChange.mockImplementation(() => ({ a: undefined }));
    const deps = {
      template: {
        tableCell: {
          tableRow: { row: { a: 'a1', b: 'b1' } },
          tableColumn: { column: { name: 'column' } },
        },
      },
    };

    const tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} depsOverrides={deps} />
            <DxTableEditRow
              {...{ attrs: { ...defaultProps } }}
              rowHeight={120}
            />
          </DxPluginHost>
        );
      },
    });

    tree.find(defaultProps.cellComponent).vm.$emit('valueChange', 'test');

    expect(defaultDeps.getter.createRowChange)
      .toBeCalledWith({
        a: undefined,
        b: 'b1',
      }, 'test', 'column');
  });
  it('should render edit cell on user-defined column and edit row intersection', () => {
    isEditTableCell.mockImplementation(() => true);

    const tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} />
            <DxTableEditRow
              {...{ attrs: { ...defaultProps } }}
              rowHeight={120}
            />
          </DxPluginHost>
        );
      },
    });

    expect(defaultDeps.getter.getCellValue)
      .toBeCalledWith(
        { ...defaultDeps.template.tableCell.tableRow.row },
        defaultDeps.template.tableCell.tableColumn.column.name,
      );
    expect(isEditTableCell)
      .toBeCalledWith(
        defaultDeps.template.tableCell.tableRow,
        defaultDeps.template.tableCell.tableColumn,
      );
    expect(tree.find(defaultProps.cellComponent).vm.$attrs)
      .toMatchObject({
        ...defaultDeps.template.tableCell,
        row: defaultDeps.template.tableCell.tableRow.row,
        column: defaultDeps.template.tableCell.tableColumn.column,
      });
  });
Beispiel #6
0
  test('removes child ref when the child is destroyed', async () => {
    const wrapper = mount({
      data: () => ({
        value: ''
      }),
      template: `
        <ValidationObserver ref="obs">
          <div slot-scope="ctx">

            <ValidationProvider rules="required" vid="id">

              <div slot-scope="{ errors }">
                <input v-model="value" type="text">
                <span id="error">{{ errors[0] }}</span>
              </div>

            </ValidationProvider>

          </div>
        </ValidationObserver>
      `
    }, { localVue: Vue });

    const obs = wrapper.vm.$refs.obs;
    expect(obs.refs).toHaveProperty('id');

    wrapper.destroy();

    expect(obs.refs).not.toHaveProperty('id');
  });
Beispiel #7
0
  test('observes the current state of providers', async () => {
    const wrapper = mount({
      data: () => ({
        value: ''
      }),
      template: `
        <ValidationObserver>
          <div slot-scope="{ valid }">
            <ValidationProvider rules="required">
              <div slot-scope="ctx">
                <input v-model="value" type="text">
              </div>
            </ValidationProvider>

            <span id="state">{{ valid }}</span>
          </div>
        </ValidationObserver>
      `
    }, { localVue: Vue });

    const stateSpan = wrapper.find('#state');
    const input = wrapper.find('input');

    await flushPromises();
    expect(stateSpan.text()).toBe('false');

    input.element.value = 'value';
    input.trigger('input');
    await flushPromises();

    expect(stateSpan.text()).toBe('true');
  });
Beispiel #8
0
  test('validates manually using the validate event handler', async () => {
    const wrapper = mount({
      template: `
        <ValidationProvider rules="required">
          <div slot-scope="{ validate, errors }">
            <input type="text" @input="validate">
            <p id="error">{{ errors[0] }}</p>  
          </div>
        </ValidationProvider>
      `
    }, { localVue: Vue });

    const input = wrapper.find('input');
    input.element.value = '';
    input.trigger('input');
    await flushPromises();

    const error = wrapper.find('#error');
    expect(error.text()).toBeTruthy();

    input.element.value = '123';
    input.trigger('input');
    await flushPromises();

    expect(error.text()).toBeFalsy();
  });
    it('should render cancel command when row is added', () => {
      isEditCommandsTableCell.mockImplementation(() => true);
      isAddedTableRow.mockImplementation(() => true);

      const tree = mount({
        render() {
          return (
            <DxPluginHost>
              <PluginDepsToComponents deps={defaultDeps} />
              <DxTableEditColumn
                {...{ attrs: { ...defaultProps } }}
                messages={{}}
              />
            </DxPluginHost>
          );
        },
      });

      const cancelComponent = findCommandWithId(tree, 'cancel').at(0);
      expect(cancelComponent.vm.$attrs)
        .toMatchObject({ text: 'cancelCommand' });

      cancelComponent.vm.$emit('execute');
      expect(defaultDeps.action.cancelAddedRows.mock.calls[0][0])
        .toEqual({ rowIds: [defaultDeps.template.tableCell.tableRow.rowId] });
    });
    it('should render edit command when showEditCommand is true', () => {
      isEditCommandsTableCell.mockImplementation(() => true);

      const tree = mount({
        render() {
          return (
            <DxPluginHost>
              <PluginDepsToComponents deps={defaultDeps} />
              <DxTableEditColumn
                {...{ attrs: { ...defaultProps } }}
                messages={{}}
                showEditCommand
              />
            </DxPluginHost>
          );
        },
      });

      const commandComponent = tree.find(defaultProps.commandComponent);
      expect(commandComponent.vm.$attrs)
        .toMatchObject({ text: 'editCommand' });

      commandComponent.vm.$emit('execute');
      expect(defaultDeps.action.startEditRows.mock.calls[0][0])
        .toEqual({ rowIds: [defaultDeps.template.tableCell.tableRow.rowId] });
    });
    it('should render edit commands cell on edit-commands column and added row intersection', () => {
      isEditCommandsTableCell.mockImplementation(() => true);

      const tree = mount({
        render() {
          return (
            <DxPluginHost>
              <PluginDepsToComponents deps={defaultDeps} />
              <DxTableEditColumn
                {...{ attrs: { ...defaultProps } }}
                messages={{ addCommand: 'addCommand' }}
              />
            </DxPluginHost>
          );
        },
      });

      expect(isEditCommandsTableCell)
        .toBeCalledWith(
          defaultDeps.template.tableCell.tableRow,
          defaultDeps.template.tableCell.tableColumn,
        );
      expect(tree.find(defaultProps.cellComponent).vm.$attrs)
        .toMatchObject({
          ...defaultDeps.template.tableCell,
          row: defaultDeps.template.tableCell.tableRow.row,
        });
      expect(tree.findAll(defaultProps.commandComponent).length)
        .toEqual(0);
    });
    it('should render add command when showAddCommand is true', () => {
      isHeadingEditCommandsTableCell.mockImplementation(() => true);

      const tree = mount({
        render() {
          return (
            <DxPluginHost>
              <PluginDepsToComponents deps={defaultDeps} />
              <DxTableEditColumn
                {...{ attrs: { ...defaultProps } }}
                showAddCommand
                messages={{ addCommand: 'addCommand' }}
              />
            </DxPluginHost>
          );
        },
      });

      const commandComponent = tree.find(defaultProps.commandComponent);
      expect(commandComponent.vm.$attrs)
        .toMatchObject({ text: 'addCommand' });

      commandComponent.vm.$emit('execute');
      expect(defaultDeps.action.addRow)
        .toBeCalled();
    });
Beispiel #13
0
test('refs with v-for loops', async () => {
  const wrapper = mount(TestComponent, { localVue: Vue });
  wrapper.setData({
    d3: '10'
  });
  wrapper.findAll(InputComponent).at(2).trigger('input');
  await flushPromises();


  expect(wrapper.vm.$validator.errors.first('f7_1')).toBe('The f7_1 confirmation does not match.');
  expect(wrapper.vm.$validator.errors.first('f7_2')).toBe('The f7_2 confirmation does not match.');
  expect(wrapper.vm.$validator.errors.first('f7_3')).toBe('The f7_3 confirmation does not match.');

  wrapper.setData({
    d4: '10'
  });
  wrapper.findAll(InputComponent).at(3).trigger('input');
  wrapper.findAll(InputComponent).at(5).trigger('input');
  wrapper.findAll(InputComponent).at(7).trigger('input');
  await flushPromises();

  expect(wrapper.vm.$validator.errors.has('f7_1')).toBe(false);
  expect(wrapper.vm.$validator.flags.f7_1.valid).toBe(true);
  expect(wrapper.vm.$validator.errors.has('f7_2')).toBe(false);
  expect(wrapper.vm.$validator.flags.f7_2.valid).toBe(true);
  expect(wrapper.vm.$validator.errors.has('f7_3')).toBe(false);
  expect(wrapper.vm.$validator.flags.f7_3.valid).toBe(true);
});
  it('should render detail cell on detail row', () => {
    isDetailTableRow.mockImplementation(() => true);
    isDetailTableCell.mockImplementation(() => true);

    const tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} />
            <DxTableRowDetail
              {...{ attrs: { ...defaultProps } }}
            />
          </DxPluginHost>
        );
      },
    });

    expect(isDetailTableRow)
      .toBeCalledWith(defaultDeps.template.tableCell.tableRow);
    expect(tree.find(defaultProps.cellComponent).vm.$attrs)
      .toMatchObject({
        ...defaultDeps.template.tableCell,
        row: defaultDeps.template.tableCell.tableRow.row,
      });

    expect(tree.find(defaultProps.contentComponent).vm.$attrs)
      .toMatchObject({
        row: defaultDeps.template.tableCell.tableRow.row,
      });
  });
  it('should render detailToggle cell on detail column and user-defined row intersection', () => {
    isDetailToggleTableCell.mockImplementation(() => true);

    const tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} />
            <DxTableRowDetail
              {...{ attrs: { ...defaultProps } }}
            />
          </DxPluginHost>
        );
      },
    });

    expect(isDetailToggleTableCell)
      .toBeCalledWith(
        defaultDeps.template.tableCell.tableRow,
        defaultDeps.template.tableCell.tableColumn,
      );
    expect(tree.find(defaultProps.toggleCellComponent).vm.$attrs)
      .toMatchObject({
        ...defaultDeps.template.tableCell,
        row: defaultDeps.template.tableCell.tableRow.row,
      });
  });
Beispiel #16
0
  test('setting bails prop to false disables fast exit', async () => {
    const wrapper = mount({
      data: () => ({
        value: ''
      }),
      template: `
        <ValidationProvider :bails="false" rules="email|min:3">
          <div slot-scope="{ errors }">
            <input v-model="value" type="text">
            <p v-for="error in errors">{{ error }}</p>
          </div>
        </ValidationProvider>
      `
    }, { localVue: Vue });

    const input = wrapper.find('input');

    input.element.value = '';
    input.trigger('input');
    await flushPromises();

    const errors = wrapper.findAll('p');
    expect(errors).toHaveLength(2);
    expect(errors.at(0).text()).toBe('The {field} field must be a valid email.');
    expect(errors.at(1).text()).toBe('The {field} field must be at least 3 characters.');
  });
Beispiel #17
0
  test('validation can be debounced', async () => {
    const wrapper = mount({
      data: () => ({
        value: ''
      }),
      template: `
        <ValidationProvider rules="required" :debounce="50">
          <div slot-scope="{ errors }">
            <input v-model="value" type="text">
            <p>{{ errors[0] }}</p>
          </div>
        </ValidationProvider>
      `
    }, { localVue: Vue });

    const input = wrapper.find('input');
    const error = wrapper.find('p');

    input.element.value = '';
    input.trigger('input');
    await sleep(40);
    expect(error.text()).toBe('');
    await sleep(10);
    await flushPromises();
    expect(error.text()).toBe(DEFAULT_REQUIRED_MESSAGE);
  });
  it('should render root template', () => {
    const tree = mount({
      render() {
        return (
          <DxPluginHost>
            <GridCore
              {...{ attrs: { ...defaultProps } }}
              rootComponent={{
                render() {
                  return (
                    <div class="root">
                      {this.$slots.default}
                    </div>
                  );
                },
              }}
            />
            <DxTemplate name="header"><div class="header-content" /></DxTemplate>
            <DxTemplate name="body"><div class="body-content" /></DxTemplate>
            <DxTemplate name="footer"><div class="footer-content" /></DxTemplate>
          </DxPluginHost>
        );
      },
    });

    const root = tree.find('.root');
    expect(root.exists()).toBeTruthy();
    expect(root.find('.header-content').exists()).toBeTruthy();
    expect(root.find('.body-content').exists()).toBeTruthy();
    expect(root.find('.footer-content').exists()).toBeTruthy();
  });
Beispiel #19
0
  test('resets validation state using reset method in slot scope data', async () => {
    const wrapper = mount({
      data: () => ({
        value: ''
      }),
      template: `
        <div>
          <ValidationProvider rules="required">
            <div slot-scope="{ errors, reset }">
              <input type="text" v-model="value">
              <span id="error">{{ errors && errors[0] }}</span>
              <button @click="reset">Reset</button>
            </div>
          </ValidationProvider>
        </div>
      `
    }, { localVue: Vue });

    const error = wrapper.find('#error');
    const input = wrapper.find('input');

    expect(error.text()).toBe('');

    input.element.value = '';
    input.trigger('input');
    await flushPromises();

    expect(error.text()).toBe(DEFAULT_REQUIRED_MESSAGE);

    wrapper.find('button').trigger('click');
    await flushPromises();
    expect(error.text()).toBe('');
  });
Beispiel #20
0
test('alias can be set with the ctor options', async () => {
  const wrapper = mount({
    template: `<TextInput v-model="value" v-validate="'required'" name="bar" label="foo"></TextInput>`,
    data: () => ({
      value: ''
    }),
    components: {
      TextInput: {
        template: `<input type="text">`,
        $_veeValidate: {
          name () {
            return this.$attrs.name;
          },
          alias () {
            return this.$attrs.label;
          }
        }
      }
    }
  }, { localVue: Vue });

  await wrapper.vm.$validator.validate();

  expect(wrapper.vm.errors.first('bar')).toBe('The foo field is required.');
});
Beispiel #21
0
  test('triggers validation manually on its children providers using refs', async () => {
    const wrapper = mount({
      data: () => ({
        value: ''
      }),
      template: `
        <ValidationObserver ref="obs">
          <div slot-scope="ctx">

            <ValidationProvider rules="required">

              <div slot-scope="{ errors }">
                <input v-model="value" type="text">
                <span id="error">{{ errors[0] }}</span>
              </div>

            </ValidationProvider>

          </div>
        </ValidationObserver>
      `
    }, { localVue: Vue });

    const error = wrapper.find('#error');
    await flushPromises();
    expect(error.text()).toBe('');

    await wrapper.vm.$refs.obs.validate();

    expect(error.text()).toBe(DEFAULT_REQUIRED_MESSAGE);
  });
    it('can show info about page sizes', () => {
      const tree = mount({
        render() {
          return (
            <PageSizeSelector
              {...{ attrs: defaultProps() }}
            />
          );
        },
      });

      const mobileSelector = tree.findAll('select');
      const mobileSelectorItems = tree.findAll('option');
      const desktopSelectorItems = tree.findAll('li');

      expect(mobileSelector.at(0).element.value).toBe('10');
      expect(mobileSelectorItems).toHaveLength(2);

      expect(mobileSelectorItems.at(0).element.text).toBe('5');
      expect(mobileSelectorItems.at(1).element.text).toBe('10');

      expect(desktopSelectorItems).toHaveLength(2);
      expect(desktopSelectorItems.at(0).element.className).toBe('page-item');
      expect(desktopSelectorItems.at(0).element.textContent).toBe('5');
      expect(desktopSelectorItems.at(1).element.className).toBe('page-item active');
      expect(desktopSelectorItems.at(1).element.textContent).toBe('10');
    });
Beispiel #23
0
  test('collects errors from child providers', async () => {
    const wrapper = mount({
      data: () => ({
        email: '',
        name: ''
      }),
      template: `
        <ValidationObserver ref="obs">
          <div slot-scope="{ errors }">
            <ValidationProvider vid="name" rules="required">
              <div slot-scope="ctx">
                <input v-model="name" type="text">
              </div>
            </ValidationProvider>
            <ValidationProvider vid="email" rules="required">
              <div slot-scope="ctx">
                <input v-model="email" type="text">
              </div>
            </ValidationProvider>

            <p v-for="fieldErrors in errors">{{ fieldErrors[0] }}</p>
          </div>
        </ValidationObserver>
      `
    }, { localVue: Vue });

    await flushPromises();

    await wrapper.vm.$refs.obs.validate();

    const errors = wrapper.findAll('p');
    expect(errors).toHaveLength(2); // 2 fields.
    expect(errors.at(0).text()).toBe(DEFAULT_REQUIRED_MESSAGE);
    expect(errors.at(1).text()).toBe(DEFAULT_REQUIRED_MESSAGE);
  });
Beispiel #24
0
    test('renders', () => {
        const wrapper = mount(NamePattern, {
            localVue,
            propsData: {
                namingPattern: 'S%0SE%0E - %EN',
                namingPresets: [
                    { pattern: '%SN - %Sx%0E - %EN', example: 'Show Name - 2x03 - Ep Name' },
                    { pattern: '%S.N.S%0SE%0E.%E.N', example: 'Show.Name.S02E03.Ep.Name' },
                    { pattern: '%Sx%0E - %EN', example: '2x03 - Ep Name' },
                    { pattern: 'S%0SE%0E - %EN', example: 'S02E03 - Ep Name' },
                    { pattern: 'Season %0S/%S.N.S%0SE%0E.%Q.N-%RG', example: 'Season 02/Show.Name.S02E03.720p.HDTV-RLSGROUP' }
                ],
                type: '',
                multiEpStyle: 1,
                animeNamingType: 0
            },
            methods: {
                checkNaming() {
                    return Promise.resolve();
                },
                testNaming() {
                    return Promise.resolve('MockTestNamingResult');
                }
            }
        });

        expect(wrapper.element).toMatchSnapshot();
    });
  it('should render new row by using rowComponent', () => {
    isAddedTableRow.mockImplementation(() => true);

    const tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} />
            <DxTableEditRow
              {...{ attrs: { ...defaultProps } }}
              rowHeight={120}
            />
          </DxPluginHost>
        );
      },
    });

    expect(isAddedTableRow)
      .toBeCalledWith(defaultDeps.template.tableRow.tableRow);
    expect(tree.find(defaultProps.rowComponent).vm.$attrs)
      .toMatchObject({
        ...defaultDeps.template.tableRow,
        row: defaultDeps.template.tableRow.tableRow.row,
      });
  });
Beispiel #26
0
  test('validates on custom events', async () => {
    const wrapper = mount({
      data: () => ({
        value: ''
      }),
      components: {
        TextInput: {
          props: ['value'],
          template: `<input :value="value" @input="$emit('input', $event.target.value)" @blur="$emit('blur')">`
        }
      },
      template: `
        <div>
          <ValidationProvider rules="required" events="blur">
            <div slot-scope="{ errors }">
              <TextInput v-model="value"></TextInput>
              <span id="error">{{ errors[0] }}</span>
            </div>
          </ValidationProvider>
        </div>
      `
    }, { localVue: Vue });
    const error = wrapper.find('#error');
    const input = wrapper.find('input');

    expect(error.text()).toBe('');
    input.element.value = '';
    input.trigger('input');
    await flushPromises();
    // did not validate.
    expect(error.text()).toBe('');
    input.trigger('blur');
    await flushPromises();
    expect(error.text()).toBe(DEFAULT_REQUIRED_MESSAGE);
  });
  it('can render custom editors', () => {
    isEditTableCell.mockImplementation(() => true);

    const tree = mount({
      render() {
        return (
          <DxPluginHost>
            <PluginDepsToComponents deps={defaultDeps} />
            <DxTableEditRow
              {...{ attrs: { ...defaultProps } }}
              rowHeight={120}
            />
          </DxPluginHost>
        );
      },
    });

    const valueEditorTemplatePlaceholder = tree.findAll(DxTemplatePlaceholder)
      .filter(wrapper => wrapper.vm.name === 'valueEditor').at(0);

    expect(valueEditorTemplatePlaceholder.vm.$attrs)
      .toMatchObject({
        column: defaultDeps.template.tableCell.tableColumn.column,
        row: defaultDeps.template.tableCell.tableRow.row,
        value: defaultDeps.getter.getCellValue(),
      });
    expect(valueEditorTemplatePlaceholder.vm.$listeners)
      .toMatchObject({
        valueChange: expect.any(Function),
      });
  });
Beispiel #28
0
  test('creates HOCs from other components', async () => {
    const InputWithValidation = VeeValidate.withValidation(InputWithoutValidation);

    const wrapper = mount({
      template: `
        <div>
          <InputWithValidation v-model="value" rules="required"></InputWithValidation>
        </div>
      `,
      data: () => ({ value: '' }),
      components: {
        InputWithValidation
      }
    }, { localVue: Vue });

    const error = wrapper.find('#error');
    const input = wrapper.find('#input');

    expect(error.text()).toBe('');
    input.element.value = '';
    input.trigger('input');

    await flushPromises();

    expect(error.text()).toBe(DEFAULT_REQUIRED_MESSAGE);

    input.element.value = 'txt';
    input.trigger('input');
    await flushPromises();
    await flushPromises();
    expect(error.text()).toBe('');
  });
Beispiel #29
0
 it('可以触发 update:selected 事件', (done) => {
   Vue.component('b-sub-nav', SubNav)
   Vue.component('b-nav-item', NavItem)
   const callback = sinon.fake()
   const wrapper = mount(Nav, {
     slots: {
       default: `
         <b-nav-item name="a">aaa</b-nav-item>
         <b-sub-nav name="b">
           <template slot="title">bbb</template>
           <b-nav-item name="b1">b1</b-nav-item>
           <b-nav-item name="b2">b2</b-nav-item>
           <b-nav-item name="b3">b3</b-nav-item>
         </b-sub-nav>
         <b-nav-item name="c">ccc</b-nav-item>
       `,
     },
     propsData: {
       selected: ['c']
     },
     listeners: {
       'update:selected': callback
     }
   })
   wrapper.find('[data-name="c"]').trigger('click')
   expect(callback).to.have.been.calledWith(['c'])
   done()
 })
Beispiel #30
0
  test('validates lazy models', async () => {
    const wrapper = mount({
      data: () => ({
        value: ''
      }),
      template: `
        <ValidationProvider rules="required">
          <div slot-scope="{ errors }">
            <input v-model.lazy="value" type="text">
            <span id="error">{{ errors[0] }}</span>
          </div>
        </ValidationProvider>
      `
    }, { localVue: Vue });

    const input = wrapper.find('input');
    const error = wrapper.find('#error');

    input.element.value = '';
    input.trigger('input');
    await flushPromises();
    // did not validate on input.
    expect(error.text()).toBe('');

    input.trigger('change');
    await flushPromises();
    // validation triggered on change.
    expect(error.text()).toBe(DEFAULT_REQUIRED_MESSAGE);

    input.element.value = 'text';
    input.trigger('change');
    await flushPromises();
    // validation triggered on change.
    expect(error.text()).toBe('');
  });