/* --------------------------------------------------------------------- * Numenta Platform for Intelligent Computing (NuPIC) * Copyright (C) 2014, Numenta, Inc. Unless you have an agreement * with Numenta, Inc., for a separate license for this software code, the * following terms and conditions apply: * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero Public License version 3 as * published by the Free Software Foundation. * * 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 Affero Public License for more details. * * You should have received a copy of the GNU Affero Public License * along with this program. If not, see http://www.gnu.org/licenses. * * http://numenta.org/licenses/ * --------------------------------------------------------------------- */ package org.numenta.nupic.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Collection; import java.util.LinkedHashSet; import java.util.Set; import org.junit.Test; public class NamedTupleTest { @Test public void testCannotIntantiateAsymmetric() { // Test that keys and values are tested for symmetry try { new NamedTuple(new String[] { "one", "two" }, 1, 2, 3); fail(); }catch(Exception e) { assertEquals("Keys and values must be same length.", e.getMessage()); } try { new NamedTuple(new String[] { "one", "two", "three" }, 1, 2); fail(); }catch(Exception e) { assertEquals("Keys and values must be same length.", e.getMessage()); } try { new NamedTuple(new String[] { "one", "two", "three" }, 1, 2, 3); }catch(Exception e) { fail(); } } @Test public void testHashStrategy() { String[][] elementsToAdd = { { "ace", "Very good" }, { "act", "Take action" }, { "add", "Join (something) to something else" }, { "age", "Grow old" }, { "ago", "Before the present" }, { "aid", "Help, assist, or support" }, { "aim", "Point or direct" }, { "air", "Invisible gaseous substance" }, { "all", "Used to refer to the whole quantity" }, { "amp", "Unit of measure for the strength of an electrical current" }, { "and", "Used to connect words" }, { "ant", "A small insect" }, { "any", "Used to refer to one or some of a thing" }, { "ape", "A large primate" }, { "apt", "Appropriate or suitable in the circumstances" }, { "arc", "A part of the circumference of a curve" }, { "are", "Unit of measure, equal to 100 square meters" }, { "ark", "The ship built by Noah" }, { "arm", "Two upper limbs of the human body" }, { "art", "Expression or application of human creative skill" }, { "ash", "Powdery residue left after the burning" }, { "ask", "Say something in order to obtain information" }, { "asp", "Small southern European viper" }, { "ass", "Hoofed mammal" }, { "ate", "To put (food) into the mouth and swallow it" }, { "atm", "Unit of pressure" }, { "awe", "A feeling of reverential respect" }, { "axe", "Edge tool with a heavy bladed head" }, { "aye", "An affirmative answer" } }; NamedTuple nt = new NamedTuple(new String[] { "one", "two", "three" }, 1, 2, 3); assertEquals(nt.get("one"), 1); assertEquals(nt.get("two"), 2); assertEquals(nt.get("three"), 3); assertNull(nt.get("four")); assertNull(nt.get(null)); assertNull(nt.get("")); String[] keys = new String[elementsToAdd.length]; Object[] vals = new Object[elementsToAdd.length]; int i = 0; for(String[] elem : elementsToAdd) { keys[i] = elem[0]; vals[i++] = elem[1]; } nt = new NamedTuple(keys, vals); for(String[] elem : elementsToAdd) { assertEquals(nt.get(elem[0]), elem[1]); } } @Test public void testEquality() { NamedTuple nt = new NamedTuple(new String[] { "one", "two", "three" }, 1, 2, 3); NamedTuple nt2 = new NamedTuple(new String[] { "one", "two", "three" }, 1, 2, 3); assertEquals(nt, nt2); //Test inequality due to (colliding) key order nt = new NamedTuple(new String[] { "one", "two", "three" }, 1, 2, 3); nt2 = new NamedTuple(new String[] { "two", "one", "three" }, 1, 2, 3); assertNotEquals(nt, nt2); //Test inequality due to (non-colliding) key order nt = new NamedTuple(new String[] { "one", "different" }, 1, 3); nt2 = new NamedTuple(new String[] { "different", "one" }, 3, 1); assertNotEquals(nt, nt2); } @Test public void testInterleave() { String[] f = { "0" }; double[] s = { 0.8 }; // Test most simple interleave of equal length arrays Object[] result = NamedTuple.interleave(f, s); assertEquals("0", result[0]); assertEquals(0.8, result[1]); // Test simple interleave of larger array f = new String[] { "0", "1" }; s = new double[] { 0.42, 2.5 }; result = NamedTuple.interleave(f, s); assertEquals("0", result[0]); assertEquals(0.42, result[1]); assertEquals("1", result[2]); assertEquals(2.5, result[3]); // Test complex interleave of larger array f = new String[] { "0", "1", "bob", "harry", "digit", "temperature" }; s = new double[] { 0.42, 2.5, .001, 1e-2, 34.0, .123 }; result = NamedTuple.interleave(f, s); for(int i = 0, j = 0;j < result.length;i++, j+=2) { assertEquals(f[i], result[j]); assertEquals(s[i], result[j + 1]); } // Test interleave with zero length of first f = new String[0]; s = new double[] { 0.42, 2.5 }; result = NamedTuple.interleave(f, s); assertEquals(0.42, result[0]); assertEquals(2.5, result[1]); // Test interleave with zero length of second f = new String[] { "0", "1" }; s = new double[0]; result = NamedTuple.interleave(f, s); assertEquals("0", result[0]); assertEquals("1", result[1]); // Test complex unequal length: left side smaller f = new String[] { "0", "1", "bob" }; s = new double[] { 0.42, 2.5, .001, 1e-2, 34.0, .123 }; result = NamedTuple.interleave(f, s); assertEquals("0", result[0]); assertEquals(0.42, result[1]); assertEquals("1", result[2]); assertEquals(2.5, result[3]); assertEquals("bob", result[4]); assertEquals(.001, result[5]); assertEquals(1e-2, result[6]); assertEquals(34.0, result[7]); assertEquals(.123, result[8]); // Test complex unequal length: right side smaller f = new String[] { "0", "1", "bob", "harry", "digit", "temperature" }; s = new double[] { 0.42, 2.5, .001 }; result = NamedTuple.interleave(f, s); assertEquals("0", result[0]); assertEquals(0.42, result[1]); assertEquals("1", result[2]); assertEquals(2.5, result[3]); assertEquals("bob", result[4]); assertEquals(.001, result[5]); assertEquals("harry", result[6]); assertEquals("digit", result[7]); assertEquals("temperature", result[8]); // Negative testing try { f = null; s = new double[] { 0.42, 2.5, .001 }; result = NamedTuple.interleave(f, s); fail(); }catch(Exception e) { assertEquals(NullPointerException.class, e.getClass()); } } @Test public void testGetValues() { Set<Integer> set = new LinkedHashSet<>(); set.add(1); set.add(2); set.add(3); NamedTuple nt = new NamedTuple(new String[] { "one", "two", "three" }, set.toArray()); Collection<?> values = nt.values(); assertTrue(values.size() == 3); assertTrue(set.containsAll(values) && values.containsAll(set)); } @Test public void testDuplicatesNotAllowed() { try { new NamedTuple(new String[] { "one", "one" }, 1, 2); fail(); }catch(Exception e) { assertEquals(IllegalStateException.class, e.getClass()); assertEquals("Duplicates Not Allowed - Key: one, reinserted.", e.getMessage()); } } @Test public void testHashCodeEquals() { NamedTuple nt0 = new NamedTuple(new String[] { "one", "two" }, 1, 2); NamedTuple nt1 = new NamedTuple(new String[] { "one", "two" }, 1, 2); assertEquals(nt0, nt1); assertEquals(nt0.hashCode(), nt1.hashCode()); NamedTuple nt2 = new NamedTuple(new String[] { "one", "2" }, 1, 2); NamedTuple nt3 = new NamedTuple(new String[] { "one", "two" }, 1, 2); assertNotEquals(nt2, nt3); assertNotEquals(nt2.hashCode(), nt3.hashCode()); String nt0String = "Bucket: 0\n" + "\tkey=two, value=2, hash=0\n"+ "Bucket: 1\n" + "Bucket: 2\n" + "\tkey=one, value=1, hash=2\n"+ "Bucket: 3\n"; assertEquals(nt0String, nt0.toString()); } }