| /* |
| * Copyright (C) 2011 The Guava Authors |
| * |
| * 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.google.common.hash; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.hash.HashTestUtils.RandomHasherAction; |
| import java.io.ByteArrayOutputStream; |
| import java.nio.ByteBuffer; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Random; |
| import junit.framework.TestCase; |
| |
| /** Tests for AbstractNonStreamingHashFunction. */ |
| public class AbstractNonStreamingHashFunctionTest extends TestCase { |
| /** |
| * Constructs two trivial HashFunctions (output := input), one streaming and one non-streaming, |
| * and checks that their results are identical, no matter which newHasher version we used. |
| */ |
| public void testExhaustive() { |
| List<Hasher> hashers = |
| ImmutableList.of( |
| new StreamingVersion().newHasher(), |
| new StreamingVersion().newHasher(52), |
| new NonStreamingVersion().newHasher(), |
| new NonStreamingVersion().newHasher(123)); |
| Random random = new Random(0); |
| for (int i = 0; i < 200; i++) { |
| RandomHasherAction.pickAtRandom(random).performAction(random, hashers); |
| } |
| HashCode[] codes = new HashCode[hashers.size()]; |
| for (int i = 0; i < hashers.size(); i++) { |
| codes[i] = hashers.get(i).hash(); |
| } |
| for (int i = 1; i < codes.length; i++) { |
| assertEquals(codes[i - 1], codes[i]); |
| } |
| } |
| |
| public void testPutStringWithLowSurrogate() { |
| // we pad because the dummy hash function we use to test this, merely copies the input into |
| // the output, so the input must be at least 32 bits, since the output has to be that long |
| assertPutString(new char[] {'p', HashTestUtils.randomLowSurrogate(new Random())}); |
| } |
| |
| public void testPutStringWithHighSurrogate() { |
| // we pad because the dummy hash function we use to test this, merely copies the input into |
| // the output, so the input must be at least 32 bits, since the output has to be that long |
| assertPutString(new char[] {'p', HashTestUtils.randomHighSurrogate(new Random())}); |
| } |
| |
| public void testPutStringWithLowHighSurrogate() { |
| assertPutString( |
| new char[] { |
| HashTestUtils.randomLowSurrogate(new Random()), |
| HashTestUtils.randomHighSurrogate(new Random()) |
| }); |
| } |
| |
| public void testPutStringWithHighLowSurrogate() { |
| assertPutString( |
| new char[] { |
| HashTestUtils.randomHighSurrogate(new Random()), |
| HashTestUtils.randomLowSurrogate(new Random()) |
| }); |
| } |
| |
| private static void assertPutString(char[] chars) { |
| Hasher h1 = new NonStreamingVersion().newHasher(); |
| Hasher h2 = new NonStreamingVersion().newHasher(); |
| String s = new String(chars); |
| // this is the correct implementation of the spec |
| for (int i = 0; i < s.length(); i++) { |
| h1.putChar(s.charAt(i)); |
| } |
| h2.putUnencodedChars(s); |
| assertEquals(h1.hash(), h2.hash()); |
| } |
| |
| static class StreamingVersion extends AbstractHashFunction { |
| @Override |
| public int bits() { |
| return 32; |
| } |
| |
| @Override |
| public Hasher newHasher() { |
| return new AbstractStreamingHasher(4, 4) { |
| final ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| |
| @Override |
| protected HashCode makeHash() { |
| return HashCode.fromBytes(out.toByteArray()); |
| } |
| |
| @Override |
| protected void process(ByteBuffer bb) { |
| while (bb.hasRemaining()) { |
| out.write(bb.get()); |
| } |
| } |
| |
| @Override |
| protected void processRemaining(ByteBuffer bb) { |
| while (bb.hasRemaining()) { |
| out.write(bb.get()); |
| } |
| } |
| }; |
| } |
| } |
| |
| static class NonStreamingVersion extends AbstractNonStreamingHashFunction { |
| @Override |
| public int bits() { |
| return 32; |
| } |
| |
| @Override |
| public HashCode hashBytes(byte[] input, int off, int len) { |
| return HashCode.fromBytes(Arrays.copyOfRange(input, off, off + len)); |
| } |
| } |
| } |