139 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Java
		
	
	
	
| /*
 | |
|  * 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));
 | |
|     }
 | |
|   }
 | |
| }
 |