Changeset 15979 in josm for trunk/src/org
- Timestamp:
- 2020-03-01T23:35:47+01:00 (5 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/data/validation/tests
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
r15972 r15979 10 10 import java.io.Reader; 11 11 import java.io.StringReader; 12 import java.lang.reflect.Method;13 import java.text.MessageFormat;14 12 import java.util.ArrayList; 15 13 import java.util.Collection; 16 import java.util.Collections;17 14 import java.util.HashMap; 18 15 import java.util.HashSet; 19 16 import java.util.Iterator; 20 17 import java.util.LinkedHashMap; 21 import java.util.LinkedHashSet;22 18 import java.util.LinkedList; 23 19 import java.util.List; … … 36 32 import org.openstreetmap.josm.command.DeleteCommand; 37 33 import org.openstreetmap.josm.command.SequenceCommand; 38 import org.openstreetmap.josm.data.coor.LatLon;39 import org.openstreetmap.josm.data.osm.DataSet;40 34 import org.openstreetmap.josm.data.osm.IPrimitive; 41 35 import org.openstreetmap.josm.data.osm.OsmPrimitive; 42 import org.openstreetmap.josm.data.osm.OsmUtils;43 import org.openstreetmap.josm.data.osm.Relation;44 36 import org.openstreetmap.josm.data.osm.Tag; 45 37 import org.openstreetmap.josm.data.osm.Way; … … 55 47 import org.openstreetmap.josm.gui.mappaint.MultiCascade; 56 48 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition; 57 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.ClassCondition;58 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.ExpressionCondition;59 49 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression; 60 import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory.ParameterFunction;61 import org.openstreetmap.josm.gui.mappaint.mapcss.Functions;62 50 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction; 63 import org.openstreetmap.josm.gui.mappaint.mapcss.LiteralExpression;64 51 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule; 65 52 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule.Declaration; … … 67 54 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource.MapCSSRuleIndex; 68 55 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector; 69 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.AbstractSelector;70 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector;71 56 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.OptimizedGeneralSelector; 72 57 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser; … … 80 65 import org.openstreetmap.josm.spi.preferences.Config; 81 66 import org.openstreetmap.josm.tools.CheckParameterUtil; 82 import org.openstreetmap.josm.tools.DefaultGeoProperty;83 import org.openstreetmap.josm.tools.GeoProperty;84 import org.openstreetmap.josm.tools.GeoPropertyIndex;85 67 import org.openstreetmap.josm.tools.I18n; 86 68 import org.openstreetmap.josm.tools.Logging; 87 69 import org.openstreetmap.josm.tools.MultiMap; 88 import org.openstreetmap.josm.tools.Territories;89 70 import org.openstreetmap.josm.tools.Utils; 90 71 … … 96 77 private MapCSSTagCheckerIndex indexData; 97 78 private final Set<OsmPrimitive> tested = new HashSet<>(); 98 final Map<IPrimitive, Area> mpAreaCache = new HashMap<>(); 79 private static final Map<IPrimitive, Area> mpAreaCache = new HashMap<>(); 99 80 100 81 /** … … 668 649 } 669 650 670 /**671 * Returns the set of tagchecks on which this check depends on.672 * @param schecks the collection of tagcheks to search in673 * @return the set of tagchecks on which this check depends on674 * @since 7881675 */676 public Set<TagCheck> getTagCheckDependencies(Collection<TagCheck> schecks) {677 Set<TagCheck> result = new HashSet<>();678 Set<String> classes = getClassesIds();679 if (schecks != null && !classes.isEmpty()) {680 for (TagCheck tc : schecks) {681 if (this.equals(tc)) {682 continue;683 }684 for (String id : tc.setClassExpressions) {685 if (classes.contains(id)) {686 result.add(tc);687 break;688 }689 }690 }691 }692 return result;693 }694 695 /**696 * Returns the list of ids of all MapCSS classes referenced in the rule selectors.697 * @return the list of ids of all MapCSS classes referenced in the rule selectors698 * @since 7881699 */700 public Set<String> getClassesIds() {701 Set<String> result = new HashSet<>();702 for (Selector s : rule.selectors) {703 if (s instanceof AbstractSelector) {704 for (Condition c : ((AbstractSelector) s).getConditions()) {705 if (c instanceof ClassCondition) {706 result.add(((ClassCondition) c).id);707 }708 }709 }710 }711 return result;712 }713 651 } 714 652 … … 814 752 } 815 753 816 privateCollection<TestError> getErrorsForPrimitive(OsmPrimitive p, boolean includeOtherSeverity,754 static Collection<TestError> getErrorsForPrimitive(OsmPrimitive p, boolean includeOtherSeverity, 817 755 Collection<Set<TagCheck>> checksCol) { 818 756 // this variant is only used by the assertion tests … … 877 815 // Check assertions, useful for development of local files 878 816 if (Config.getPref().getBoolean("validator.check_assert_local_rules", false) && Utils.isLocalUrl(url)) { 879 for (String msg : checkAsserts(result.parseChecks)) { 817 for (String msg : MapCSSTagCheckerAsserts.checkAsserts(result.parseChecks)) { 880 818 Logging.warn(msg); 881 819 } … … 912 850 } 913 851 } 914 }915 916 private static Method getFunctionMethod(String method) {917 try {918 return Functions.class.getDeclaredMethod(method, Environment.class, String.class);919 } catch (NoSuchMethodException | SecurityException e) {920 Logging.error(e);921 return null;922 }923 }924 925 private static Optional<String> getFirstInsideCountry(TagCheck check, Method insideMethod) {926 return check.rule.selectors.stream()927 .filter(s -> s instanceof GeneralSelector)928 .flatMap(s -> ((GeneralSelector) s).getConditions().stream())929 .filter(c -> c instanceof ExpressionCondition)930 .map(c -> ((ExpressionCondition) c).getExpression())931 .filter(c -> c instanceof ParameterFunction)932 .map(c -> (ParameterFunction) c)933 .filter(c -> c.getMethod().equals(insideMethod))934 .flatMap(c -> c.getArgs().stream())935 .filter(e -> e instanceof LiteralExpression)936 .map(e -> ((LiteralExpression) e).getLiteral())937 .filter(l -> l instanceof String)938 .map(l -> ((String) l).split(",")[0])939 .findFirst();940 }941 942 private static LatLon getLocation(TagCheck check, Method insideMethod) {943 Optional<String> inside = getFirstInsideCountry(check, insideMethod);944 if (inside.isPresent()) {945 GeoPropertyIndex<Boolean> index = Territories.getGeoPropertyIndex(inside.get());946 if (index != null) {947 GeoProperty<Boolean> prop = index.getGeoProperty();948 if (prop instanceof DefaultGeoProperty) {949 return ((DefaultGeoProperty) prop).getRandomLatLon();950 }951 }952 }953 return LatLon.ZERO;954 }955 956 /**957 * Checks that rule assertions are met for the given set of TagChecks.958 * @param schecks The TagChecks for which assertions have to be checked959 * @return A set of error messages, empty if all assertions are met960 * @since 7356961 */962 public Set<String> checkAsserts(final Collection<TagCheck> schecks) {963 Set<String> assertionErrors = new LinkedHashSet<>();964 final Method insideMethod = getFunctionMethod("inside");965 final DataSet ds = new DataSet();966 for (final TagCheck check : schecks) {967 Logging.debug("Check: {0}", check);968 for (final Map.Entry<String, Boolean> i : check.assertions.entrySet()) {969 Logging.debug("- Assertion: {0}", i);970 final OsmPrimitive p = OsmUtils.createPrimitive(i.getKey(), getLocation(check, insideMethod), true);971 // Build minimal ordered list of checks to run to test the assertion972 List<Set<TagCheck>> checksToRun = new ArrayList<>();973 Set<TagCheck> checkDependencies = check.getTagCheckDependencies(schecks);974 if (!checkDependencies.isEmpty()) {975 checksToRun.add(checkDependencies);976 }977 checksToRun.add(Collections.singleton(check));978 // Add primitive to dataset to avoid DataIntegrityProblemException when evaluating selectors979 addPrimitive(ds, p);980 final Collection<TestError> pErrors = getErrorsForPrimitive(p, true, checksToRun);981 Logging.debug("- Errors: {0}", pErrors);982 final boolean isError = pErrors.stream().anyMatch(e -> e.getTester() instanceof MapCSSTagCheckerAndRule983 && ((MapCSSTagCheckerAndRule) e.getTester()).rule.equals(check.rule));984 if (isError != i.getValue()) {985 assertionErrors.add(MessageFormat.format("Expecting test ''{0}'' (i.e., {1}) to {2} {3} (i.e., {4})",986 check.getMessage(p), check.rule.selectors, i.getValue() ? "match" : "not match", i.getKey(), p.getKeys()));987 }988 if (isError) {989 // Check that autofix works as expected990 Command fix = check.fixPrimitive(p);991 if (fix != null && fix.executeCommand() && !getErrorsForPrimitive(p, true, checksToRun).isEmpty()) {992 assertionErrors.add(MessageFormat.format("Autofix does not work for test ''{0}'' (i.e., {1})",993 check.getMessage(p), check.rule.selectors));994 }995 }996 ds.removePrimitive(p);997 }998 }999 return assertionErrors;1000 }1001 1002 private static void addPrimitive(DataSet ds, OsmPrimitive p) {1003 if (p instanceof Way) {1004 ((Way) p).getNodes().forEach(n -> addPrimitive(ds, n));1005 } else if (p instanceof Relation) {1006 ((Relation) p).getMembers().forEach(m -> addPrimitive(ds, m.getMember()));1007 }1008 ds.addPrimitive(p);1009 852 } 1010 853
Note:
See TracChangeset
for help on using the changeset viewer.