Skip to content

Commit

Permalink
Merge pull request objectionary#188 from h1alexbel/149
Browse files Browse the repository at this point in the history
feat(objectionary#149): incorrect-alias lint
  • Loading branch information
yegor256 authored Dec 31, 2024
2 parents 0f81922 + 5c91e3e commit be868ca
Show file tree
Hide file tree
Showing 10 changed files with 416 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/main/java/org/eolang/lints/PkWpa.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Map;
import org.cactoos.iterable.IterableEnvelope;
import org.cactoos.list.ListOf;
import org.eolang.lints.critical.LtIncorrectAlias;
import org.eolang.lints.units.LtUnitTestMissing;

/**
Expand All @@ -45,7 +46,8 @@ public final class PkWpa extends IterableEnvelope<Lint<Map<String, XML>>> {
public PkWpa() {
super(
new ListOf<>(
new LtUnitTestMissing()
new LtUnitTestMissing(),
new LtIncorrectAlias()
)
);
}
Expand Down
23 changes: 22 additions & 1 deletion src/main/java/org/eolang/lints/Programs.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.cactoos.iterable.Sticky;
Expand All @@ -60,6 +61,11 @@ public final class Programs {
)
);

/**
* XMIR extension.
*/
private static final Pattern XMIR_EXT = Pattern.compile("\\.xmir$");

/**
* Lints to use.
*/
Expand Down Expand Up @@ -156,14 +162,29 @@ private static Map<String, XML> discover(final Iterable<Path> dirs) throws IOExc
* @param dir The directories to search for XMIR files in (recursively)
* @return Map of XMIR files
* @throws IOException If fails
* @todo #149:35min Introduce new class XmirKey.java
* Let's extract the code that calculates the key for XMIR file into new
* Java class. Don't forget to create unit tests, and remove this puzzle.
*/
private static Map<String, XML> discover(final Path dir) throws IOException {
try (Stream<Path> walk = Files.walk(dir)) {
return walk
.filter(Files::isRegularFile)
.collect(
Collectors.toMap(
path -> path.getFileName().toString().replaceAll("\\.xmir$", ""),
path -> {
final String key;
final Path parent = dir.relativize(path.getParent());
final String name = Programs.XMIR_EXT.matcher(
path.getFileName().toString()
).replaceAll("");
if (parent.toString().isEmpty()) {
key = name;
} else {
key = String.format("%s/%s", parent, name);
}
return key;
},
path -> {
try {
return new XMLDocument(path);
Expand Down
93 changes: 93 additions & 0 deletions src/main/java/org/eolang/lints/critical/LtIncorrectAlias.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.eolang.lints.critical;

import com.jcabi.xml.XML;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
import org.cactoos.io.ResourceOf;
import org.cactoos.text.TextOf;
import org.eolang.lints.Defect;
import org.eolang.lints.Lint;
import org.eolang.lints.Severity;

/**
* Checks that `+alias` is pointing to existing `.xmir` files.
* @since 0.0.30
*/
public final class LtIncorrectAlias implements Lint<Map<String, XML>> {

@Override
public String name() {
return "incorrect-alias";
}

@Override
public Collection<Defect> defects(final Map<String, XML> pkg) {
final Collection<Defect> defects = new LinkedList<>();
pkg.values().forEach(
xmir -> {
for (final XML alias : xmir.nodes("/program/metas/meta[head='alias']/tail")) {
if (xmir.nodes("/program/metas/meta[head='package']").size() != 1) {
continue;
}
final String pointer = alias.xpath("text()").get(0);
final String lookup = String.format(
"%s/%s",
xmir.xpath("/program/metas/meta[head='package']/tail/text()").get(0),
pointer
);
if (!pkg.containsKey(lookup)) {
defects.add(
new Defect.Default(
"incorrect-alias",
Severity.CRITICAL,
xmir.xpath("/program/@name").stream().findFirst().orElse("unknown"),
Integer.parseInt(
xmir.xpath("/program/metas/meta[head='alias'][1]/@line").get(0)
),
String.format(
"Incorrect pointing alias '%s', there is no %s",
pointer,
lookup
)
)
);
}
}
}
);
return defects;
}

@Override
public String motive() throws Exception {
return new TextOf(
new ResourceOf(
"org/eolang/motives/critical/incorrect-alias.md"
)
).asString();
}
}
28 changes: 28 additions & 0 deletions src/main/java/org/eolang/lints/critical/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* Critical Java lints.
* @since 0.0.30
*/
package org.eolang.lints.critical;
17 changes: 17 additions & 0 deletions src/main/resources/org/eolang/motives/critical/incorrect-alias.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Incorrect Alias

Special meta `+alias` must point to existing file in the dir, outlined by
`+package` meta.

Incorrect:

```eo
+alias foo
+package ttt
# Bar.
[] > bar
foo > @
```

Since `ttt/foo.xmir` file doesn't exist, `critical` defect will be issued.
143 changes: 143 additions & 0 deletions src/test/java/org/eolang/lints/critical/LtIncorrectAliasTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.eolang.lints.critical;

import com.jcabi.xml.XML;
import com.jcabi.xml.XMLDocument;
import com.yegor256.Mktmp;
import com.yegor256.MktmpResolver;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.cactoos.io.ResourceOf;
import org.cactoos.map.MapEntry;
import org.cactoos.map.MapOf;
import org.eolang.lints.Programs;
import org.eolang.parser.EoSyntax;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

/**
* Tests for {@link LtIncorrectAlias}.
*
* @since 0.0.30
*/
final class LtIncorrectAliasTest {

@Test
void catchesBrokenAlias() throws IOException {
MatcherAssert.assertThat(
"Defects are empty, but shouldn't be",
new LtIncorrectAlias().defects(
new MapOf<>(
new MapEntry<>(
"bar",
new EoSyntax(
new ResourceOf(
"org/eolang/lints/critical/incorrect-alias/bar.eo"
)
).parsed()
)
)
),
Matchers.hasSize(Matchers.greaterThan(0))
);
}

@Test
void passesIfFileExists() throws IOException {
MatcherAssert.assertThat(
"Defects aren't empty, but should be",
new LtIncorrectAlias().defects(
new MapOf<String, XML>(
new MapEntry<>(
"bar",
new EoSyntax(
new ResourceOf(
"org/eolang/lints/critical/incorrect-alias/bar.eo"
)
).parsed()
),
new MapEntry<>("ttt/foo", new XMLDocument("<program/>"))
)
),
Matchers.hasSize(0)
);
}

@ParameterizedTest
@ValueSource(
strings = {
"no-aliases.eo",
"no-package.eo"
}
)
void ignoresProgram(final String name) throws IOException {
MatcherAssert.assertThat(
"Defects aren't empty, but should be",
new LtIncorrectAlias().defects(
new MapOf<>(
new MapEntry<>(
"foo",
new EoSyntax(
new ResourceOf(
String.format(
"org/eolang/lints/critical/incorrect-alias/%s",
name
)
)
).parsed()
)
)
),
Matchers.hasSize(0)
);
}

@Test
@ExtendWith(MktmpResolver.class)
void acceptsValidDirectory(@Mktmp final Path dir) throws IOException {
Files.write(
dir.resolve("bar.xmir"),
new EoSyntax(
new ResourceOf(
"org/eolang/lints/critical/incorrect-alias/bar.eo"
)
).parsed().toString().getBytes()
);
Files.createDirectory(dir.resolve("ttt"));
Files.write(dir.resolve("ttt/foo.xmir"), "<program/>".getBytes());
Files.write(dir.resolve("bar-test.xmir"), "<program/>".getBytes());
Files.write(dir.resolve("ttt/foo-test.xmir"), "<program/>".getBytes());
MatcherAssert.assertThat(
"Defects are not empty, but should be",
new Programs(dir).defects(),
Matchers.emptyIterable()
);
}
}
28 changes: 28 additions & 0 deletions src/test/java/org/eolang/lints/critical/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* Tests for critical Java lints.
* @since 0.0.30
*/
package org.eolang.lints.critical;
Loading

0 comments on commit be868ca

Please sign in to comment.