/** * Copyright 2011-2017 Asakusa Framework Team. * * 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.asakusafw.utils.io; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Random; import org.junit.Test; /** * Test for {@link Sources}. */ public class SourcesTest { /** * simple test for {@link Sources#empty()}. * @throws Exception if failed */ @Test public void empty() throws Exception { List<String> objects = dump(Sources.empty()); assertThat(objects, hasSize(0)); } /** * simple test for {@link Sources#wrap(java.util.Iterator)}. * @throws Exception if failed */ @Test public void wrap() throws Exception { List<String> objects = dump(Sources.wrap(iter("1", "2", "3"))); assertThat(objects, contains("1", "2", "3")); } /** * empty elements for {@link Sources#wrap(java.util.Iterator)}. * @throws Exception if failed */ @Test public void wrap_empty() throws Exception { List<String> objects = dump(Sources.wrap(SourcesTest.iter())); assertThat(objects, hasSize(0)); } /** * Test method for {@link Sources#concat(java.util.List)}. * @throws Exception if failed */ @Test public void concat() throws Exception { List<Source<String>> sources = new ArrayList<>(); sources.add(Sources.wrap(iter("1", "2"))); sources.add(Sources.wrap(iter("3", "4"))); sources.add(Sources.wrap(iter("5", "6"))); List<String> objects = dump(Sources.concat(sources)); assertThat(objects, contains("1", "2", "3", "4", "5", "6")); } /** * empty elements for {@link Sources#concat(java.util.List)}. * @throws Exception if failed */ @Test public void concat_empty() throws Exception { List<Source<String>> sources = new ArrayList<>(); List<String> objects = dump(Sources.concat(sources)); assertThat(objects, hasSize(0)); } /** * Test method for {@link Sources#merge(java.util.List, java.util.Comparator)}. */ @Test public void merge() { List<Source<IntBuf>> cursors = new ArrayList<>(); cursors.add(Sources.wrap(array(1, 4, 7))); cursors.add(Sources.wrap(array(2, 5, 8))); cursors.add(Sources.wrap(array(3, 6, 9))); check(Sources.merge(cursors, IntBuf.COMPARATOR), 1, 2, 3, 4, 5, 6, 7, 8, 9); } /** * Test method for {@link Sources#merge(java.util.List, java.util.Comparator)}. */ @Test public void merge_empty() { List<Source<IntBuf>> cursors = new ArrayList<>(); check(Sources.merge(cursors, IntBuf.COMPARATOR)); } /** * Test method for {@link Sources#merge(java.util.List, java.util.Comparator)}. */ @Test public void merge_single() { List<Source<IntBuf>> cursors = new ArrayList<>(); cursors.add(Sources.wrap(array(1, 2, 3))); check(Sources.merge(cursors, IntBuf.COMPARATOR), 1, 2, 3); } /** * Test method for {@link Sources#merge(java.util.List, java.util.Comparator)}. * @throws Exception if failed */ @Test public void merge_large() throws Exception { int base = 1000000; List<Source<IntBuf>> cursors = new ArrayList<>(); cursors.add(new IntSource(random(new Random(6502 + 0), base * 3))); cursors.add(new IntSource(random(new Random(6502 + 1), base * 3))); cursors.add(new IntSource(random(new Random(6502 + 2), base * 4))); int last = -1; int count = 0; try (Source<IntBuf> c = Sources.merge(cursors, IntBuf.COMPARATOR)) { while (c.next()) { int next = c.get().value; assertTrue(last <= next); last = next; count++; } } assertThat(count, is(base * 10)); } /** * Test method for {@link Sources#merge(java.util.List, java.util.Comparator)}. * @throws Exception if failed */ @Test public void merge_many() throws Exception { int numSources = 1000; int base = 1000; List<Source<IntBuf>> cursors = new ArrayList<>(); for (int i = 0; i < numSources; i++) { cursors.add(new IntSource(random(new Random(6502 + i), base))); } int last = -1; int count = 0; try (Source<IntBuf> c = Sources.merge(cursors, IntBuf.COMPARATOR)) { while (c.next()) { int next = c.get().value; assertTrue(last <= next); last = next; count++; } } assertThat(count, is(base * numSources)); } private IntBuf[] array(int... values) { IntBuf[] results = new IntBuf[values.length]; for (int i = 0; i < results.length; i++) { results[i] = new IntBuf(values[i]); } return results; } private int[] random(Random random, int count) { int[] array = new int[count]; for (int i = 0; i < array.length; i++) { array[i] = random.nextInt(Integer.MAX_VALUE); } Arrays.sort(array); return array; } private void check(Source<IntBuf> cursor, int... values) { try { for (int i = 0; i < values.length; i++) { assertTrue(cursor.next()); assertEquals(values[i], cursor.get().value); } assertFalse(cursor.next()); } catch (Exception e) { throw new AssertionError(e); } finally { try { cursor.close(); } catch (IOException e) { throw new AssertionError(e); } } } private static final class IntBuf implements Comparable<IntBuf> { static final Comparator<IntBuf> COMPARATOR = new Comparator<IntBuf>() { @Override public int compare(IntBuf o1, IntBuf o2) { return o1.compareTo(o2); } }; int value; IntBuf(int value) { this.value = value; } @Override public int compareTo(IntBuf o) { return Integer.compare(value, o.value); } @Override public int hashCode() { return value; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } IntBuf other = (IntBuf) obj; if (value != other.value) { return false; } return true; } @Override public String toString() { return String.valueOf(value); } } private static final class IntSource implements Source<IntBuf> { private final int[] array; private int position = -1; private final IntBuf next = new IntBuf(-1); public IntSource(int[] values) { this.array = values; } @Override public boolean next() throws IOException, InterruptedException { if (position + 1 < array.length) { next.value = array[++position]; return true; } else { next.value = -1; return false; } } @Override public IntBuf get() throws IOException, InterruptedException { if (next.value == -1) { throw new NoSuchElementException(); } return next; } @Override public void close() { return; } } @SafeVarargs private static <T> Iterator<T> iter(T... values) { return Arrays.asList(values).iterator(); } private <T> List<T> dump(Source<T> source) throws IOException, InterruptedException { try { List<T> results = new ArrayList<>(); while (source.next()) { results.add(source.get()); } return results; } finally { source.close(); } } }