1
0
mirror of synced 2025-01-31 06:41:41 +03:00

Updates vue-test-utils to 1.0.2

This commit is contained in:
Justin Schroeder 2020-05-14 16:08:54 -04:00
commit fdcf7b3dbf
21 changed files with 1313 additions and 838 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

11
dist/snow.css vendored
View File

@ -121,6 +121,7 @@
width: 1em;
height: 1em;
border-radius: 1em;
border: 0;
background-color: #41b883;
margin-top: calc(-.5em + 2px); }
.formulate-input[data-classification='slider'] input::-moz-range-thumb {
@ -129,6 +130,7 @@
width: 1em;
height: 1em;
border-radius: 1em;
border: 0;
background-color: #41b883;
margin-top: calc(-.5em + 2px); }
.formulate-input[data-classification='slider'] input::-ms-thumb {
@ -137,6 +139,7 @@
width: 1em;
height: 1em;
border-radius: 1em;
border: 0;
background-color: #41b883;
margin-top: calc(-.5em + 2px); }
.formulate-input[data-classification='slider'] input::-webkit-slider-runnable-track {
@ -147,6 +150,14 @@
border-radius: 3px;
margin: 0;
padding: 0; }
.formulate-input[data-classification='slider'] input::-moz-range-track {
appearance: none;
width: 100%;
height: 4px;
background-color: #efefef;
border-radius: 3px;
margin: 0;
padding: 0; }
.formulate-input[data-classification='textarea'] textarea {
appearance: none;
border-radius: .3em;

6
dist/snow.min.css vendored

File diff suppressed because one or more lines are too long

1808
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "@braid/vue-formulate",
"version": "2.2.8",
"version": "2.2.12",
"description": "The easiest way to build forms in Vue.",
"main": "dist/formulate.umd.js",
"module": "dist/formulate.esm.js",
@ -8,9 +8,6 @@
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=11"
},
"browser": {
"./sfc": "src/Formulate.js"
},
@ -45,9 +42,9 @@
},
"homepage": "https://www.vueformulate.com",
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/plugin-transform-modules-commonjs": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/core": "^7.9.6",
"@babel/plugin-transform-modules-commonjs": "^7.9.6",
"@babel/preset-env": "^7.9.6",
"@rollup/plugin-buble": "^0.21.3",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-node-resolve": "^7.1.3",
@ -55,11 +52,11 @@
"@vue/cli-plugin-eslint": "^4.3.1",
"@vue/cli-service": "^4.3.1",
"@vue/component-compiler-utils": "^3.1.2",
"@vue/test-utils": "^1.0.0-beta.33",
"@vue/test-utils": "^1.0.2",
"autoprefixer": "^9.7.6",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^25.3.0",
"babel-jest": "^25.5.1",
"cssnano": "^4.1.10",
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
@ -69,19 +66,19 @@
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.2.3",
"flush-promises": "^1.0.2",
"jest": "^25.3.0",
"jest": "^25.5.4",
"jest-vue-preprocessor": "^1.7.1",
"node-sass": "^4.13.1",
"postcss": "^7.0.27",
"postcss-cli": "^7.1.0",
"node-sass": "^4.14.1",
"postcss": "^7.0.30",
"postcss-cli": "^7.1.1",
"rollup": "^1.32.1",
"rollup-plugin-auto-external": "^2.0.0",
"rollup-plugin-internal": "^1.0.4",
"rollup-plugin-multi-input": "^1.1.1",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-vue": "^5.1.6",
"rollup-plugin-vue": "^5.1.7",
"sass-loader": "^8.0.2",
"typescript": "^3.8.3",
"typescript": "^3.9.2",
"vue": "^2.6.11",
"vue-jest": "^3.0.5",
"vue-runtime-helpers": "^1.1.2",

View File

@ -72,9 +72,11 @@ class Formulate {
uploadJustCompleteDuration: 1000,
errorHandler: (err) => err,
plugins: [ en ],
locales: {}
locales: {},
idPrefix: 'formulate-'
}
this.registry = new Map()
this.idRegistry = {}
}
/**
@ -94,6 +96,21 @@ class Formulate {
}
}
/**
* Produce a deterministically generated id based on the sequence by which it
* was requested. This should be *theoretically* the same SSR as client side.
* However, SSR and deterministic ids can be very challenging, so this
* implementation is open to community review.
*/
nextId (vm) {
const path = vm.$route && vm.$route.path || false
const pathPrefix = path ? vm.$route.path.replace(/[\/\\.\s]/g, '-') : 'global';
if (!Object.prototype.hasOwnProperty.call(this.idRegistry, pathPrefix)) {
this.idRegistry[pathPrefix] = 0;
}
return `${this.options.idPrefix}${pathPrefix}-${++this.idRegistry[pathPrefix]}`
}
/**
* Given a set of options, apply them to the pre-existing options.
* @param {Object} extendWith

View File

@ -80,8 +80,7 @@
<script>
import context from './libs/context'
import { shallowEqualObjects, parseRules, snakeToCamel, arrayify, has } from './libs/utils'
import nanoid from 'nanoid/non-secure'
import { shallowEqualObjects, parseRules, snakeToCamel, has, arrayify } from './libs/utils'
export default {
name: 'FormulateInput',
@ -238,7 +237,7 @@ export default {
},
data () {
return {
defaultId: nanoid(9),
defaultId: this.$formulate.nextId(this),
localAttributes: {},
localErrors: [],
internalModelProxy: this.getInitialValue(),
@ -314,7 +313,7 @@ export default {
this.updateLocalAttributes(this.$attrs)
this.performValidation()
},
destroyed () {
beforeDestroy () {
if (!this.disableErrors && typeof this.removeErrorObserver === 'function') {
this.removeErrorObserver(this.setErrors)
}

View File

@ -60,21 +60,21 @@ export default {
optionsWithContext () {
const {
// The following are a list of items to pull out of the context object
options,
labelPosition,
attributes: { id, ...groupApplicableAttributes },
classification,
blurHandler,
performValidation,
hasValidationErrors,
getValidationErrors,
validationErrors,
setErrors,
visibleValidationErrors,
classification,
component,
getValidationErrors,
hasLabel,
slotComponents,
hasValidationErrors,
isSubField,
labelPosition,
options,
performValidation,
setErrors,
slotComponents,
validationErrors,
visibleValidationErrors,
...context
} = this.context
return this.options.map(option => this.groupItemContext(
@ -100,7 +100,9 @@ export default {
},
groupItemContext (context, option, groupAttributes) {
const optionAttributes = {}
const ctx = Object.assign({}, context, option, groupAttributes, optionAttributes)
const ctx = Object.assign({}, context, option, groupAttributes, optionAttributes, !context.hasGivenName ? {
name: true
} : {})
return ctx
}
}

View File

@ -17,6 +17,7 @@ export default {
errors: this.explicitErrors,
formShouldShowErrors: this.formShouldShowErrors,
getValidationErrors: this.getValidationErrors.bind(this),
hasGivenName: this.hasGivenName,
hasLabel: (this.label && this.classification !== 'button'),
hasValidationErrors: this.hasValidationErrors.bind(this),
help: this.help,
@ -46,6 +47,7 @@ export default {
},
// Used in sub-context
nameOrFallback,
hasGivenName,
typeContext,
elementAttributes,
logicalLabelPosition,
@ -106,11 +108,17 @@ function typeContext () {
*/
function elementAttributes () {
const attrs = Object.assign({}, this.localAttributes)
// pass the ID prop through to the root element
if (this.id) {
attrs.id = this.id
} else {
attrs.id = this.defaultId
}
// pass an explicitly given name prop through to the root element
if (this.hasGivenName) {
attrs.name = this.name
}
return attrs
}
@ -204,6 +212,13 @@ function nameOrFallback () {
return this.name
}
/**
* determine if an input has a user-defined name
*/
function hasGivenName () {
return typeof this.name !== 'boolean'
}
/**
* Determines if this formulate element is v-modeled or not.
*/

View File

@ -28,13 +28,11 @@ describe('FormulateForm', () => {
const wrapper = mount(FormulateForm, {
slots: {
default: "<button type='submit' />"
},
methods: {
formSubmitted
}
})
const spy = jest.spyOn(wrapper.vm, 'formSubmitted')
wrapper.find('form').trigger('submit')
expect(formSubmitted).toBeCalled()
expect(spy).toHaveBeenCalled()
})
it('registers its subcomponents', () => {
@ -45,6 +43,27 @@ describe('FormulateForm', () => {
expect(wrapper.vm.registry.keys()).toEqual(['subinput1', 'subinput2'])
})
it('deregisters a subcomponents', async () => {
const wrapper = mount({
data () {
return {
active: true
}
},
template: `
<FormulateForm>
<FormulateInput v-if="active" type="text" name="subinput1" />
<FormulateInput type="checkbox" name="subinput2" />
</FormulateForm>
`
})
await flushPromises()
expect(wrapper.findComponent(FormulateForm).vm.registry.keys()).toEqual(['subinput1', 'subinput2'])
wrapper.setData({ active: false })
await flushPromises()
expect(wrapper.findComponent(FormulateForm).vm.registry.keys()).toEqual(['subinput2'])
})
it('can set a fields initial value', async () => {
const wrapper = mount(FormulateForm, {
propsData: { formulateValue: { testinput: 'has initial value' } },
@ -81,7 +100,7 @@ describe('FormulateForm', () => {
propsData: { formulateValue: { box1: true } },
slots: { default: '<FormulateInput type="checkbox" name="box1" />' }
})
expect(wrapper.find('input[type="checkbox"]').is(':checked')).toBe(true)
expect(wrapper.find('input[type="checkbox"]').element.checked).toBeTruthy()
});
it('can set initial unchecked attribute on single checkboxes', () => {
@ -89,7 +108,7 @@ describe('FormulateForm', () => {
propsData: { formulateValue: { box1: false } },
slots: { default: '<FormulateInput type="checkbox" name="box1" />' }
})
expect(wrapper.find('input[type="checkbox"]').is(':checked')).toBe(false)
expect(wrapper.find('input[type="checkbox"]').element.checked).toBeFalsy()
});
it('can set checkbox initial value with options', async () => {
@ -326,7 +345,7 @@ describe('FormulateForm', () => {
await flushPromises()
expect(wrapper.findAll('.formulate-form-errors').length).toBe(1)
// Ensure that we moved the position of the errors
expect(wrapper.find('h1 + *').is('.formulate-form-errors')).toBe(true)
expect(wrapper.find('h1 + *').element.classList.contains('formulate-form-errors')).toBe(true)
})
it('allows rendering multiple locations', async () => {
@ -443,10 +462,10 @@ describe('FormulateForm', () => {
`
})
await flushPromises()
expect(wrapper.find(FormulateForm).vm.errorObservers.length).toBe(1)
expect(wrapper.findComponent(FormulateForm).vm.errorObservers.length).toBe(1)
wrapper.setData({ hasField: false })
await flushPromises()
expect(wrapper.find(FormulateForm).vm.errorObservers.length).toBe(0)
expect(wrapper.findComponent(FormulateForm).vm.errorObservers.length).toBe(0)
})
it('emits correct validation event on entry', async () => {
@ -494,4 +513,26 @@ describe('FormulateForm', () => {
hasErrors: false
})
})
// it('removes field data when that field is de-registered', async () => {
// const wrapper = mount({
// template: `
// <FormulateForm
// v-model="formData"
// >
// <FormulateInput type="text" name="foo" value="abc123" />
// <FormulateInput type="checkbox" name="bar" v-if="formData.foo !== 'bar'" :value="true" />
// </FormulateForm>
// `,
// data () {
// return {
// formData: {}
// }
// }
// })
// await flushPromises()
// wrapper.find('input[type="text"]').setValue('bar')
// await flushPromises()
// expect(wrapper.vm.formData).toEqual({ bar: true })
// })
})

View File

@ -113,7 +113,7 @@ describe('FormulateInput', () => {
value: 'bar'
} })
await flushPromises()
expect(wrapper.contains(FormulateInputBox)).toBe(true)
expect(wrapper.findComponent(FormulateInputBox).exists()).toBe(true)
})
it('emits correct validation event', async () => {

View File

@ -11,12 +11,22 @@ Vue.use(Formulate)
describe('FormulateInputBox', () => {
it('renders a box element when type "checkbox" ', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox' } })
expect(wrapper.contains(FormulateInputBox)).toBe(true)
expect(wrapper.findComponent(FormulateInputBox).exists()).toBe(true)
})
it('renders a box element when type "radio"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'radio' } })
expect(wrapper.contains(FormulateInputBox)).toBe(true)
expect(wrapper.findComponent(FormulateInputBox).exists()).toBe(true)
})
it('passes an explicitly given name prop through to the root radio elements', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'radio', name: 'foo', options: {a: '1', b: '2'} } })
expect(wrapper.findAll('input[name="foo"]')).toHaveLength(2)
})
it('passes an explicitly given name prop through to the root checkbox elements', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox', name: 'foo', options: {a: '1', b: '2'} } })
expect(wrapper.findAll('input[name="foo"]')).toHaveLength(2)
})
it('box inputs properly process options object in context library', () => {
@ -26,12 +36,12 @@ describe('FormulateInputBox', () => {
it('renders a group when type "checkbox" with options', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox', options: {a: '1', b: '2'} } })
expect(wrapper.contains(FormulateInputGroup)).toBe(true)
expect(wrapper.findComponent(FormulateInputGroup).exists()).toBe(true)
})
it('renders a group when type "radio" with options', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'radio', options: {a: '1', b: '2'} } })
expect(wrapper.contains(FormulateInputGroup)).toBe(true)
expect(wrapper.findComponent(FormulateInputGroup).exists()).toBe(true)
})
it('defaults labelPosition to "after" when type "checkbox"', () => {
@ -52,7 +62,7 @@ describe('FormulateInputBox', () => {
it('generates ids if not provided when type "radio"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'radio', options: {a: '1', b: '2'} } })
expect(wrapper.findAll('input[type="radio"]').is('[id]')).toBe(true)
expect(wrapper.find('input[type="radio"]').attributes().id).toBeTruthy()
})
it('additional context does not bleed through to attributes with type "radio" and options', () => {
@ -72,14 +82,14 @@ describe('FormulateInputBox', () => {
it('does not use the value attribute to be checked', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox', value: '123' } })
expect(wrapper.find('input').is(':checked')).toBe(false)
expect(wrapper.find('input').element.checked).toBe(false)
})
it('uses the checked attribute to be checked', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox', checked: 'true' } })
await flushPromises()
await wrapper.vm.$nextTick()
expect(wrapper.find('input').is(':checked')).toBe(true)
expect(wrapper.find('input').element.checked).toBe(true)
})
it('uses the value attribute to select "type" radio when using options', async () => {
@ -204,7 +214,15 @@ describe('FormulateInputBox', () => {
it('renders no boxes when options array is empty', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox', options: [] } })
expect(wrapper.contains(FormulateInputGroup)).toBe(true)
expect(wrapper.findComponent(FormulateInputGroup).exists()).toBe(true)
expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false)
})
it('renders multiple labels both with correct id', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox', label: 'VueFormulate FTW!'} })
const id = wrapper.find('input[type="checkbox"]').attributes('id')
const labelIds = wrapper.findAll('label').wrappers.map(label => label.attributes('for'));
expect(labelIds.length).toBe(2);
expect(labelIds.filter(labelId => labelId === id).length).toBe(2);
})
})

View File

@ -11,12 +11,12 @@ describe('FormulateInputButton', () => {
it('renders a button element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'button' } })
expect(wrapper.contains(FormulateInputButton)).toBe(true)
expect(wrapper.findComponent(FormulateInputButton).exists()).toBe(true)
})
it('renders a button element when type submit', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'submit' } })
expect(wrapper.contains(FormulateInputButton)).toBe(true)
expect(wrapper.findComponent(FormulateInputButton).exists()).toBe(true)
})
it('uses value as highest priority content', () => {
@ -103,3 +103,13 @@ describe('FormulateInputButton', () => {
})
})
it('passes an explicitly given name prop through to the root element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'button', name: 'foo' } })
expect(wrapper.find('button[name="foo"]').exists()).toBe(true)
})
it('additional context does not bleed through to button input attributes', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'button' } } )
expect(Object.keys(wrapper.find('button').attributes())).toEqual(["type", "id"])
})

View File

@ -12,12 +12,12 @@ describe('FormulateInputFile', () => {
it('type "file" renders a file element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'file' } })
expect(wrapper.contains(FormulateInputFile)).toBe(true)
expect(wrapper.findComponent(FormulateInputFile).exists()).toBe(true)
})
it('type "image" renders a file element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'image' } })
expect(wrapper.contains(FormulateInputFile)).toBe(true)
expect(wrapper.findComponent(FormulateInputFile).exists()).toBe(true)
})
it('forces an error-behavior live mode when upload-behavior is live and it has content', () => {
@ -37,6 +37,16 @@ describe('FormulateInputFile', () => {
expect(file.attributes('data-has-preview')).toBe('true')
})
it('passes an explicitly given name prop through to the root element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'image', name: 'foo' } })
expect(wrapper.find('input[name="foo"]').exists()).toBe(true)
})
it('additional context does not bleed through to file input attributes', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'image' } } )
expect(Object.keys(wrapper.find('input[type="file"]').attributes())).toEqual(["type", "id"])
})
/**
* ===========================================================================
* Currently there appears to be no way to properly mock upload data in

View File

@ -28,7 +28,7 @@ describe('FormulateInputGroup', () => {
default: '<FormulateInput type="text" name="persona" />'
}
})
expect(wrapper.find(FormulateRepeatableProvider).vm.registry.has('persona')).toBeTruthy()
expect(wrapper.findComponent(FormulateRepeatableProvider).vm.registry.has('persona')).toBeTruthy()
})
it('is not repeatable by default', async () => {
@ -156,7 +156,7 @@ describe('FormulateInputGroup', () => {
submit
}
})
const form = wrapper.find(FormulateForm)
const form = wrapper.findComponent(FormulateForm)
await form.vm.formSubmitted()
expect(submit.mock.calls.length).toBe(0);
})
@ -188,7 +188,7 @@ describe('FormulateInputGroup', () => {
submit
}
})
const form = wrapper.find(FormulateForm)
const form = wrapper.findComponent(FormulateForm)
await form.vm.formSubmitted()
expect(submit.mock.calls.length).toBe(1);
})
@ -208,7 +208,7 @@ describe('FormulateInputGroup', () => {
</FormulateForm>
`
})
const form = wrapper.find(FormulateForm)
const form = wrapper.findComponent(FormulateForm)
await form.vm.formSubmitted()
expect(wrapper.find('[data-classification="text"] .formulate-input-error').exists()).toBe(true);
})
@ -228,7 +228,7 @@ describe('FormulateInputGroup', () => {
</FormulateForm>
`
})
const form = wrapper.find(FormulateForm)
const form = wrapper.findComponent(FormulateForm)
await form.vm.formSubmitted()
// Click the add more button
wrapper.find('button[type="button"]').trigger('click')
@ -251,7 +251,7 @@ describe('FormulateInputGroup', () => {
</FormulateForm>
`
})
const form = wrapper.find(FormulateForm)
const form = wrapper.findComponent(FormulateForm)
await form.vm.formSubmitted()
// Click the add more button
wrapper.find('button[type="button"]').trigger('click')
@ -374,7 +374,7 @@ describe('FormulateInputGroup', () => {
}
}
})
const form = wrapper.find(FormulateForm)
const form = wrapper.findComponent(FormulateForm)
await form.vm.formSubmitted()
expect(wrapper.find('[data-classification="group"] > .formulate-input-errors').exists()).toBe(false)
})
@ -416,7 +416,7 @@ describe('FormulateInputGroup', () => {
}
})
await flushPromises();
expect(wrapper.find(FormulateGrouping).vm.items).toEqual([{}])
expect(wrapper.findComponent(FormulateGrouping).vm.items).toEqual([{}])
})
it('allows repeatable groups to initialize with an empty array', async () => {
@ -438,6 +438,6 @@ describe('FormulateInputGroup', () => {
}
})
await flushPromises();
expect(wrapper.find(FormulateGrouping).vm.items).toEqual([])
expect(wrapper.findComponent(FormulateGrouping).vm.items).toEqual([])
})
})

View File

@ -10,7 +10,7 @@ Vue.use(Formulate)
describe('FormulateInputSelect', () => {
it('renders select input when type is "select"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'select' } })
expect(wrapper.contains(FormulateInputSelect)).toBe(true)
expect(wrapper.findComponent(FormulateInputSelect).exists()).toBe(true)
})
it('renders select options when options object is passed', () => {
@ -42,4 +42,14 @@ describe('FormulateInputSelect', () => {
expect(options.length).toBe(1)
expect(options.at(0).attributes('disabled')).toBeTruthy()
})
it('passes an explicitly given name prop through to the root element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'select', options: [], name: 'foo' } })
expect(wrapper.find('select[name="foo"]').exists()).toBe(true)
})
it('additional context does not bleed through to text select attributes', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'select' } } )
expect(Object.keys(wrapper.find('select').attributes())).toEqual(["id"])
})
})

View File

@ -13,7 +13,7 @@ Vue.use(Formulate)
describe('FormulateInputSlider', () => {
it('renders range input when type is "range"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'range' } })
expect(wrapper.contains(FormulateInputSlider)).toBe(true)
expect(wrapper.findComponent(FormulateInputSlider).exists()).toBe(true)
})
it('does not show value if the show-value prop is not set', () => {
@ -25,4 +25,14 @@ describe('FormulateInputSlider', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'range', showValue: 'true', value: '15', min: '0', max: '100' } })
expect(wrapper.find('.formulate-input-element-range-value').text()).toBe('15')
})
it('passes an explicitly given name prop through to the root element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'range', name: 'foo' } })
expect(wrapper.find('input[name="foo"]').exists()).toBe(true)
})
it('additional context does not bleed through to range input attributes', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'range' } } )
expect(Object.keys(wrapper.find('input[type="range"]').attributes())).toEqual(["type", "id"])
})
})

View File

@ -15,62 +15,62 @@ Vue.use(Formulate)
describe('FormulateInputText', () => {
it('renders text input when type is "text"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders search input when type is "search"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'search' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders email input when type is "email"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'email' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders number input when type is "number"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'number' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders color input when type is "color"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'color' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders date input when type is "date"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'date' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders month input when type is "month"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'month' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders password input when type is "password"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'password' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders tel input when type is "tel"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'tel' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders time input when type is "time"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'time' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders url input when type is "url"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'url' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders week input when type is "week"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'week' } })
expect(wrapper.contains(FormulateInputText)).toBe(true)
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
/**
@ -83,6 +83,26 @@ describe('FormulateInputText', () => {
expect(wrapper.find(`input[id="${wrapper.vm.context.attributes.id}"]`).exists()).toBe(true)
})
it('passes an explicitly given name prop through to the root text element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', name: 'foo' } })
expect(wrapper.find('input[name="foo"]').exists()).toBe(true)
})
it('passes an explicitly given name prop through to the root textarea element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'textarea', name: 'foo' } })
expect(wrapper.find('textarea[name="foo"]').exists()).toBe(true)
})
it('additional context does not bleed through to text input attributes', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } } )
expect(Object.keys(wrapper.find('input[type="text"]').attributes())).toEqual(["type", "id"])
})
it('additional context does not bleed through to textarea input attributes', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'textarea' } } )
expect(Object.keys(wrapper.find('textarea').attributes())).toEqual(["id"])
})
it('doesnt automatically add a label', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
expect(wrapper.find('label').exists()).toBe(false)
@ -130,15 +150,15 @@ describe('FormulateInputText', () => {
`
})
await flushPromises()
const firstContext = wrapper.find({ref: "first"}).vm.context
const secondContext = wrapper.find({ref: "second"}).vm.context
const firstContext = wrapper.findComponent({ref: "first"}).vm.context
const secondContext = wrapper.findComponent({ref: "second"}).vm.context
wrapper.find('input').setValue('new value')
await flushPromises()
expect(firstContext).toBeTruthy()
expect(wrapper.vm.valueA === 'new value').toBe(true)
expect(wrapper.vm.valueB === 'second value').toBe(true)
expect(wrapper.find({ref: "first"}).vm.context === firstContext).toBe(false)
expect(wrapper.find({ref: "second"}).vm.context === secondContext).toBe(true)
expect(wrapper.findComponent({ref: "first"}).vm.context === firstContext).toBe(false)
expect(wrapper.findComponent({ref: "second"}).vm.context === secondContext).toBe(true)
})
it('uses the v-model value as the initial value', () => {

View File

@ -168,6 +168,7 @@
width: 1em;
height: 1em;
border-radius: 1em;
border: 0;
background-color: $formulate-green;
margin-top: calc(-.5em + 2px);
}
@ -197,6 +198,10 @@
&::-webkit-slider-runnable-track {
@include track;
}
&::-moz-range-track {
@include track;
}
}
}