From 6a761c8b0d3201b088f65c4689c1fc02bf7e0aa5 Mon Sep 17 00:00:00 2001 From: VasilevNStas Date: Fri, 14 Aug 2026 23:48:47 +0300 Subject: [PATCH 1/4] feat(#1271): run Java lints from YAML packs via lint key --- .../java/org/eolang/lints/LtByXslTest.java | 63 +++++++-- src/test/java/org/eolang/lints/XtLint.java | 123 ++++++++++++++++++ .../ascii-only/catches-cyrillic-comment.yaml | 12 ++ .../catches-unknown-lint.yaml | 12 ++ .../reserved-name/allows-custom-name.yaml | 12 ++ 5 files changed, 210 insertions(+), 12 deletions(-) create mode 100644 src/test/java/org/eolang/lints/XtLint.java create mode 100644 src/test/resources/org/eolang/lints/packs/single/ascii-only/catches-cyrillic-comment.yaml create mode 100644 src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml create mode 100644 src/test/resources/org/eolang/lints/packs/single/reserved-name/allows-custom-name.yaml diff --git a/src/test/java/org/eolang/lints/LtByXslTest.java b/src/test/java/org/eolang/lints/LtByXslTest.java index 144bef92c..639d7c461 100644 --- a/src/test/java/org/eolang/lints/LtByXslTest.java +++ b/src/test/java/org/eolang/lints/LtByXslTest.java @@ -108,6 +108,10 @@ void lintsInMultipleThreads() { @ParameterizedTest @ClasspathSource(value = "org/eolang/lints/packs/single/", glob = "**.yaml") void testsAllLintsByEo(final String yaml, final String pack) { + org.junit.jupiter.api.Assumptions.assumeTrue( + !((Map) new org.yaml.snakeyaml.Yaml().load(yaml)).containsKey("lint"), + String.format("Pack '%s' is a Java lint pack", pack) + ); MatcherAssert.assertThat( String.format( "Pack '%s' doesn't tell the story as expected", @@ -125,6 +129,32 @@ void testsAllLintsByEo(final String yaml, final String pack) { ); } + @SuppressWarnings("JTCOP.RuleNotContainsTestWord") + @Execution(ExecutionMode.CONCURRENT) + @ParameterizedTest + @ClasspathSource(value = "org/eolang/lints/packs/single/", glob = "**.yaml") + void testsAllLintsByLintName(final String yaml, final String pack) { + org.junit.jupiter.api.Assumptions.assumeTrue( + ((Map) new org.yaml.snakeyaml.Yaml().load(yaml)).containsKey("lint"), + String.format("Pack '%s' has no lint key", pack) + ); + MatcherAssert.assertThat( + String.format( + "Pack '%s' doesn't tell the story as expected", + pack + ), + new fixtures.XtDefects( + new XtSticky( + new XtLint( + yaml, + eo -> new EoProgram(pack, new InputOf(eo)).parse() + ) + ) + ), + new XtoryMatcher(new DefectsMatcher()) + ); + } + @Test void returnsMotive() throws Exception { MatcherAssert.assertThat( @@ -480,22 +510,31 @@ private static Predicate yamls() { */ @SuppressWarnings("StreamResourceLeak") private static boolean hasMatchingXsl(final Path yaml) { + final boolean result; try { - return Files.walk(Paths.get("src/main/resources/org/eolang/lints")) - .filter(Files::isRegularFile) - .filter(path -> path.toString().endsWith(".xsl")) - .map(path -> path.getParent().getFileName().toString()).anyMatch( - group -> Files.exists( - Paths.get("src/main/resources/org/eolang/lints/").resolve(group).resolve( - String.format( - "%s.xsl", - yaml.getParent().getFileName().toString() - ) + if (((Map) new org.yaml.snakeyaml.Yaml().load( + new String(Files.readAllBytes(yaml), java.nio.charset.StandardCharsets.UTF_8) + )).containsKey("lint")) { + result = true; + } else { + result = Files.walk(Paths.get("src/main/resources/org/eolang/lints")) + .filter(Files::isRegularFile) + .filter(path -> path.toString().endsWith(".xsl")) + .map(path -> path.getParent().getFileName().toString()).anyMatch( + group -> Files.exists( + Paths.get("src/main/resources/org/eolang/lints/") + .resolve(group).resolve( + String.format( + "%s.xsl", + yaml.getParent().getFileName().toString() + ) + ) ) - ) - ); + ); + } } catch (final IOException ex) { throw new IllegalStateException(ex); } + return result; } } diff --git a/src/test/java/org/eolang/lints/XtLint.java b/src/test/java/org/eolang/lints/XtLint.java new file mode 100644 index 000000000..4c0ab79c9 --- /dev/null +++ b/src/test/java/org/eolang/lints/XtLint.java @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com + * SPDX-License-Identifier: MIT + */ +package org.eolang.lints; + +import com.jcabi.xml.XML; +import com.yegor256.xsline.Shift; +import com.yegor256.xsline.Xsline; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import org.eolang.xax.Xtory; +import org.xembly.Directives; +import org.xembly.Xembler; + +/** + * A story that runs a Java-implemented lint by its name. + * Reads the {@code lint} key from the pack YAML and applies + * the resolved {@link Lint} to the input, producing a + * {@code } document. + * @since 1.0 + */ +public final class XtLint implements Xtory { + + /** + * Original story. + */ + private final Xtory origin; + + /** + * Ctor. + * @param yaml YAML pack + * @param parser Parser + */ + public XtLint(final String yaml, final Xtory.Parser parser) { + this(new org.eolang.xax.XtYaml(yaml, parser)); + } + + /** + * Ctor. + * @param origin Original story + */ + private XtLint(final Xtory origin) { + this.origin = origin; + } + + @Override + public Map map() { + return this.origin.map(); + } + + @Override + public XML before() { + return this.origin.before(); + } + + @Override + public XML after() { + return this.xsline().pass(this.before()); + } + + @Override + public Xsline xsline() { + return new Xsline( + new Shift() { + @Override + public String uid() { + return XtLint.this.name(); + } + + @Override + public XML apply(final int position, final XML xml) { + return XtLint.this.defects(xml); + } + } + ); + } + + @Override + public Collection asserts() { + return this.origin.asserts(); + } + + /** + * Lint name from the YAML map. + * @return Lint name + */ + private String name() { + return String.valueOf(this.origin.map().get("lint")); + } + + /** + * Run the lint and serialize defects into XML. + * @param xml Input XMIR + * @return Defects document + */ + private XML defects(final XML xml) { + final Directives dirs = new Directives().add("defects"); + try { + for (final Lint lint : new PkMono()) { + if (lint.name().equals(this.name())) { + for (final Defect defect : lint.defects(xml)) { + dirs.add("defect") + .attr("line", defect.line()) + .attr("severity", defect.severity().mnemo()) + .set(defect.text()) + .up(); + } + break; + } + } + } catch (final IOException ex) { + throw new IllegalStateException( + String.format("Failed to run lint %s", this.name()), + ex + ); + } + return new com.jcabi.xml.XMLDocument( + new Xembler(dirs).xmlQuietly() + ); + } +} diff --git a/src/test/resources/org/eolang/lints/packs/single/ascii-only/catches-cyrillic-comment.yaml b/src/test/resources/org/eolang/lints/packs/single/ascii-only/catches-cyrillic-comment.yaml new file mode 100644 index 000000000..5d0bcf528 --- /dev/null +++ b/src/test/resources/org/eolang/lints/packs/single/ascii-only/catches-cyrillic-comment.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com +# SPDX-License-Identifier: MIT +--- +lint: ascii-only +asserts: + - /defects[count(defect[@severity='warning'])=1] +document: | + + + привет + + diff --git a/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml b/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml new file mode 100644 index 000000000..8aa40b8aa --- /dev/null +++ b/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com +# SPDX-License-Identifier: MIT +--- +lint: incorrect-unlint +asserts: + - /defects[count(defect[@severity='error'])=1] +input: | + +unlint non-existent-lint-name:5 + +version 0.0.0 + + # Foo. + [] > foo diff --git a/src/test/resources/org/eolang/lints/packs/single/reserved-name/allows-custom-name.yaml b/src/test/resources/org/eolang/lints/packs/single/reserved-name/allows-custom-name.yaml new file mode 100644 index 000000000..380aa342e --- /dev/null +++ b/src/test/resources/org/eolang/lints/packs/single/reserved-name/allows-custom-name.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com +# SPDX-License-Identifier: MIT +--- +lint: reserved-name +asserts: + - /defects[count(defect)=0] +document: | + + + + + From d52220cc530c4fdb908784f02ab0879cc75b2bde Mon Sep 17 00:00:00 2001 From: VasilevNStas Date: Fri, 14 Aug 2026 23:55:23 +0300 Subject: [PATCH 2/4] feat(#1271): syntax-version packs as demo --- .../single/syntax-version/allows-older-syntax.yaml | 12 ++++++++++++ .../single/syntax-version/catches-newer-syntax.yaml | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml create mode 100644 src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml diff --git a/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml b/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml new file mode 100644 index 000000000..c782f18e3 --- /dev/null +++ b/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com +# SPDX-License-Identifier: MIT +--- +lint: syntax-version +asserts: + - /defects[count(defect)=0] +input: | + +syntax 0.0.1 + +version 0.0.0 + + # Foo. + [] > foo diff --git a/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml b/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml new file mode 100644 index 000000000..9f1f9bc3b --- /dev/null +++ b/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright (c) 2016-2026 Objectionary.com +# SPDX-License-Identifier: MIT +--- +lint: syntax-version +asserts: + - /defects[count(defect[@severity='error'])=1] +input: | + +syntax 999.0.0 + +version 0.0.0 + + # Foo. + [] > foo From ab67d7d2edfa26202f4f300619a488d722fdba95 Mon Sep 17 00:00:00 2001 From: VasilevNStas Date: Sat, 15 Aug 2026 00:12:16 +0300 Subject: [PATCH 3/4] fix(#1271): use document packs for meta-based lints, filter lint packs in EO test --- .../incorrect-unlint/catches-unknown-lint.yaml | 13 +++++++++++++ .../single/syntax-version/allows-older-syntax.yaml | 13 +++++++++++++ .../single/syntax-version/catches-newer-syntax.yaml | 13 +++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml b/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml index 8aa40b8aa..0bdb033fc 100644 --- a/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml +++ b/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml @@ -4,9 +4,22 @@ lint: incorrect-unlint asserts: - /defects[count(defect[@severity='error'])=1] +<<<<<<< HEAD input: | +unlint non-existent-lint-name:5 +version 0.0.0 # Foo. [] > foo +======= +document: | + + + + unlint + non-existent-lint-name:5 + + + + +>>>>>>> ad92fd53 (fix(#1271): use document packs for meta-based lints, filter lint packs in EO test) diff --git a/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml b/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml index c782f18e3..625abbc87 100644 --- a/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml +++ b/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml @@ -4,9 +4,22 @@ lint: syntax-version asserts: - /defects[count(defect)=0] +<<<<<<< HEAD input: | +syntax 0.0.1 +version 0.0.0 # Foo. [] > foo +======= +document: | + + + + syntax + 0.0.1 + + + + +>>>>>>> ad92fd53 (fix(#1271): use document packs for meta-based lints, filter lint packs in EO test) diff --git a/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml b/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml index 9f1f9bc3b..ddb9cf5d5 100644 --- a/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml +++ b/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml @@ -4,9 +4,22 @@ lint: syntax-version asserts: - /defects[count(defect[@severity='error'])=1] +<<<<<<< HEAD input: | +syntax 999.0.0 +version 0.0.0 # Foo. [] > foo +======= +document: | + + + + syntax + 999.0.0 + + + + +>>>>>>> ad92fd53 (fix(#1271): use document packs for meta-based lints, filter lint packs in EO test) From 182e372a1750cabd120b713fe180bdbf8ca4a786 Mon Sep 17 00:00:00 2001 From: VasilevNStas Date: Sat, 15 Aug 2026 00:31:12 +0300 Subject: [PATCH 4/4] fix(#1271): resolve conflict markers, add version attr to syntax packs --- .../single/incorrect-unlint/catches-unknown-lint.yaml | 9 --------- .../single/syntax-version/allows-older-syntax.yaml | 11 +---------- .../single/syntax-version/catches-newer-syntax.yaml | 11 +---------- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml b/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml index 0bdb033fc..abbd3d665 100644 --- a/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml +++ b/src/test/resources/org/eolang/lints/packs/single/incorrect-unlint/catches-unknown-lint.yaml @@ -4,14 +4,6 @@ lint: incorrect-unlint asserts: - /defects[count(defect[@severity='error'])=1] -<<<<<<< HEAD -input: | - +unlint non-existent-lint-name:5 - +version 0.0.0 - - # Foo. - [] > foo -======= document: | @@ -22,4 +14,3 @@ document: | ->>>>>>> ad92fd53 (fix(#1271): use document packs for meta-based lints, filter lint packs in EO test) diff --git a/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml b/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml index 625abbc87..12b93f246 100644 --- a/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml +++ b/src/test/resources/org/eolang/lints/packs/single/syntax-version/allows-older-syntax.yaml @@ -4,16 +4,8 @@ lint: syntax-version asserts: - /defects[count(defect)=0] -<<<<<<< HEAD -input: | - +syntax 0.0.1 - +version 0.0.0 - - # Foo. - [] > foo -======= document: | - + syntax @@ -22,4 +14,3 @@ document: | ->>>>>>> ad92fd53 (fix(#1271): use document packs for meta-based lints, filter lint packs in EO test) diff --git a/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml b/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml index ddb9cf5d5..873e566d7 100644 --- a/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml +++ b/src/test/resources/org/eolang/lints/packs/single/syntax-version/catches-newer-syntax.yaml @@ -4,16 +4,8 @@ lint: syntax-version asserts: - /defects[count(defect[@severity='error'])=1] -<<<<<<< HEAD -input: | - +syntax 999.0.0 - +version 0.0.0 - - # Foo. - [] > foo -======= document: | - + syntax @@ -22,4 +14,3 @@ document: | ->>>>>>> ad92fd53 (fix(#1271): use document packs for meta-based lints, filter lint packs in EO test)