From 6e920e8821a0dcc5059659ca3b7af7ca88082564 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 15 Jun 2018 09:09:40 -0400 Subject: [PATCH] failing test for #1104 --- src/validate/html/validateElement.ts | 25 ++++-- .../binding-input-radio-checked/_config.js | 81 +++++++++++++++++++ .../binding-input-radio-checked/main.html | 15 ++++ 3 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 test/runtime/samples/binding-input-radio-checked/_config.js create mode 100644 test/runtime/samples/binding-input-radio-checked/main.html diff --git a/src/validate/html/validateElement.ts b/src/validate/html/validateElement.ts index 002120e721..7ffe9ea83f 100644 --- a/src/validate/html/validateElement.ts +++ b/src/validate/html/validateElement.ts @@ -80,6 +80,15 @@ export default function validateElement( let hasTransition: boolean; let hasAnimation: boolean; + function checkElement(attribute, bindingName, nodeName) { + if (node.name !== nodeName) { + validator.error(attribute, { + code: `invalid-binding`, + message: `'${bindingName}' is not a valid binding on <${nodeName}> elements` + }); + } + } + node.attributes.forEach((attribute: Node) => { if (attribute.type === 'Ref') { if (!refs.has(attribute.name)) refs.set(attribute.name, []); @@ -115,18 +124,24 @@ export default function validateElement( } else { checkTypeAttribute(validator, node); } - } else if (name === 'checked' || name === 'indeterminate') { - if (node.name !== 'input') { + } else if (name === 'checked') { + checkElement(attribute, name, 'input'); + const type = checkTypeAttribute(validator, node); + + if (type !== 'checkbox' && type !== 'radio') { validator.error(attribute, { code: `invalid-binding`, - message: `'${name}' is not a valid binding on <${node.name}> elements` + message: `'checked' binding can only be used with or ` }); } + } else if (name === 'indeterminate') { + checkElement(attribute, name, 'input'); + const type = checkTypeAttribute(validator, node); - if (checkTypeAttribute(validator, node) !== 'checkbox') { + if (type !== 'checkbox') { validator.error(attribute, { code: `invalid-binding`, - message: `'${name}' binding can only be used with ` + message: `'indeterminate' binding can only be used with ` }); } } else if (name === 'group') { diff --git a/test/runtime/samples/binding-input-radio-checked/_config.js b/test/runtime/samples/binding-input-radio-checked/_config.js new file mode 100644 index 0000000000..85193ffc3f --- /dev/null +++ b/test/runtime/samples/binding-input-radio-checked/_config.js @@ -0,0 +1,81 @@ +export default { + data: { + foo: false, + bar: true, + baz: false, + }, + + html: ` + + + + + + +

foo false

+

bar true

+

baz false

`, + + test(assert, component, target, window) { + const inputs = target.querySelectorAll('input'); + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, true); + assert.equal(inputs[2].checked, false); + + const event = new window.Event('change'); + + inputs[0].checked = true; + inputs[0].dispatchEvent(event); + + assert.htmlEqual(target.innerHTML, ` + + + + + + +

foo true

+

bar false

+

baz false

+ `); + + assert.equal(inputs[0].checked, true); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, false); + + component.set({ baz: true }); + assert.equal(inputs[0].checked, false); + assert.equal(inputs[1].checked, false); + assert.equal(inputs[2].checked, true); + + assert.htmlEqual(target.innerHTML, ` + + + + + + +

foo false

+

bar false

+

baz true

+ `); + }, +}; diff --git a/test/runtime/samples/binding-input-radio-checked/main.html b/test/runtime/samples/binding-input-radio-checked/main.html new file mode 100644 index 0000000000..dc4022dd55 --- /dev/null +++ b/test/runtime/samples/binding-input-radio-checked/main.html @@ -0,0 +1,15 @@ + + + + + + +

foo {foo}

+

bar {bar}

+

baz {baz}

\ No newline at end of file