view test/org/tmatesoft/hg/test/TestNewlineFilter.java @ 709:497e697636fc

Report merged lines as changed block if possible, not as a sequence of added/deleted blocks. To facilitate access to merge parent lines AddBlock got mergeLineAt() method that reports index of the line in the second parent (if any), while insertedAt() has been changed to report index in the first parent always
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 21 Aug 2013 16:23:27 +0200
parents f2c11fe7f3e9
children
line wrap: on
line source
/*
 * Copyright (c) 2011 TMate Software Ltd
 *  
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * For information on how to redistribute this software under
 * the terms of a license other than GNU General Public License
 * contact TMate Software at support@hg4j.com
 */
package org.tmatesoft.hg.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;

import org.junit.Assert;
import org.junit.Test;
import org.tmatesoft.hg.internal.NewlineFilter;

/**
 *
 * @author Artem Tikhomirov
 * @author TMate Software Ltd.
 */
public class TestNewlineFilter {

	public static void main(String[] args) throws Exception {
		FileInputStream fis = new FileInputStream(new File("/temp/design.lf.txt"));
		FileOutputStream fos = new FileOutputStream(new File("/temp/design.newline.out"));
		ByteBuffer b = ByteBuffer.allocate(12);
		NewlineFilter nlFilter = NewlineFilter.createNix2Win(true);
		while (fis.getChannel().read(b) != -1) {
			b.flip(); // get ready to be read
			ByteBuffer f = nlFilter.filter(b);
			fos.getChannel().write(f); // XXX in fact, f may not be fully consumed
			if (b.hasRemaining()) {
				b.compact();
			} else {
				b.clear();
			}
		}
		fis.close();
		fos.flush();
		fos.close();
	}

	// pure
	private final String crlf_1 = "\r\nA\r\nBC\r\n\r\nDEF\r\n";
	private final String lf_1 = "\nA\nBC\n\nDEF\n";
	// mixed
	private final String crlf_2 = "\r\nA\r\nBC\n\nDEF\r\n";
	private final String lf_2 = "\nA\nBC\r\n\r\nDEF\n";
	
	@Test
	public void testPure_CRLF_2_LF() {
		final byte[] input = crlf_1.getBytes();
		byte[] result = apply(NewlineFilter.createWin2Nix(false), input);
		Assert.assertArrayEquals(lf_1.getBytes(), result);
	}

	@Test
	public void testPure_LF_2_CRLF() {
		final byte[] input = lf_1.getBytes();
		byte[] result = apply(NewlineFilter.createNix2Win(false), input);
		Assert.assertArrayEquals(crlf_1.getBytes(), result);
	}

	@Test
	public void testRelaxedMixed_CRLF_2_LF() {
		// mixed \n and \r\n to uniform \n
		byte[] result = apply(NewlineFilter.createWin2Nix(true), crlf_2.getBytes());
		Assert.assertArrayEquals(lf_1.getBytes(), result);
	}

	@Test
	public void testRelaxedMixed_LF_2_CRLF() {
		// mixed \n and \r\n to uniform \r\n
		byte[] result = apply(NewlineFilter.createNix2Win(true), lf_2.getBytes());
		Assert.assertArrayEquals(crlf_1.getBytes(), result);
	}

	@Test
	public void testStrictMixed_CRLF_2_LF() {
		final byte[] input = crlf_2.getBytes();
		byte[] result = apply(NewlineFilter.createWin2Nix(false), input);
		Assert.assertArrayEquals(input, result);
	}

	@Test
	public void testStrictMixed_LF_2_CRLF() {
		final byte[] input = lf_2.getBytes();
		byte[] result = apply(NewlineFilter.createNix2Win(false), input);
		Assert.assertArrayEquals(input, result);
	}
	
	@Test
	public void testBufferEndInTheMiddle_CRLF_2_LF() {
		// filter works with ByteBuffer that may end with \r, and the next one starting with \n
		// need to make sure this is handled correctly.
		byte[] i1 = "\r\nA\r\nBC\r".getBytes();
		byte[] i2 = "\n\r\nDEF\r\n".getBytes();
		NewlineFilter nlFilter = NewlineFilter.createWin2Nix(false);
		ByteBuffer input = ByteBuffer.allocate(i1.length + i2.length);
		ByteBuffer res = ByteBuffer.allocate(i1.length + i2.length); // at most of the original size
		nlFilter.preview(ByteBuffer.wrap(i1));
		nlFilter.preview(ByteBuffer.wrap(i2));
		//
		input.put(i1).flip();
		res.put(nlFilter.filter(input));
		Assert.assertTrue("Unpocessed chars shall be left in input buffer", input.remaining() > 0);
		input.compact();
		input.put(i2);
		input.flip();
		res.put(nlFilter.filter(input));
		Assert.assertTrue("Input shall be consumed completely", input.remaining() == 0);
		//
		res.flip();
		byte[] result = new byte[res.remaining()];
		res.get(result);
		Assert.assertArrayEquals(lf_1.getBytes(), result);
		//
		//
		// check the same, with extra \r at the end of first portion
		nlFilter = NewlineFilter.createWin2Nix(false);
		res.clear();
		input.clear();
		input.put(i1).put("\r\r\r".getBytes()).flip();
		// preview requred
		nlFilter.preview(input);
		nlFilter.preview(ByteBuffer.wrap(i2));
		// input.position(0); correctly written preview shall not affect buffer position 
		//
		res.put(nlFilter.filter(input));
		Assert.assertTrue("Unpocessed chars shall be left in input buffer", input.remaining() > 0);
		input.compact();
		input.put(i2);
		input.flip();
		res.put(nlFilter.filter(input));
		Assert.assertTrue("Input shall be consumed completely", input.remaining() == 0);
		res.flip();
		result = new byte[res.remaining()];
		res.get(result);
		Assert.assertArrayEquals(lf_1.getBytes(), result);
	}
	
	@Test
	public void testNoConversionLoneCR() {
		// CRLF -> LF
		final byte[] input = "\r\nA\rBC\r\rDE\r\nFGH".getBytes();
		final byte[] output = "\nA\rBC\r\rDE\nFGH".getBytes();
		byte[] result = apply(NewlineFilter.createWin2Nix(false), input);
		Assert.assertArrayEquals(output, result);
		//
		// LF -> CRLF
		result = apply(NewlineFilter.createNix2Win(false), output);
		Assert.assertArrayEquals(input, result);
	}


	@Test
	public void testNoConversionNeeded_LF_2_LF() {
		final byte[] input = lf_1.getBytes();
		Assert.assertTrue("sanity", indexOf(input, '\r') == -1);
		byte[] result = apply(NewlineFilter.createWin2Nix(false), input);
		Assert.assertArrayEquals(input, result);
	}

	@Test
	public void testNoConversionNeeded_CRLF_2_CRLF() {
		final byte[] input = crlf_1.getBytes();
		byte[] result = apply(NewlineFilter.createNix2Win(false), input);
		Assert.assertArrayEquals(input, result);
	}

	private static byte[] apply(NewlineFilter nlFilter, byte[] input) {
		final ByteBuffer inputBuffer = ByteBuffer.wrap(input);
		nlFilter.preview(inputBuffer);
		// inputBuffer.position(0); correctly written filter shall not affect buffer position
		ByteBuffer result = nlFilter.filter(inputBuffer);
		byte[] res = new byte[result.remaining()];
		result.get(res);
		return res;
	}

	private static int indexOf(byte[] arr, int val) {
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] == val) {
				return i;
			}
		}
		return -1;
	}
}