1/*
2 * Copyright (C) 2012 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14
15package com.google.common.hash;
16
17import static com.google.common.base.Charsets.UTF_16LE;
18import static org.junit.Assert.assertArrayEquals;
19
20import junit.framework.TestCase;
21
22import java.io.ByteArrayOutputStream;
23import java.io.UnsupportedEncodingException;
24import java.util.Random;
25
26/**
27 * Tests for AbstractByteHasher.
28 *
29 * @author Colin Decker
30 */
31public class AbstractByteHasherTest extends TestCase {
32
33  public void testBytes() {
34    TestHasher hasher = new TestHasher(); // byte order insignificant here
35    byte[] expected = {1, 2, 3, 4, 5, 6, 7, 8};
36    hasher.putByte((byte) 1);
37    hasher.putBytes(new byte[]{2, 3, 4, 5, 6});
38    hasher.putByte((byte) 7);
39    hasher.putBytes(new byte[]{});
40    hasher.putBytes(new byte[]{8});
41    hasher.assertBytes(expected);
42  }
43
44  public void testShort() {
45    TestHasher hasher = new TestHasher();
46    hasher.putShort((short) 0x0201);
47    hasher.assertBytes(new byte[]{1, 2});
48  }
49
50  public void testInt() {
51    TestHasher hasher = new TestHasher();
52    hasher.putInt(0x04030201);
53    hasher.assertBytes(new byte[]{1, 2, 3, 4});
54  }
55
56  public void testLong() {
57    TestHasher hasher = new TestHasher();
58    hasher.putLong(0x0807060504030201L);
59    hasher.assertBytes(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});
60  }
61
62  public void testChar() {
63    TestHasher hasher = new TestHasher();
64    hasher.putChar((char) 0x0201);
65    hasher.assertBytes(new byte[]{1, 2});
66  }
67
68  public void testString() throws UnsupportedEncodingException {
69    Random random = new Random();
70    for (int i = 0; i < 100; i++) {
71      byte[] bytes = new byte[64];
72      random.nextBytes(bytes);
73      String s = new String(bytes, UTF_16LE.name()); // so all random strings are valid
74      assertEquals(
75          new TestHasher().putString(s).hash(),
76          new TestHasher().putBytes(s.getBytes(UTF_16LE.name())).hash());
77      assertEquals(
78          new TestHasher().putString(s).hash(),
79          new TestHasher().putString(s, UTF_16LE).hash());
80    }
81  }
82
83  public void testFloat() {
84    TestHasher hasher = new TestHasher();
85    hasher.putFloat(Float.intBitsToFloat(0x04030201));
86    hasher.assertBytes(new byte[]{1, 2, 3, 4});
87  }
88
89  public void testDouble() {
90    TestHasher hasher = new TestHasher();
91    hasher.putDouble(Double.longBitsToDouble(0x0807060504030201L));
92    hasher.assertBytes(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});
93  }
94
95  public void testCorrectExceptions() {
96    TestHasher hasher = new TestHasher();
97    try {
98      hasher.putBytes(new byte[8], -1, 4);
99      fail();
100    } catch (IndexOutOfBoundsException expected) {
101    }
102    try {
103      hasher.putBytes(new byte[8], 0, 16);
104      fail();
105    } catch (IndexOutOfBoundsException expected) {
106    }
107    try {
108      hasher.putBytes(new byte[8], 0, -1);
109      fail();
110    } catch (IndexOutOfBoundsException expected) {
111    }
112  }
113
114  private class TestHasher extends AbstractByteHasher {
115
116    private final ByteArrayOutputStream out = new ByteArrayOutputStream();
117
118    @Override
119    protected void update(byte b) {
120      out.write(b);
121    }
122
123    @Override
124    protected void update(byte[] b, int off, int len) {
125      out.write(b, off, len);
126    }
127
128    byte[] bytes() {
129      return out.toByteArray();
130    }
131
132    void assertBytes(byte[] expected) {
133      assertArrayEquals(expected, bytes());
134    }
135
136    @Override
137    public HashCode hash() {
138      return HashCode.fromBytesNoCopy(bytes());
139    }
140  }
141}
142