Skip to content

Commit

Permalink
Merge branch 'main' into taefi/remove-install-auto-signal-tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
taefi authored Oct 22, 2024
2 parents 7c510cd + e8eb0a8 commit 3ae5ef3
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -338,17 +338,15 @@ private NodeDependencies scanTypes(List<SignatureModel> types,
private NodeDependencies scanTypeSignature(TypeSignatureNode node,
NodeDependencies nodeDependencies) {
var signature = node.getSource();
var referredTypes = getReferredTypes(signature);

if (signature instanceof ClassRefSignatureModel) {
var classModel = (ClassRefSignatureModel) signature;
// Create dependencies for type arguments
nodeDependencies = nodeDependencies.appendChildNodes(classModel
.getTypeArguments().stream().map(TypeSignatureNode::of));
for (var i = 0; i < referredTypes.size(); i++) {
var referredType = referredTypes.get(i);
nodeDependencies = nodeDependencies.appendChildNodes(
Stream.of(TypeSignatureNode.of(referredType, i)));
}

var referredTypes = getReferredTypes(signature);
return nodeDependencies.appendChildNodes(
referredTypes.stream().map(TypeSignatureNode::of));
return nodeDependencies;
}

private String signatureToTypeString(SignatureModel type) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.vaadin.hilla.parser.plugins.backbone.nodes;

import java.util.List;
import java.util.Objects;
import java.util.function.UnaryOperator;

import com.vaadin.hilla.parser.core.AbstractNode;
Expand All @@ -13,15 +14,18 @@
public final class TypeSignatureNode
extends AbstractNode<SignatureModel, Schema<?>> implements TypedNode {
private final List<AnnotationInfoModel> annotations;
private final Integer position;

private TypeSignatureNode(SignatureModel source, Schema<?> target,
List<AnnotationInfoModel> annotations) {
List<AnnotationInfoModel> annotations, Integer position) {
super(source, target);
this.annotations = annotations;
this.position = position;
}

private TypeSignatureNode(SignatureModel source, Schema<?> target) {
this(source, target, source.getAnnotations());
private TypeSignatureNode(SignatureModel source, Schema<?> target,
Integer position) {
this(source, target, source.getAnnotations(), position);
}

public List<AnnotationInfoModel> getAnnotations() {
Expand All @@ -40,11 +44,45 @@ public TypedNode processType(UnaryOperator<SignatureModel> typeProcessor) {
}

return new TypeSignatureNode(typeProcessor.apply(getSource()),
getTarget(), annotations);
getTarget(), annotations, position);
}

@Nonnull
static public TypeSignatureNode of(@Nonnull SignatureModel source) {
return new TypeSignatureNode(source, new Schema<>());
return new TypeSignatureNode(source, new Schema<>(), null);
}

@Nonnull
static public TypeSignatureNode of(@Nonnull SignatureModel source,
int position) {
return new TypeSignatureNode(source, new Schema<>(), position);
}

@Override
public boolean equals(Object o) {
boolean eq = super.equals(o);

if (eq) {
var other = (TypeSignatureNode) o;
eq = Objects.equals(position, other.position);
}

return eq;
}

@Override
public int hashCode() {
return super.hashCode() ^ Objects.hashCode(position);
}

@Override
public String toString() {
var str = super.toString();

if (position != null) {
str += "[" + position + "]";
}

return str;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,14 @@ public GenericsBareRefEntity<List<Float>> getBareEntityList(
GenericsBareRefEntity<List<Float>> ref) {
return ref;
}

public record GenericsRecord<T1,T2>(
T1 first, T2 second)
{
}

public GenericsRecord<String, String> getRecord(
GenericsRecord<String, String> record) {
return record;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,72 @@
}
}
},
"/GenericsBareEntityEndpoint/getRecord": {
"post": {
"tags": ["GenericsBareEntityEndpoint"],
"operationId": "GenericsBareEntityEndpoint_getRecord_POST",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"record": {
"nullable": true,
"anyOf": [
{
"$ref": "#/components/schemas/com.vaadin.hilla.parser.plugins.backbone.generics.GenericsBareEntityEndpoint$GenericsRecord"
}
],
"x-type-arguments": {
"allOf": [
{
"type": "string",
"nullable": true
},
{
"type": "string",
"nullable": true
}
]
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"nullable": true,
"anyOf": [
{
"$ref": "#/components/schemas/com.vaadin.hilla.parser.plugins.backbone.generics.GenericsBareEntityEndpoint$GenericsRecord"
}
],
"x-type-arguments": {
"allOf": [
{
"type": "string",
"nullable": true
},
{
"type": "string",
"nullable": true
}
]
}
}
}
}
}
}
}
},
"/GenericsExtendedEndpoint/getMap": {
"post": {
"tags": ["GenericsExtendedEndpoint"],
Expand Down Expand Up @@ -718,11 +784,11 @@
}
],
"x-type-arguments": {
"allOf" : [
"allOf": [
{
"type" : "object",
"nullable" : true,
"x-type-variable" : "T"
"type": "object",
"nullable": true,
"x-type-variable": "T"
}
]
}
Expand All @@ -741,6 +807,25 @@
}
}
},
"com.vaadin.hilla.parser.plugins.backbone.generics.GenericsBareEntityEndpoint$GenericsRecord": {
"type": "object",
"properties": {
"first": {
"type": "object",
"nullable": true,
"x-type-variable": "T1"
},
"second": {
"type": "object",
"nullable": true,
"x-type-variable": "T2"
}
},
"x-type-parameters": [
"T1",
"T2"
]
},
"com.vaadin.hilla.parser.plugins.backbone.generics.GenericsExtendedRefEntity": {
"type": "object",
"properties": {
Expand All @@ -762,7 +847,7 @@
}
}
},
"com.vaadin.hilla.parser.plugins.backbone.generics.ConcreteType" : {
"com.vaadin.hilla.parser.plugins.backbone.generics.ConcreteType": {
"type": "object"
}
}
Expand Down
11 changes: 11 additions & 0 deletions packages/ts/lit-form/src/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,17 @@ export class VaadinFieldStrategy<T = any, E extends FieldElement<T> = FieldEleme
this.element.invalid = this.#invalid;
}
}

override checkValidity(): boolean {
// Ignore the `invalid` property of the Vaadin component to avoid
// reading the component's internal old validation state and validate
// the element based on the current state.
const isElementInvalid = this.element.invalid;
this.element.invalid = false;
const valid = super.checkValidity();
this.element.invalid = isElementInvalid;
return valid;
}
}

export class GenericFieldStrategy<T = any, E extends FieldElement<T> = FieldElement<T>> extends AbstractFieldStrategy<
Expand Down
65 changes: 65 additions & 0 deletions packages/ts/lit-form/test/Field.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { customElement, query } from 'lit/decorators.js';
import { html, unsafeStatic } from 'lit/static-html.js';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import isLength from 'validator/es/lib/isLength.js';
import type { BinderNode } from '../src/BinderNode.js';
// API to test
import {
Expand Down Expand Up @@ -496,6 +497,14 @@ describe('@vaadin/hilla-lit-form', () => {
}
}

@customElement('validity-vaadin-element-tag')
class ValidityVaadinElement extends AnyVaadinElement {
invalid = false;
checkValidity() {
return !this.invalid;
}
}

beforeEach(() => {
getFieldStrategySpy.resetHistory();
render(nothing, div);
Expand Down Expand Up @@ -630,6 +639,62 @@ describe('@vaadin/hilla-lit-form', () => {
});
});

it(`should ignore old invalid state of element for checkValidity`, async () => {
const stringModel = binder.model.fieldString;
const binderNode = binder.for(stringModel);
binderNode.value = '';
await resetBinderNodeValidation(binderNode);

const renderElement = () => {
render(
html`
<validity-vaadin-element-tag ${field(stringModel)}"></validity-vaadin-element-tag>`,
div,
);
return div.firstElementChild as HTMLInputElement & {
invalid?: boolean;
required?: boolean;
errorMessage?: string;
selectedItems?: any;
};
};

binderNode.validators = [
{
message: 'too-long',
validate: (value) => isLength(value, { max: 3 }),
},
];

await binderNode.validate();
let element = renderElement();

const currentStrategy: FieldStrategy = getFieldStrategySpy.lastCall.returnValue;
expect(currentStrategy instanceof VaadinFieldStrategy).to.be.true;

expect(binderNode.invalid).to.be.false;
expect(element.invalid).to.be.false;
expect(element.errorMessage).to.be.undefined;

element.value = 'test';
element.dispatchEvent(new CustomEvent('input', { bubbles: true, cancelable: false, composed: true }));
await binderNode.validate();
element = renderElement();

expect(element.invalid).to.be.true;
expect(binderNode.invalid).to.be.true;
expect(element.errorMessage).to.be.equal('too-long');

element.value = 'te';
element.dispatchEvent(new CustomEvent('input', { bubbles: true, cancelable: false, composed: true }));
await binderNode.validate();
element = renderElement();

expect(binderNode.invalid).to.be.false;
expect(element.invalid).to.be.false;
expect(element.errorMessage).to.be.empty;
});

[
{ tag: 'input', type: 'checkbox' },
{ tag: 'input', type: 'radio' },
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@
<gentyref.version>1.2.0.vaadin1</gentyref.version>
<jsr305.version>3.0.2</jsr305.version>
<jna.version>5.14.0</jna.version>
<swagger.core.version>2.2.22</swagger.core.version>
<swagger.models.version>2.2.22</swagger.models.version>
<swagger.core.version>2.2.24</swagger.core.version>
<swagger.models.version>2.2.24</swagger.models.version>
<swagger.parser.v3.version>2.1.15</swagger.parser.v3.version>
<jackson.version>2.17.2</jackson.version>
<junit.version>5.10.1</junit.version>
Expand Down

0 comments on commit 3ae5ef3

Please sign in to comment.