+ * If enabled, the test field is visible only when the selected operator is
+ * {@link RegularExpressionOperator#ADVANCED}.
+ *
+ *
+ * @param enabled {@code true} to enable the test field, {@code false} to disable it
+ */
+ public void setTestFieldEnabled(boolean enabled) {
+ testFieldEnabled = enabled;
+ testField.setVisible(
+ testFieldEnabled && operatorField.getValue() == RegularExpressionOperator.ADVANCED);
+ }
+
+ /**
+ * Checks whether the test field is enabled.
+ *
+ * @return {@code true} if the test field is enabled, otherwise {@code false}
+ */
+ public boolean isTestFieldEnabled() {
+ return testFieldEnabled;
+ }
+
+ /**
+ * Sets the regular expression operator for this component.
+ *
+ * @param operator the {@link RegularExpressionOperator} to set
+ */
+ public void setOperator(RegularExpressionOperator operator) {
+ operatorField.setValue(operator);
+ }
+
+ /**
+ * Sets the test strings for validation using a variable-length argument array.
+ *
+ * The provided strings will be set as selectable test cases in the test field.
+ *
+ * @param strings the test strings to set
+ */
+ public void setTestStrings(String... strings) {
+ testField.setItems(strings);
+ }
+
+ /**
+ * Sets the test strings for validation using a collection.
+ *
+ * The provided strings will be set as selectable test cases in the test field.
+ *
+ * @param strings the collection of test strings to set
+ */
+ public void setTestStrings(Collection strings) {
+ testField.setItems(strings);
+ }
+
+}
diff --git a/src/main/java/com/flowingcode/vaadin/addons/regex/RegularExpressionOperator.java b/src/main/java/com/flowingcode/vaadin/addons/regex/RegularExpressionOperator.java
new file mode 100644
index 0000000..5085536
--- /dev/null
+++ b/src/main/java/com/flowingcode/vaadin/addons/regex/RegularExpressionOperator.java
@@ -0,0 +1,42 @@
+/*-
+ * #%L
+ * Regular Expression Field Add-on
+ * %%
+ * Copyright (C) 2025 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.regex;
+
+/**
+ * Defines the available operators for creating regular expressions in a
+ * {@link RegularExpressionField}.
+ *
+ * @author Javier Godoy
+ */
+public enum RegularExpressionOperator {
+
+ /** Matches strings that start with a given substring. */
+ STARTS_WITH,
+
+ /** Matches strings that end with a given substring. */
+ ENDS_WITH,
+
+ /** Matches strings that contain a given substring. */
+ CONTAINS,
+
+ /** Enables advanced custom regular expressions with validation support. */
+ ADVANCED;
+
+}
diff --git a/src/main/java/com/flowingcode/vaadin/addons/regex/RegularExpressionTestField.java b/src/main/java/com/flowingcode/vaadin/addons/regex/RegularExpressionTestField.java
new file mode 100644
index 0000000..62bb5ab
--- /dev/null
+++ b/src/main/java/com/flowingcode/vaadin/addons/regex/RegularExpressionTestField.java
@@ -0,0 +1,131 @@
+/*-
+ * #%L
+ * Regular Expression Field Add-on
+ * %%
+ * Copyright (C) 2025 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.regex;
+
+import com.vaadin.flow.component.ClickEvent;
+import com.vaadin.flow.component.ComponentEventListener;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.button.ButtonVariant;
+import com.vaadin.flow.component.dependency.CssImport;
+import com.vaadin.flow.component.grid.Grid;
+import com.vaadin.flow.component.grid.GridVariant;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.icon.VaadinIcon;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.data.binder.Binder;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+/**
+ * A component for managing a list of words with real-time validation.
+ *
+ * This component allows users to add and remove words while providing immediate feedback on their
+ * validity based on a predefined regular expression pattern. When a word matches the given pattern,
+ * it is displayed with a green background; otherwise, it is marked with red.
+ *
+ * @author Javier Godoy
+ */
+@SuppressWarnings("serial")
+@CssImport("./styles/fc-regex-test-strings.css")
+public final class RegularExpressionTestField extends Div {
+
+ private Pattern pattern;
+
+ private final Grid grid;
+
+ public RegularExpressionTestField() {
+ grid = new Grid<>();
+ grid.setClassName("fc-regex-test-strings");
+ Binder binder = new Binder<>();
+ grid.getEditor().setBinder(binder);
+ grid.getEditor().setBuffered(false);
+ grid.addThemeVariants(GridVariant.LUMO_COMPACT);
+
+ TextField editField = new TextField();
+ editField.setWidthFull();
+ grid.addColumn(item -> item[0]).setEditorComponent(editField);
+ binder.forField(editField).bind(item -> item[0], (item, value) -> item[0] = value);
+
+ grid.addComponentColumn(item -> newButton(VaadinIcon.MINUS_CIRCLE, ev -> {
+ grid.getListDataView().removeItem(item);
+ })).setFooter(newButton(VaadinIcon.PLUS_CIRCLE, ev -> {
+ if (grid.getListDataView().getItems().noneMatch(item -> item[0].isEmpty())) {
+ String[] item = new String[] {""};
+ grid.getListDataView().addItem(item);
+ grid.getEditor().editItem(item);
+ }
+ })).setFlexGrow(0).setWidth("40px");
+
+ grid.setAllRowsVisible(true);
+ grid.addItemClickListener(ev -> grid.getEditor().editItem(ev.getItem()));
+ editField.addBlurListener(ev -> {
+ grid.getEditor().closeEditor();
+ });
+ grid.getEditor().addCloseListener(ev -> {
+ if (ev.getItem()[0].isEmpty()) {
+ grid.getListDataView().removeItem(ev.getItem());
+ }
+ });
+ grid.getEditor().addOpenListener(ev -> {
+ editField.focus();
+ });
+ add(grid);
+
+ grid.setPartNameGenerator(item -> {
+ if (pattern != null) {
+ return pattern.matcher(item[0]).matches() ? "match-success" : "match-fail";
+ } else {
+ return null;
+ }
+ });
+
+ }
+
+ private Button newButton(VaadinIcon icon,
+ ComponentEventListener> clickListener) {
+ var button = new Button(icon.create(), clickListener);
+ button.addThemeVariants(ButtonVariant.LUMO_SMALL);
+ return button;
+ }
+
+ private void setItems(Stream items) {
+ grid.setItems(items.map(s -> new String[] {s}).toArray(String[][]::new));
+ }
+
+ public void setItems(String... items) {
+ setItems(Stream.of(items));
+ }
+
+ public void setItems(Collection items) {
+ setItems(items.stream());
+ }
+
+ public void setPattern(RegularExpression regex) {
+ setPattern(Optional.ofNullable(regex).map(RegularExpression::getPattern).orElse(null));
+ }
+
+ public void setPattern(Pattern pattern) {
+ this.pattern = pattern;
+ grid.getDataProvider().refreshAll();
+ }
+
+}
diff --git a/src/main/resources/META-INF/VAADIN/package.properties b/src/main/resources/META-INF/VAADIN/package.properties
deleted file mode 100644
index c66616f..0000000
--- a/src/main/resources/META-INF/VAADIN/package.properties
+++ /dev/null
@@ -1 +0,0 @@
-vaadin.allowed-packages=com.flowingcode
diff --git a/src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java b/src/main/resources/META-INF/frontend/styles/fc-regex-test-strings.css
similarity index 51%
rename from src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java
rename to src/main/resources/META-INF/frontend/styles/fc-regex-test-strings.css
index c9ec694..3bb7f34 100644
--- a/src/main/java/com/flowingcode/vaadin/addons/template/TemplateAddon.java
+++ b/src/main/resources/META-INF/frontend/styles/fc-regex-test-strings.css
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Regular Expression Field Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2025 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,16 +17,24 @@
* limitations under the License.
* #L%
*/
+.fc-regex-test-strings vaadin-grid-cell-content {
+ padding-top: 0;
+ padding-bottom: 0;
+ text-overflow: clip;
+}
-package com.flowingcode.vaadin.addons.template;
+.fc-regex-test-strings vaadin-button {
+ margin: 0;
+ padding: 0;
+ background: transparent;
+}
-import com.vaadin.flow.component.Tag;
-import com.vaadin.flow.component.dependency.JsModule;
-import com.vaadin.flow.component.dependency.NpmPackage;
-import com.vaadin.flow.component.html.Div;
+.fc-regex-test-strings::part(match-success) {
+ color: var(--lumo-success-color);
+ background-color: var(--lumo-success-color-10pct);
+}
-@SuppressWarnings("serial")
-@NpmPackage(value = "@polymer/paper-input", version = "3.2.1")
-@JsModule("@polymer/paper-input/paper-input.js")
-@Tag("paper-input")
-public class TemplateAddon extends Div {}
+.fc-regex-test-strings::part(match-fail) {
+ color: var(--lumo-error-color);
+ background-color: var(--lumo-error-color-10pct);
+}
diff --git a/src/main/resources/META-INF/frontend/styles/static_addon_styles b/src/main/resources/META-INF/frontend/styles/static_addon_styles
deleted file mode 100644
index c2a6ed1..0000000
--- a/src/main/resources/META-INF/frontend/styles/static_addon_styles
+++ /dev/null
@@ -1 +0,0 @@
-Place add-on shareable styles in this folder
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/static_addon_resources b/src/main/resources/META-INF/resources/static_addon_resources
deleted file mode 100644
index 70832cc..0000000
--- a/src/main/resources/META-INF/resources/static_addon_resources
+++ /dev/null
@@ -1 +0,0 @@
-Place static add-on resources in this folder
\ No newline at end of file
diff --git a/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java b/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java
index b84172e..ef7288b 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/DemoLayout.java
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Regular Expression Field Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2025 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java b/src/test/java/com/flowingcode/vaadin/addons/regex/DemoView.java
similarity index 84%
rename from src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java
rename to src/test/java/com/flowingcode/vaadin/addons/regex/DemoView.java
index a600c9d..494f3e5 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/template/DemoView.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/regex/DemoView.java
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Regular Expression Field Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2025 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,7 +18,7 @@
* #L%
*/
-package com.flowingcode.vaadin.addons.template;
+package com.flowingcode.vaadin.addons.regex;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEnterEvent;
@@ -31,6 +31,7 @@ public class DemoView extends VerticalLayout implements BeforeEnterObserver {
@Override
public void beforeEnter(BeforeEnterEvent event) {
- event.forwardTo(TemplateDemoView.class);
+ event.forwardTo(RegularExpressionFieldView.class);
}
+
}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/regex/RegularExpressionFieldDemo.java b/src/test/java/com/flowingcode/vaadin/addons/regex/RegularExpressionFieldDemo.java
new file mode 100644
index 0000000..c258135
--- /dev/null
+++ b/src/test/java/com/flowingcode/vaadin/addons/regex/RegularExpressionFieldDemo.java
@@ -0,0 +1,53 @@
+/*-
+ * #%L
+ * Regular Expression Field Add-on
+ * %%
+ * Copyright (C) 2025 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.regex;
+
+import com.flowingcode.vaadin.addons.demo.DemoSource;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.router.PageTitle;
+import com.vaadin.flow.router.Route;
+import java.util.Optional;
+import java.util.regex.Pattern;
+
+@DemoSource
+@PageTitle("Regular Expression Field Add-on Demo")
+@SuppressWarnings("serial")
+@Route(value = "demo", layout = RegularExpressionFieldView.class)
+public class RegularExpressionFieldDemo extends Div {
+
+ public RegularExpressionFieldDemo() {
+ RegularExpressionField field = new RegularExpressionField();
+ field.setTestFieldEnabled(true);
+ field.setValue(RegularExpression.of(Pattern.compile("he.*[od]")));
+ field.setTestStrings("hello", "hero", "help", "held", "world", "gold");
+ add(field);
+ // #if vaadin eq 0
+ Div div1 = new Div();
+ Div div2 = new Div();
+ add(div1, div2);
+ field.addValueChangeListener(
+ ev -> {
+ div1.setText(Optional.ofNullable(ev.getValue()).map(Object::toString).orElse(""));
+ div2.setText(Optional.ofNullable(ev.getValue()).map(RegularExpression::getPattern)
+ .map(Pattern::pattern).orElse(""));
+ });
+ // #endif
+ }
+}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java b/src/test/java/com/flowingcode/vaadin/addons/regex/RegularExpressionFieldView.java
similarity index 70%
rename from src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java
rename to src/test/java/com/flowingcode/vaadin/addons/regex/RegularExpressionFieldView.java
index 1954535..b06788b 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemoView.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/regex/RegularExpressionFieldView.java
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Regular Expression Field Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2025 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,7 @@
* limitations under the License.
* #L%
*/
-package com.flowingcode.vaadin.addons.template;
+package com.flowingcode.vaadin.addons.regex;
import com.flowingcode.vaadin.addons.DemoLayout;
import com.flowingcode.vaadin.addons.GithubLink;
@@ -27,12 +27,12 @@
@SuppressWarnings("serial")
@ParentLayout(DemoLayout.class)
-@Route("template")
-@GithubLink("https://github.com/FlowingCode/AddonStarter24")
-public class TemplateDemoView extends TabbedDemo {
+@Route("regular-expression-field")
+@GithubLink("https://github.com/FlowingCode/RegularExpressionField")
+public class RegularExpressionFieldView extends TabbedDemo {
- public TemplateDemoView() {
- addDemo(TemplateDemo.class);
+ public RegularExpressionFieldView() {
+ addDemo(RegularExpressionFieldDemo.class);
setSizeFull();
}
}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/regex/test/RegularExpressionTest.java b/src/test/java/com/flowingcode/vaadin/addons/regex/test/RegularExpressionTest.java
new file mode 100644
index 0000000..561b3c5
--- /dev/null
+++ b/src/test/java/com/flowingcode/vaadin/addons/regex/test/RegularExpressionTest.java
@@ -0,0 +1,131 @@
+/*-
+ * #%L
+ * Regular Expression Field Add-on
+ * %%
+ * Copyright (C) 2025 Flowing Code
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.flowingcode.vaadin.addons.regex.test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import com.flowingcode.vaadin.addons.regex.RegularExpression;
+import com.flowingcode.vaadin.addons.regex.RegularExpressionOperator;
+import org.junit.Test;
+
+public class RegularExpressionTest {
+
+ @Test
+ public void testAdvanced() {
+ var r = new RegularExpression(RegularExpressionOperator.ADVANCED, ".*");
+ assertThat(r.getPattern().pattern(), equalTo(".*"));
+ assertThat(r.getInput(), equalTo(".*"));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+
+ @Test
+ public void testStartsWith() {
+ var r = new RegularExpression(RegularExpressionOperator.STARTS_WITH, "[");
+ assertThat(r.getPattern().pattern(), equalTo("\\[.*"));
+ assertThat(r.getInput(), equalTo("["));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+
+ @Test
+ public void testEndsWith() {
+ var r = new RegularExpression(RegularExpressionOperator.ENDS_WITH, "[");
+ assertThat(r.getPattern().pattern(), equalTo(".*\\["));
+ assertThat(r.getInput(), equalTo("["));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+
+ @Test
+ public void testContains() {
+ var r = new RegularExpression(RegularExpressionOperator.CONTAINS, "[");
+ assertThat(r.getPattern().pattern(), equalTo(".*\\[.*"));
+ assertThat(r.getInput(), equalTo("["));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+
+ @Test
+ public void testShort() {
+ var r = new RegularExpression(RegularExpressionOperator.CONTAINS, "a");
+ assertThat(r.getPattern().pattern(), equalTo(".*a.*"));
+ assertThat(r.getInput(), equalTo("a"));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+
+ @Test
+ public void testQuoteE() {
+ var r = new RegularExpression(RegularExpressionOperator.CONTAINS, ".........\\E");
+ assertThat(r.getPattern().pattern(), equalTo(".*\\Q.........\\E\\\\E\\Q\\E.*"));
+ assertThat(r.getInput(), equalTo(".........\\E"));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+
+ @Test
+ public void testQuoteMode1() {
+ var r = new RegularExpression(RegularExpressionOperator.CONTAINS, "...");
+ assertThat(r.getPattern().pattern(), equalTo(".*\\.\\.\\..*"));
+ assertThat(r.getInput(), equalTo("..."));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+
+ @Test
+ public void testQuoteMode2() {
+ var r = new RegularExpression(RegularExpressionOperator.CONTAINS, "....");
+ assertThat(r.getPattern().pattern(), equalTo(".*\\Q....\\E.*"));
+ assertThat(r.getInput(), equalTo("...."));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+
+ @Test
+ public void testQuoteChars() {
+ for (char c : ".?+*[({$^|\\".toCharArray()) {
+ var r = new RegularExpression(RegularExpressionOperator.CONTAINS, Character.toString(c));
+ assertThat(r.getPattern().pattern(), equalTo(".*\\" + c + ".*"));
+ assertThat(r.getInput(), equalTo(Character.toString(c)));
+
+ var q = RegularExpression.of(r.getPattern());
+ assertThat(q, equalTo(r));
+ assertThat(q.getPattern().pattern(), equalTo(r.getPattern().pattern()));
+ }
+ }
+
+}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java b/src/test/java/com/flowingcode/vaadin/addons/regex/test/SerializationTest.java
similarity index 85%
rename from src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java
rename to src/test/java/com/flowingcode/vaadin/addons/regex/test/SerializationTest.java
index 1ee78c3..559dfcd 100644
--- a/src/test/java/com/flowingcode/vaadin/addons/template/test/SerializationTest.java
+++ b/src/test/java/com/flowingcode/vaadin/addons/regex/test/SerializationTest.java
@@ -1,15 +1,15 @@
/*-
* #%L
- * Template Add-on
+ * Regular Expression Field Add-on
* %%
- * Copyright (C) 2024 Flowing Code
+ * Copyright (C) 2025 Flowing Code
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,9 +17,9 @@
* limitations under the License.
* #L%
*/
-package com.flowingcode.vaadin.addons.template.test;
+package com.flowingcode.vaadin.addons.regex.test;
-import com.flowingcode.vaadin.addons.template.TemplateAddon;
+import com.flowingcode.vaadin.addons.regex.RegularExpressionField;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -44,7 +44,7 @@ private void testSerializationOf(Object obj) throws IOException, ClassNotFoundEx
@Test
public void testSerialization() throws ClassNotFoundException, IOException {
try {
- testSerializationOf(new TemplateAddon());
+ testSerializationOf(new RegularExpressionField());
} catch (Exception e) {
Assert.fail("Problem while testing serialization: " + e.getMessage());
}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java b/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java
deleted file mode 100644
index 5f6e6ee..0000000
--- a/src/test/java/com/flowingcode/vaadin/addons/template/TemplateDemo.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.flowingcode.vaadin.addons.template;
-
-import com.flowingcode.vaadin.addons.demo.DemoSource;
-import com.vaadin.flow.component.html.Div;
-import com.vaadin.flow.router.PageTitle;
-import com.vaadin.flow.router.Route;
-
-@DemoSource
-@PageTitle("Template Add-on Demo")
-@SuppressWarnings("serial")
-@Route(value = "demo", layout = TemplateDemoView.class)
-public class TemplateDemo extends Div {
-
- public TemplateDemo() {
- add(new TemplateAddon());
- }
-}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java b/src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java
deleted file mode 100644
index 1f7749b..0000000
--- a/src/test/java/com/flowingcode/vaadin/addons/template/it/AbstractViewTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*-
- * #%L
- * Template Add-on
- * %%
- * Copyright (C) 2024 Flowing Code
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-package com.flowingcode.vaadin.addons.template.it;
-
-import com.vaadin.testbench.ScreenshotOnFailureRule;
-import com.vaadin.testbench.TestBench;
-import com.vaadin.testbench.parallel.ParallelTest;
-import io.github.bonigarcia.wdm.WebDriverManager;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.openqa.selenium.chrome.ChromeDriver;
-
-/**
- * Base class for ITs
- *
- * The tests use Chrome driver (see pom.xml for integration-tests profile) to run integration
- * tests on a headless Chrome. If a property {@code test.use .hub} is set to true, {@code
- * AbstractViewTest} will assume that the TestBench test is running in a CI environment. In order to
- * keep the this class light, it makes certain assumptions about the CI environment (such as
- * available environment variables). It is not advisable to use this class as a base class for you
- * own TestBench tests.
- *
- *
To learn more about TestBench, visit Vaadin TestBench.
- */
-public abstract class AbstractViewTest extends ParallelTest {
- private static final int SERVER_PORT = 8080;
-
- private final String route;
-
- @Rule public ScreenshotOnFailureRule rule = new ScreenshotOnFailureRule(this, true);
-
- public AbstractViewTest() {
- this("");
- }
-
- protected AbstractViewTest(String route) {
- this.route = route;
- }
-
- @BeforeClass
- public static void setupClass() {
- WebDriverManager.chromedriver().setup();
- }
-
- @Override
- @Before
- public void setup() throws Exception {
- if (isUsingHub()) {
- super.setup();
- } else {
- setDriver(TestBench.createDriver(new ChromeDriver()));
- }
- getDriver().get(getURL(route));
- }
-
- /**
- * Returns deployment host name concatenated with route.
- *
- * @return URL to route
- */
- private static String getURL(String route) {
- return String.format("http://%s:%d/%s", getDeploymentHostname(), SERVER_PORT, route);
- }
-
- /** Property set to true when running on a test hub. */
- private static final String USE_HUB_PROPERTY = "test.use.hub";
-
- /**
- * Returns whether we are using a test hub. This means that the starter is running tests in
- * Vaadin's CI environment, and uses TestBench to connect to the testing hub.
- *
- * @return whether we are using a test hub
- */
- private static boolean isUsingHub() {
- return Boolean.TRUE.toString().equals(System.getProperty(USE_HUB_PROPERTY));
- }
-
- /**
- * If running on CI, get the host name from environment variable HOSTNAME
- *
- * @return the host name
- */
- private static String getDeploymentHostname() {
- return isUsingHub() ? System.getenv("HOSTNAME") : "localhost";
- }
-}
diff --git a/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java b/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java
deleted file mode 100644
index 0e5f164..0000000
--- a/src/test/java/com/flowingcode/vaadin/addons/template/it/ViewIT.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * #%L
- * Template Add-on
- * %%
- * Copyright (C) 2024 Flowing Code
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-package com.flowingcode.vaadin.addons.template.it;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-
-import com.vaadin.testbench.TestBenchElement;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeDiagnosingMatcher;
-import org.junit.Test;
-
-public class ViewIT extends AbstractViewTest {
-
- private Matcher hasBeenUpgradedToCustomElement =
- new TypeSafeDiagnosingMatcher() {
-
- @Override
- public void describeTo(Description description) {
- description.appendText("a custom element");
- }
-
- @Override
- protected boolean matchesSafely(TestBenchElement item, Description mismatchDescription) {
- String script = "let s=arguments[0].shadowRoot; return !!(s&&s.childElementCount)";
- if (!item.getTagName().contains("-")) {
- return true;
- }
- if ((Boolean) item.getCommandExecutor().executeScript(script, item)) {
- return true;
- } else {
- mismatchDescription.appendText(item.getTagName() + " ");
- mismatchDescription.appendDescriptionOf(is(not(this)));
- return false;
- }
- }
- };
-
- @Test
- public void componentWorks() {
- TestBenchElement element = $("paper-input").first();
- assertThat(element, hasBeenUpgradedToCustomElement);
- }
-}
diff --git a/src/test/resources/META-INF/frontend/styles/shared-styles.css b/src/test/resources/META-INF/frontend/styles/shared-styles.css
deleted file mode 100644
index 6680e2d..0000000
--- a/src/test/resources/META-INF/frontend/styles/shared-styles.css
+++ /dev/null
@@ -1 +0,0 @@
-/*Demo styles*/
\ No newline at end of file
diff --git a/src/test/resources/META-INF/resources/static_addon_test_resources b/src/test/resources/META-INF/resources/static_addon_test_resources
deleted file mode 100644
index b68f527..0000000
--- a/src/test/resources/META-INF/resources/static_addon_test_resources
+++ /dev/null
@@ -1 +0,0 @@
-Place static addon test resources in this folder
\ No newline at end of file