diff --git a/CHANGELOG.md b/CHANGELOG.md index 73da1a0d7..8196b8a02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to AET will be documented in this file. - [PR-470](https://github.com/Cognifide/aet/pull/470) Security vulnerabilities fix ([#407](https://github.com/Cognifide/aet/issues/407)) - [PR-468](https://github.com/Cognifide/aet/pull/468) Add loggers in collector/modifier ([#446](https://github.com/Cognifide/aet/issues/446)) - [PR-461](https://github.com/Cognifide/aet/pull/461) Generating correct correlationId when suite name is overridden([#440](https://github.com/Cognifide/aet/issues/440)) +- [PR-413](https://github.com/Cognifide/aet/pull/413) Added ability to show full page source when there has been no difference discovered ([#369](https://github.com/Cognifide/aet/issues/369)) ## Version 3.2.0 diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/CodeFormatter.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/CodeFormatter.java new file mode 100644 index 000000000..57f02b948 --- /dev/null +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/CodeFormatter.java @@ -0,0 +1,81 @@ +/** + * AET + * + * Copyright (C) 2018 Cognifide Limited + * + * 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. + */ +package com.cognifide.aet.job.common.comparators.source; + +import com.cognifide.aet.job.common.comparators.source.visitors.ContentVisitor; +import com.cognifide.aet.job.common.comparators.source.visitors.MarkupVisitor; +import com.cognifide.aet.job.common.comparators.source.visitors.NodeTraversor; +import java.util.Arrays; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +class CodeFormatter { + + private static final Pattern EMPTY_LINE_PATTERN = Pattern.compile("^[\\s]*$"); + + private static final String NEWLINE = "\\r?\\n"; + + String format(String code, SourceCompareType sourceCompareType) { + String result; + switch (sourceCompareType) { + case MARKUP: + result = formatCodeMarkup(code); + break; + case CONTENT: + result = formatCodeContent(code); + break; + case ALLFORMATTED: + result = formatCodeAllFormatted(code); + break; + default: + result = code; + break; + } + return result; + } + + private String formatCodeMarkup(String code) { + Document doc = Jsoup.parse(code); + NodeTraversor traversor = new NodeTraversor(new MarkupVisitor()); + traversor.traverse(doc); + return doc.html(); + } + + private String formatCodeContent(String code) { + Document doc = Jsoup.parse(code); + ContentVisitor visitor = new ContentVisitor(); + NodeTraversor traversor = new NodeTraversor(visitor); + traversor.traverse(doc); + return visitor.getFormattedText(); + } + + private String formatCodeAllFormatted(String code) { + Document doc = Jsoup.parse(code); + return removeEmptyLines(doc.outerHtml()); + } + + // package scoped for unit test + String removeEmptyLines(String source) { + String[] lines = source.split(NEWLINE); + return Arrays + .stream(lines) + .filter(line -> !EMPTY_LINE_PATTERN.matcher(line).matches()) + .collect(Collectors.joining("\n")); + } + +} diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/SourceComparator.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/SourceComparator.java index c76910a25..c2e7d5525 100644 --- a/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/SourceComparator.java +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/SourceComparator.java @@ -16,164 +16,107 @@ package com.cognifide.aet.job.common.comparators.source; import com.cognifide.aet.communication.api.metadata.ComparatorStepResult; +import com.cognifide.aet.communication.api.metadata.ComparatorStepResult.Status; import com.cognifide.aet.job.api.comparator.ComparatorJob; import com.cognifide.aet.job.api.comparator.ComparatorProperties; -import com.cognifide.aet.job.api.datafilter.DataFilterJob; import com.cognifide.aet.job.api.exceptions.ParametersException; import com.cognifide.aet.job.api.exceptions.ProcessingException; import com.cognifide.aet.job.common.comparators.source.diff.DiffParser; import com.cognifide.aet.job.common.comparators.source.diff.ResultDelta; -import com.cognifide.aet.job.common.comparators.source.visitors.ContentVisitor; -import com.cognifide.aet.job.common.comparators.source.visitors.MarkupVisitor; -import com.cognifide.aet.job.common.comparators.source.visitors.NodeTraversor; +import com.cognifide.aet.job.common.comparators.source.diff.ResultDelta.TYPE; import com.cognifide.aet.vs.ArtifactsDAO; +import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import org.apache.commons.lang3.StringUtils; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.util.Optional; -public class SourceComparator implements ComparatorJob { - - private static final Logger LOGGER = LoggerFactory.getLogger(SourceComparator.class); - - public static final String COMPARATOR_TYPE = "source"; - - public static final String COMPARATOR_NAME = "source"; +class SourceComparator implements ComparatorJob { private static final String SOURCE_COMPARE_TYPE = "compareType"; private final ComparatorProperties properties; - private final DiffParser diffParser; - private final ArtifactsDAO artifactsDAO; + private final Sources sources; - private SourceCompareType sourceCompareType = SourceCompareType.ALL; + private SourceCompareType sourceCompareType; - private final List dataFilterJobs; + SourceComparator(ArtifactsDAO artifactsDAO, ComparatorProperties properties, + DiffParser diffParser, Sources sources) { - public SourceComparator(ArtifactsDAO artifactsDAO, ComparatorProperties properties, - DiffParser diffParser, - List dataFilterJobs) { this.artifactsDAO = artifactsDAO; this.properties = properties; this.diffParser = diffParser; - this.dataFilterJobs = dataFilterJobs; + this.sources = sources; + } + @Override + public void setParameters(final Map params) throws ParametersException { + this.sourceCompareType = + Optional.ofNullable(params.get(SOURCE_COMPARE_TYPE)) + .map(String::toUpperCase) + .map(SourceCompareType::valueOf) + .orElse(SourceCompareType.ALL); } @Override - @SuppressWarnings("unchecked") public final ComparatorStepResult compare() throws ProcessingException { - final ComparatorStepResult result; try { - String patternSource = formatCode( - artifactsDAO.getArtifactAsString(properties, properties.getPatternId())); - String dataSource = formatCode( - artifactsDAO.getArtifactAsString(properties, properties.getCollectedId())); - - for (DataFilterJob dataFilterJob : dataFilterJobs) { - LOGGER.info("Starting {}. Company: {} Project: {}", - dataFilterJob.getInfo(), properties.getCompany(), properties.getProject()); - - dataSource = dataFilterJob.modifyData(dataSource); - - LOGGER.info("Successfully ended data modifications using {}. Company: {} Project: {}", - dataFilterJob.getInfo(), properties.getCompany(), properties.getProject()); - - patternSource = dataFilterJob.modifyPattern(patternSource); - - LOGGER.info("Successfully ended pattern modifications using {}. Company: {} Project: {}", - dataFilterJob.getInfo(), properties.getCompany(), properties.getProject()); - } - - if (StringUtils.isNotBlank(patternSource)) { - boolean compareTrimmedLines = shouldCompareTrimmedLines(sourceCompareType); - final List deltas = diffParser - .generateDiffs(patternSource, dataSource, compareTrimmedLines); - if (deltas.isEmpty()) { - result = new ComparatorStepResult(null, ComparatorStepResult.Status.PASSED, false); - } else { - result = new ComparatorStepResult(artifactsDAO.saveArtifactInJsonFormat(properties, - Collections.singletonMap("differences", deltas)), - ComparatorStepResult.Status.FAILED, true); - result.addData("formattedPattern", artifactsDAO.saveArtifact(properties, patternSource)); - result.addData("formattedSource", artifactsDAO.saveArtifact(properties, dataSource)); - result.addData("sourceCompareType", sourceCompareType.name()); - } - } else { - result = new ComparatorStepResult(null, ComparatorStepResult.Status.PASSED); - } - } catch (Exception e) { - throw new ProcessingException(e.getMessage(), e); + return compareSources(); + } catch (Exception ex) { + throw new ProcessingException(ex.getMessage(), ex); } - - return result; } + @SuppressWarnings("unchecked") + private ComparatorStepResult compareSources() throws IOException, ProcessingException { + sources.generate(sourceCompareType); + return getResultOfCompare(); + } - private boolean shouldCompareTrimmedLines(SourceCompareType sourceCompareType) { - return SourceCompareType.ALLFORMATTED.equals(sourceCompareType) - || SourceCompareType.MARKUP.equals(sourceCompareType); + private ComparatorStepResult getResultOfCompare() { + List deltas = calculateDeltas(); + ComparatorStepResult.Status status = calculateStatus(deltas); + ComparatorStepResult result = createNewStepResult(deltas, status); + addFormattedSources(result); + return result; } - @Override - public void setParameters(final Map params) throws ParametersException { - if (params.containsKey(SOURCE_COMPARE_TYPE)) { - this.sourceCompareType = SourceCompareType - .valueOf(params.get(SOURCE_COMPARE_TYPE).toUpperCase()); - } + private List calculateDeltas() { + return Optional.of(sources.getPatternSource()) + .map(this::diffSources) + .orElse(new ArrayList<>()); } - private String formatCode(String code) { - String result; - switch (sourceCompareType) { - case MARKUP: - result = formatCodeMarkup(code); - break; - case CONTENT: - result = formatCodeContent(code); - break; - case ALLFORMATTED: - result = formatCodeAllFormatted(code); - break; - default: - result = code; - break; - } - return result; + private List diffSources(String patternSource) { + boolean compareTrimmedLines = shouldCompareTrimmedLines(sourceCompareType); + return diffParser.generateDiffs(patternSource, sources.getDataSource(), compareTrimmedLines); } - private String formatCodeAllFormatted(String code) { - Document doc = Jsoup.parse(code); - return removeEmptyLines(doc.outerHtml()); + private boolean shouldCompareTrimmedLines(SourceCompareType sourceCompareType) { + return SourceCompareType.ALLFORMATTED.equals(sourceCompareType) + || SourceCompareType.MARKUP.equals(sourceCompareType); } - // package scoped for unit test - String removeEmptyLines(String source) { - String result = source; - if (StringUtils.isNotBlank(source)) { - result = result.replaceAll("(?m)^[ \t]*[\r\n]+", ""); - } - return result; + private Status calculateStatus(List deltas) { + return deltas.stream().anyMatch(d -> d.getType().equals(TYPE.CHANGE)) ? + Status.FAILED : Status.PASSED; } - private String formatCodeContent(String code) { - Document doc = Jsoup.parse(code); - ContentVisitor visitor = new ContentVisitor(); - NodeTraversor traversor = new NodeTraversor(visitor); - traversor.traverse(doc); - return visitor.getFormattedText(); + private ComparatorStepResult createNewStepResult(List deltas, Status status) { + Map> differences = Collections.singletonMap("differences", deltas); + String artifactId = artifactsDAO.saveArtifactInJsonFormat(properties, differences); + boolean rebaseable = Status.FAILED.equals(status); + return new ComparatorStepResult(artifactId, status, rebaseable); } - private String formatCodeMarkup(String code) { - Document doc = Jsoup.parse(code); - NodeTraversor traversor = new NodeTraversor(new MarkupVisitor()); - traversor.traverse(doc); - return doc.html(); + private void addFormattedSources(ComparatorStepResult result) { + String pattern = artifactsDAO.saveArtifact(properties, sources.getPatternSource()); + String data = artifactsDAO.saveArtifact(properties, sources.getDataSource()); + result.addData("formattedPattern", pattern); + result.addData("formattedSource", data); + result.addData("sourceCompareType", sourceCompareType.name()); } } diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorFactory.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorFactory.java index 527f918d7..ff51c795a 100644 --- a/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorFactory.java +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorFactory.java @@ -30,17 +30,20 @@ @Component public class SourceComparatorFactory implements ComparatorFactory { + private static final String COMPARATOR_TYPE = "source"; + private static final String COMPARATOR_NAME = "source"; + @Reference private ArtifactsDAO artifactsDAO; @Override public final String getType() { - return SourceComparator.COMPARATOR_TYPE; + return COMPARATOR_TYPE; } @Override public final String getName() { - return SourceComparator.COMPARATOR_NAME; + return COMPARATOR_NAME; } @Override @@ -49,11 +52,12 @@ public final int getRanking() { } @Override - public ComparatorJob createInstance(Comparator comparator, - ComparatorProperties comparatorProperties, List dataFilterJobs) - throws ParametersException { - final SourceComparator sourceComparator = new SourceComparator(artifactsDAO, - comparatorProperties, new DiffParser(), dataFilterJobs); + public ComparatorJob createInstance(Comparator comparator, ComparatorProperties properties, + List filters) throws ParametersException { + + Sources sources = new Sources(artifactsDAO, properties, filters, new CodeFormatter()); + final SourceComparator sourceComparator = new SourceComparator(artifactsDAO, properties, + new DiffParser(), sources); sourceComparator.setParameters(comparator.getParameters()); return sourceComparator; } diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/Sources.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/Sources.java new file mode 100644 index 000000000..1dc6b7700 --- /dev/null +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/Sources.java @@ -0,0 +1,88 @@ +/** + * AET + * + * Copyright (C) 2018 Cognifide Limited + * + * 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. + */ +package com.cognifide.aet.job.common.comparators.source; + + +import com.cognifide.aet.job.api.comparator.ComparatorProperties; +import com.cognifide.aet.job.api.datafilter.DataFilterJob; +import com.cognifide.aet.job.api.exceptions.ProcessingException; +import com.cognifide.aet.vs.ArtifactsDAO; +import java.io.IOException; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class can generate pattern source and tested data source from artifact. It will also format + * and filter sources. + */ +class Sources { + + private static final Logger LOGGER = LoggerFactory.getLogger(Sources.class); + + private final ComparatorProperties properties; + private final ArtifactsDAO artifactsDAO; + private final List dataFilterJobs; + private final CodeFormatter codeFormatter; + + private String patternSource; + private String dataSource; + + Sources(ArtifactsDAO artifactsDAO, ComparatorProperties properties, + List dataFilterJobs, CodeFormatter codeFormatter) { + this.properties = properties; + this.artifactsDAO = artifactsDAO; + this.dataFilterJobs = dataFilterJobs; + this.codeFormatter = codeFormatter; + } + + @SuppressWarnings("unchecked") + void generate(SourceCompareType sourceCompareType) throws IOException, ProcessingException { + String pattern = artifactsDAO.getArtifactAsString(properties, properties.getPatternId()); + String data = artifactsDAO.getArtifactAsString(properties, properties.getCollectedId()); + + this.patternSource = codeFormatter.format(pattern, sourceCompareType); + this.dataSource = codeFormatter.format(data, sourceCompareType); + + for (DataFilterJob dataFilterJob : dataFilterJobs) { + filter(dataFilterJob); + } + } + + private void filter(DataFilterJob dataFilterJob) throws ProcessingException { + String company = properties.getCompany(); + String project = properties.getProject(); + + LOGGER.info("Starting {}. Company: {} Project: {}", + dataFilterJob.getInfo(), company, project); + + dataSource = dataFilterJob.modifyData(dataSource); + LOGGER.info("Successfully ended data modifications using {}. Company: {} Project: {}", + dataFilterJob.getInfo(), company, project); + + patternSource = dataFilterJob.modifyPattern(patternSource); + LOGGER.info("Successfully ended pattern modifications using {}. Company: {} Project: {}", + dataFilterJob.getInfo(), company, project); + } + + String getPatternSource() { + return patternSource; + } + + String getDataSource() { + return dataSource; + } +} diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/diff/DiffParser.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/diff/DiffParser.java index bd614a023..4e475fde4 100644 --- a/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/diff/DiffParser.java +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/comparators/source/diff/DiffParser.java @@ -160,8 +160,7 @@ private List addFullSource(List deltaList, List orig deltaListWithSource.add(resultDelta); deltaListWithSource.add(processDelta(delta)); } - if ((originalList.size() > lastPositionOriginal || revisedList.size() > lastPositionRevised) - && !deltaList.isEmpty()) { + if ((originalList.size() > lastPositionOriginal || revisedList.size() > lastPositionRevised)) { ResultDelta resultDelta = prepareNoChangeResultDelta(originalList, revisedList, lastPositionOriginal, lastPositionRevised); deltaListWithSource.add(resultDelta); diff --git a/core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorRegExpTest.java b/core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/CodeFormatterTest.java similarity index 65% rename from core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorRegExpTest.java rename to core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/CodeFormatterTest.java index 8c051c280..b33b4835a 100644 --- a/core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorRegExpTest.java +++ b/core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/CodeFormatterTest.java @@ -24,36 +24,45 @@ import org.junit.runner.RunWith; @RunWith(Theories.class) -public class SourceComparatorRegExpTest { +public class CodeFormatterTest { - private SourceComparator tested; + private CodeFormatter tested; @Before public void setUp() { // initialized with nulls as tested method is stateless - tested = new SourceComparator(null, null, null, null); + tested = new CodeFormatter(); } @DataPoints public static String[][] getSampleData() { return new String[][]{ + {"\n\n\n\n", ""}, {"lineA", "lineA"}, - {"lineB\n", "lineB\n"}, - {"\nlineC\n", "lineC\n"}, - {"\n\n\nlineD\n", "lineD\n"}, + {"lineB\n", "lineB"}, + {"\nlineC\n", "lineC"}, + {"\n\n\nlineD\n", "lineD"}, {"firstA\n\n\nlast", "firstA\nlast"}, {"firstB\n\n\nsecond\n\n\n\n\n\nlast", "firstB\nsecond\nlast"}, - {"firstC\n\n\nlast\n\n", "firstC\nlast\n"}, + {"firstC\n\n\nlast\n\n", "firstC\nlast"}, + {" \t indented \t ", " \t indented \t "}, + {"first line\r\n\r\n third line ", "first line\n third line "}, + {" one \n two \n\n three \n\n\n ", " one \n two \n three "}, // CRLF - {"Crlf lineA\r\n\r\nsecond line", "Crlf lineA\r\nsecond line"}, - {"Crlf lineB\r\n\r\nsecond line\r\n\r\n", "Crlf lineB\r\nsecond line\r\n"}, + {"Crlf lineA\r\n\r\nsecond line", "Crlf lineA\nsecond line"}, + {"Crlf lineB\r\n\r\nsecond line\r\n\r\n", "Crlf lineB\nsecond line"}, // mixed - {"Crlf lineC\n\n\nsecond line\r\n\r\n", "Crlf lineC\nsecond line\r\n"}, + {"Crlf lineC\n\n\nsecond line\r\n\r\n", "Crlf lineC\nsecond line"}, + // if we only have single blank line, we should also remove it + {" ", ""}, + {" \t", ""}, + {" \t ", ""}, + {" \t\t ", ""} }; } @Theory - public void removeEmptyLines(String[] dataPoint) throws Exception { + public void removeEmptyLines(String[] dataPoint) { String input = dataPoint[0]; String expected = dataPoint[1]; diff --git a/core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorTest.java b/core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorTest.java index 4b7cbfbd4..eb4c29e98 100644 --- a/core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorTest.java +++ b/core/jobs/src/test/java/com/cognifide/aet/job/common/comparators/source/SourceComparatorTest.java @@ -16,10 +16,11 @@ package com.cognifide.aet.job.common.comparators.source; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import com.cognifide.aet.communication.api.metadata.ComparatorStepResult; +import com.cognifide.aet.communication.api.metadata.ComparatorStepResult.Status; import com.cognifide.aet.job.api.comparator.ComparatorProperties; -import com.cognifide.aet.job.api.datafilter.DataFilterJob; import com.cognifide.aet.job.common.ArtifactDAOMock; import com.cognifide.aet.job.common.comparators.AbstractComparatorTest; import com.cognifide.aet.job.common.comparators.source.diff.DiffParser; @@ -51,29 +52,32 @@ public void setUp() { * @return result of comparison * @throws Exception for incorrect parameters */ - protected ComparatorStepResult compare(String patternFilename, String dataFilename, + private ComparatorStepResult compare(String patternFilename, String dataFilename, Map comparatorParams) throws Exception { ComparatorProperties properties = new ComparatorProperties(TEST_COMPANY, TEST_PROJECT, patternFilename, dataFilename); - tested = new SourceComparator(artifactDaoMock, properties, new DiffParser(), - new ArrayList()); + Sources sources = new Sources(artifactDaoMock, properties, new ArrayList<>(), + new CodeFormatter()); + tested = new SourceComparator(artifactDaoMock, properties, new DiffParser(), sources); tested.setParameters(comparatorParams); return tested.compare(); } @Test public void testCompareOfValidInput() throws Exception { - result = compare("pattern-source.html", "data-source.html", new HashMap()); + result = compare("pattern-source.html", "data-source.html", new HashMap<>()); assertEquals(ComparatorStepResult.Status.PASSED, result.getStatus()); - assertEquals(null, getActual()); + assertFalse(result.isRebaseable()); + // artifact is saved - with formatted sources of pattern and tested data, even if they are equal + assertEqualsToSavedArtifact("expected-result-with-sources.json"); } @Test public void testCompareOfInvalidInput() throws Exception { result = compare("pattern-source.html", "data-invalid-source.html", - new HashMap()); + new HashMap<>()); assertEquals(ComparatorStepResult.Status.FAILED, result.getStatus()); assertEqualsToSavedArtifact("expected-invalid-result.json"); @@ -92,6 +96,35 @@ public void testCompareMarkupWithDifferentAttributeName() throws Exception { "markup/data-source-with-different-attribute-value.html", ImmutableMap.of("compareType", "markup")); assertEquals(ComparatorStepResult.Status.FAILED, result.getStatus()); + } + + @Test + public void shouldRecognizeLineEndings() throws Exception { + //When + result = compare("formatting/empty-lines-windows.html", + "formatting/empty-lines-linux.html", + ImmutableMap.of("compareType", "all")); + //Then + assertEquals(Status.FAILED, result.getStatus()); + } + @Test + public void shouldIgnoreLineEndingsForAllFormatted() throws Exception { + //When + result = compare("formatting/empty-lines-windows.html", + "formatting/empty-lines-linux.html", + ImmutableMap.of("compareType", "allformatted")); + //Then + assertEquals(Status.PASSED, result.getStatus()); + } + + @Test + public void shouldIgnoreWhitespacesForAllFormatted() throws Exception { + //When + result = compare("formatting/formatted.html", + "formatting/not-formatted.html", + ImmutableMap.of("compareType", "allformatted")); + //Then + assertEquals(Status.PASSED, result.getStatus()); } } diff --git a/core/jobs/src/test/resources/mock/SourceComparator/expected-result-with-sources.json b/core/jobs/src/test/resources/mock/SourceComparator/expected-result-with-sources.json new file mode 100644 index 000000000..3e66980ea --- /dev/null +++ b/core/jobs/src/test/resources/mock/SourceComparator/expected-result-with-sources.json @@ -0,0 +1,15 @@ +{ + "differences": [ + { + "original": { + "position": 0, + "prettyHtml": "\u0026lt;?xml version\u003d\u0026quot;1.0\u0026quot; encoding\u003d\u0026quot;ISO-8859-1\u0026quot;?\u0026gt;\u0026lt;html\u0026gt;\u0026lt;head\u0026gt;\u0026lt;title\u0026gt;Lorem ipsum dolor sith ameth\u0026lt;/title\u0026gt;\u0026lt;/head\u0026gt;\u0026lt;body/\u0026gt;\u0026lt;/html\u0026gt;" + }, + "revised": { + "position": 0, + "prettyHtml": "\u0026lt;?xml version\u003d\u0026quot;1.0\u0026quot; encoding\u003d\u0026quot;ISO-8859-1\u0026quot;?\u0026gt;\u0026lt;html\u0026gt;\u0026lt;head\u0026gt;\u0026lt;title\u0026gt;Lorem ipsum dolor sith ameth\u0026lt;/title\u0026gt;\u0026lt;/head\u0026gt;\u0026lt;body/\u0026gt;\u0026lt;/html\u0026gt;" + }, + "type": "NO_CHANGE" + } + ] +} \ No newline at end of file diff --git a/core/jobs/src/test/resources/mock/SourceComparator/formatting/empty-lines-linux.html b/core/jobs/src/test/resources/mock/SourceComparator/formatting/empty-lines-linux.html new file mode 100644 index 000000000..f93626c9e --- /dev/null +++ b/core/jobs/src/test/resources/mock/SourceComparator/formatting/empty-lines-linux.html @@ -0,0 +1,19 @@ + + + + + title + + + + + + +
+ zażółć + +
+ + + + diff --git a/core/jobs/src/test/resources/mock/SourceComparator/formatting/empty-lines-windows.html b/core/jobs/src/test/resources/mock/SourceComparator/formatting/empty-lines-windows.html new file mode 100644 index 000000000..400aae46f --- /dev/null +++ b/core/jobs/src/test/resources/mock/SourceComparator/formatting/empty-lines-windows.html @@ -0,0 +1,19 @@ + + + + + title + + + + + + +
+ zażółć + +
+ + + + diff --git a/core/jobs/src/test/resources/mock/SourceComparator/formatting/formatted.html b/core/jobs/src/test/resources/mock/SourceComparator/formatting/formatted.html new file mode 100644 index 000000000..79a518aa6 --- /dev/null +++ b/core/jobs/src/test/resources/mock/SourceComparator/formatting/formatted.html @@ -0,0 +1,14 @@ + + + + + title + + + + +
+ zażółć +
+ + diff --git a/core/jobs/src/test/resources/mock/SourceComparator/formatting/not-formatted.html b/core/jobs/src/test/resources/mock/SourceComparator/formatting/not-formatted.html new file mode 100644 index 000000000..392554626 --- /dev/null +++ b/core/jobs/src/test/resources/mock/SourceComparator/formatting/not-formatted.html @@ -0,0 +1,26 @@ + + + + +title + + + + + + +
+ + + zażółć + + +
+ + + + + + + + diff --git a/report/src/main/webapp/app/layout/main/url/reports/source-diff.html b/report/src/main/webapp/app/layout/main/url/reports/source-diff.html new file mode 100644 index 000000000..32b4835be --- /dev/null +++ b/report/src/main/webapp/app/layout/main/url/reports/source-diff.html @@ -0,0 +1,82 @@ + +
+
+ + + + + + + + + + + + + + + + + +
#Pattern
{{code.original.position}} + +

+
{{code.original.position}} + +

+
+
+
+ + + + + + + + + + + + + + + + + +
#Source
{{code.original.position}} + +

+
{{code.original.position}} + +

+
+
\ No newline at end of file diff --git a/report/src/main/webapp/app/layout/main/url/reports/source.html b/report/src/main/webapp/app/layout/main/url/reports/source.html index 76029b61f..85977bd8c 100644 --- a/report/src/main/webapp/app/layout/main/url/reports/source.html +++ b/report/src/main/webapp/app/layout/main/url/reports/source.html @@ -17,7 +17,6 @@ limitations under the License. --> -
Settings
@@ -37,79 +36,19 @@
-
-
No issues found
-
- View source:
- {{case.getDataUrl()}} +
+
No issues found
+
+ View source:
+ {{case.getDataUrl()}} +
+
+
+
-
-
-
- - - - - - - - - - - - - - - - - - -
#Pattern
{{code.original.position}} - -

-
{{code.original.position}} - -

-
-
-
- - - - - - - - - - - - - - - - - -
#Source
{{code.original.position}} - -

-
{{code.original.position}} - -

-
-
+
\ No newline at end of file