/* * Copyright 2016 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.rf.ide.core.testdata.text.write; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.rf.ide.core.testdata.model.FilePosition; import org.rf.ide.core.testdata.model.FileRegion; import org.rf.ide.core.testdata.text.read.LineReader; public class DumperTestHelper { private static final DumperTestHelper INSTANCE = new DumperTestHelper(); public static DumperTestHelper getINSTANCE() { return INSTANCE; } public Path getFile(final String path) throws URISyntaxException { final URL resource = this.getClass().getResource(path); return Paths.get(resource.toURI()); } public String readWithLineSeparatorPresave(final Path file) throws Exception { try (InputStreamReader fisReader = new InputStreamReader(new FileInputStream(file.toFile()))) { final StringBuilder str = new StringBuilder(); final char buff[] = new char[4096]; int length = -1; while ((length = fisReader.read(buff)) != -1) { str.append(Arrays.copyOf(buff, length)); } return str.toString(); } } public TextCompareResult compare(final String text1, final String text2) { final TextCompareResult cmpResult = new TextCompareResult(text1, text2); final int text1Len = text1.length(); final int text2Len = text2.length(); int differenceOffset = FilePosition.NOT_SET; if (text1Len > text2Len) { differenceOffset = indexOfTheFirstDifference(text1.substring(0, text2Len), text2); if (differenceOffset == FilePosition.NOT_SET) { differenceOffset = text2Len; } } else if (text1Len < text2Len) { differenceOffset = indexOfTheFirstDifference(text1, text2.substring(0, text1Len)); if (differenceOffset == FilePosition.NOT_SET) { differenceOffset = text1Len; } } else { differenceOffset = indexOfTheFirstDifference(text1, text2); } if (differenceOffset != FilePosition.NOT_SET) { cmpResult.setDifference(buildFrom(text1, differenceOffset), buildFrom(text2, differenceOffset)); } return cmpResult; } private FilePosition buildFrom(final String text, final int offset) { FilePosition pos = FilePosition.createNotSet(); FileRegion regionFound = null; final List<FileRegion> endOfLinesRegions = getEndOfLinesRegions(text); for (final FileRegion reg : endOfLinesRegions) { if (reg.isInside(offset)) { regionFound = reg; break; } } if (regionFound != null) { final FilePosition fpStart = regionFound.getStart(); final int column = fpStart.getColumn() + (offset - fpStart.getOffset()); pos = new FilePosition(fpStart.getLine(), column, offset); } if (pos.isNotSet()) { pos = new FilePosition(pos.getLine(), pos.getColumn(), offset); } return pos; } private int indexOfTheFirstDifference(final String text1, final String text2) { int differenceIndex = FilePosition.NOT_SET; final char text1CharArray[] = text1.toCharArray(); final char text2CharArray[] = text2.toCharArray(); final int len = text1CharArray.length; for (int charIndex = 0; charIndex < len; charIndex++) { if (text1CharArray[charIndex] != text2CharArray[charIndex]) { differenceIndex = charIndex; break; } } return differenceIndex; } public static class TextCompareResult { private final String expected; private final String got; private FilePosition differenceStartExpectedText = FilePosition.createNotSet(); private FilePosition differenceStartGotText = FilePosition.createNotSet(); public TextCompareResult(final String expected, final String got) { this.expected = expected; this.got = got; } public String expected() { return this.expected; } public String got() { return this.got; } private void setDifference(final FilePosition differenceInExpected, final FilePosition differenceInGot) { this.differenceStartExpectedText = differenceInExpected; this.differenceStartGotText = differenceInGot; } public FilePosition getDifferenceInExpected() { return this.differenceStartExpectedText; } public FilePosition getDifferenceInGot() { return this.differenceStartGotText; } public String report() { String report = null; if (!getDifferenceInExpected().isNotSet() || !getDifferenceInGot().isNotSet()) { report = "Difference: \n" + "== Expected: \n==== Text: " + expected().substring(getDifferenceInExpected().getOffset()) + "\n==== Position: " + getDifferenceInExpected() + "\n== Got: \n==== Text: " + got().substring(getDifferenceInGot().getOffset()) + "\n==== Position: " + getDifferenceInGot(); } return report; } } private List<FileRegion> getEndOfLinesRegions(final String text) { List<FileRegion> eols = new ArrayList<>(); try (final LineReader lineReader = new LineReader(new StringReader(text)); final BufferedReader bufferedReader = new BufferedReader(lineReader);) { while (bufferedReader.readLine() != null) { // do nothing } eols = lineReader.getLinesRegion(); } catch (final Exception e) { // is not I/O will not happen } return eols; } }