package com.laytonsmith.testing;
import com.laytonsmith.abstraction.MCPlayer;
import com.laytonsmith.core.exceptions.CRE.CRECastException;
import com.laytonsmith.core.exceptions.CRE.CREIndexOverflowException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import static com.laytonsmith.testing.StaticTest.SRun;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
*
*
*/
public class ArrayTest {
MCPlayer fakePlayer;
public ArrayTest() {
}
@BeforeClass
public static void setUpClass(){
}
@Before
public void setUp() {
fakePlayer = StaticTest.GetOnlinePlayer();
}
@Test public void testAssociativeCreation() throws Exception{
assertEquals("{0: 0, 1: 1}", SRun("array(0: 0, 1: 1)", fakePlayer));
}
@Test public void testAssociativeCreation2() throws Exception{
SRun("assign(@arr, array(0, 1))"
+ "msg(@arr)"
+ "array_set(@arr, 2, 2)"
+ "msg(@arr)"
+ "array_set(@arr, 0, 0)"
+ "msg(@arr)"
+ "array_set(@arr, 'key', 'value')"
+ "msg(@arr)"
+ "array_set(@arr, 10, 'value')"
+ "msg(@arr)",
fakePlayer);
verify(fakePlayer).sendMessage("{0, 1}");
verify(fakePlayer, times(2)).sendMessage("{0, 1, 2}");
verify(fakePlayer).sendMessage("{0: 0, 1: 1, 2: 2, key: value}");
verify(fakePlayer).sendMessage("{0: 0, 1: 1, 10: value, 2: 2, key: value}");
}
@Test public void testArrayGetWithAssociativeArray() throws Exception{
assertEquals("test", SRun("g(assign(@arr, array()) array_set(@arr, 'val', 'test')) array_get(@arr, 'val')", fakePlayer));
}
@Test(expected=ConfigRuntimeException.class)
public void testAssociativeSlicing() throws Exception{
SRun("array(0: 0, 1: 1, 2: 2)[1..-1]", fakePlayer);
}
@Test public void testAssociativeCopy() throws Exception{
SRun("assign(@arr, array(0: 0, 1: 1))"
+ "assign(@arr2, @arr[])"
+ "array_set(@arr2, 0, 1)"
+ "msg(@arr)"
+ "msg(@arr2)", fakePlayer);
verify(fakePlayer).sendMessage("{0: 0, 1: 1}");
verify(fakePlayer).sendMessage("{0: 1, 1: 1}");
}
@Test public void testArrayKeyNormalization() throws Exception{
assertEquals("{0: 0}", SRun("array(false: 0)", fakePlayer));
assertEquals("{false: 0}", SRun("array('false': 0)", fakePlayer));
assertEquals("{1: 1}", SRun("array(true: 1)", fakePlayer));
assertEquals("{true: 1}", SRun("array('true': 1)", fakePlayer));
assertEquals("{: empty}", SRun("array(null: empty)", fakePlayer));
assertEquals("{null: empty}", SRun("array('null': empty)", fakePlayer));
assertEquals("{2.3: 2.3}", SRun("array(2.3: 2.3)", fakePlayer));
assertEquals("{0.3: 0.3}", SRun("array(.3: .3)", fakePlayer));
assertEquals("{.3: 0.3}", SRun("array('.3': .3)", fakePlayer));
}
@Test public void testArrayKeys() throws Exception{
assertEquals("{0, 1, potato}", SRun("array_keys(array(potato: 5, 1: 44, 0: 'i can count to'))", fakePlayer));
}
@Test public void testArrayNormalize() throws Exception{
assertEquals("{3, 2, 1}", SRun("array_normalize(array(0: 3, 1: 2, 2: 1))", fakePlayer));
}
@Test public void testArrayPushOnAssociativeArray() throws Exception{
SRun("assign(@arr, array(0: 0, 1: 1, potato: potato))"
+ "msg(@arr)"
+ "array_push(@arr, tomato)"
+ "msg(@arr)", fakePlayer);
verify(fakePlayer).sendMessage("{0: 0, 1: 1, potato: potato}");
verify(fakePlayer).sendMessage("{0: 0, 1: 1, 2: tomato, potato: potato}");
}
@Test public void testPushingANegativeIndexOnArray() throws Exception{
SRun("assign(@arr, array(0, 1, 2))"
+ "array_set(@arr, -1, -1)"
+ "msg(@arr[-1])", fakePlayer);
verify(fakePlayer).sendMessage("-1");
}
@Test public void testAssociativeArraySerialization() throws Exception{
when(fakePlayer.isOp()).thenReturn(true);
SRun("assign(@arr, array(0: 0, 1: 1, potato: potato))"
+ "store_value(potato, @arr)"
+ "msg(get_value(potato))", fakePlayer);
verify(fakePlayer).sendMessage("{0: 0, 1: 1, potato: potato}");
}
@Test public void testIsAssociative() throws Exception{
assertEquals("true", SRun("is_associative(array(1: 1))", fakePlayer));
assertEquals("false", SRun("is_associative(array(1))", fakePlayer));
}
@Test public void testFunctionResultAsAssociativeValue() throws Exception{
assertEquals("{1: this was concated, 2: this was too}", SRun("array(1: this was concated, 2: this was too)", fakePlayer));
assertEquals("{1: thiswasconcated}", SRun("array(1: concat('this', was, concated))", fakePlayer));
}
@Test public void testDocumentationExample1() throws Exception{
SRun("assign(@arr, array('string key': 'value', 'string key 2': 'value')) msg(@arr['string key'])", fakePlayer);
verify(fakePlayer).sendMessage("value");
}
@Test public void testDocumentationExample2() throws Exception{
SRun("assign(@arr, array(0, 1, 2, 3)) "
+ "msg(is_associative(@arr))"
+ "array_set(@arr, 4, 4)"
+ "msg(is_associative(@arr))"
+ "array_set(@arr, 0, 0)"
+ "msg(is_associative(@arr))"
+ "array_push(@arr, 5)"
+ "msg(is_associative(@arr))"
+ "msg(@arr)"
+ "array_set(@arr, 'key', 'value')"
+ "msg(is_associative(@arr))"
, fakePlayer);
verify(fakePlayer, times(4)).sendMessage("false");
verify(fakePlayer).sendMessage("{0, 1, 2, 3, 4, 5}");
verify(fakePlayer).sendMessage("true");
}
@Test public void testDocumentationExample3() throws Exception{
SRun("assign(@arr, array(0, 1: 1, 2, 3: 3, a: 'a'))"
+ "msg(array_keys(@arr))"
, fakePlayer);
verify(fakePlayer).sendMessage("{0, 1, 2, 3, a}");
}
@Test public void testDocumentationExample4() throws Exception{
SRun("msg(array(0: 0, 2: 2, 1))", fakePlayer);
SRun("assign(@arr, array()) array_set(@arr, 0, 0) array_set(@arr, 2, 2) array_push(@arr, 1)", fakePlayer);
verify(fakePlayer).sendMessage("{0: 0, 2: 2, 3: 1}");
}
@Test public void testDocumentationExample5() throws Exception{
SRun("assign(@arr, array(0, 1: 1, 2, 3: 3, a: 'a'))\n"
+ "foreach(array_keys(@arr), @key, #array_keys returns {0, 1, 2, 3, a}\n"
+ "msg(@arr[@key]) #Messages the value\n"
+ ")", fakePlayer);
verify(fakePlayer).sendMessage("0");
verify(fakePlayer).sendMessage("1");
verify(fakePlayer).sendMessage("2");
verify(fakePlayer).sendMessage("3");
verify(fakePlayer).sendMessage("a");
}
@Test public void testDocumentationExample6() throws Exception{
SRun("assign(@arr, array(-1: -1, 0, 1, 2: 2)) msg(@arr[-1])", fakePlayer);
verify(fakePlayer).sendMessage("-1");
}
@Test public void testDocumentationExample7() throws Exception{
SRun("assign(@arr, array(-1: -1, 0, 1, 2: 2)) msg(@arr)", fakePlayer);
verify(fakePlayer).sendMessage("{-1: -1, 0: 0, 1: 1, 2: 2}");
}
@Test public void testArraysReference1() throws Exception{
assertEquals("3", SRun("proc(_test, @array, return(array_size(@array))) _test(array(1, 2, 3))", fakePlayer));
}
@Test public void testArraysReturned() throws Exception{
SRun("proc(_test, return(array(1, 2, 3))) foreach(_test(), @i, msg(@i))", fakePlayer);
verify(fakePlayer).sendMessage("1");
verify(fakePlayer).sendMessage("2");
verify(fakePlayer).sendMessage("3");
}
@Test public void testArrayception1() throws Exception{
SRun("assign(@t, array("
+ " bla: 1, "
+ " tro: array('a', 'b')"
+ " )"
+ ")"
+ "foreach(array_keys(@t), @u,"
+ " msg(is_array(@t[@u]))"
+ ")", fakePlayer);
verify(fakePlayer).sendMessage("false");
verify(fakePlayer).sendMessage("true");
}
@Test public void testArrayception2() throws Exception{
when(fakePlayer.isOp()).thenReturn(Boolean.TRUE);
SRun("assign(@t, array(bla: 1))"
+ "array_set(@t, 'tro', array(a, b))"
+ "foreach(array_keys(@t), @u,"
+ " msg(is_array(@t[@u]))"
+ ")"
+ "store_value('bugtest_bug4', @t) "
+ "assign(@t, null) "
+ "assign(@t, get_value('bugtest_bug4')) "
+ "foreach(array_keys(@t), @u, "
+ " msg(is_array(@t[@u]))"
+ ")", fakePlayer);
verify(fakePlayer, times(2)).sendMessage("false");
verify(fakePlayer, times(2)).sendMessage("true");
}
@Test public void testArrayNPE1() throws Exception{
SRun("assign(@glyphs, array('0': 6, '1': 6,))"
+ "msg(array_index_exists(@glyphs, '1'))", fakePlayer);
verify(fakePlayer).sendMessage("true");
}
@Test public void testArrayKeys1() throws Exception{
SRun("assign(@a, array('1 ': 1, ' 1 ': 3)) msg(@a)", fakePlayer);
verify(fakePlayer).sendMessage("{ 1 : 3, 1 : 1}");
}
@Test public void testArrayAssign1() throws Exception{
SRun("assign(@array, array())\n"
+ "assign(@array[0], 'value')\n"
+ "msg(@array[0])", fakePlayer);
verify(fakePlayer).sendMessage("value");
}
@Test public void testArrayAssign2() throws Exception{
//Essentially, we want to replicate the behavior of java
String value = "value";
String[] array = new String[1];
array[0] = value;
value = "failure";
SRun("assign(@value, 'value')\n"
+ "assign(@array, array())\n"
+ "assign(@array[0], @value)\n"
+ "assign(@value, 'failure')\n"
+ "msg(@array[0])", fakePlayer);
verify(fakePlayer).sendMessage(array[0]);
}
@Test public void testArrayAssign3() throws Exception{
String value = "value";
String[][] arrayOut = new String[1][1];
String[] arrayIn = new String[1];
arrayOut[0] = arrayIn;
arrayIn[0] = value;
value = "failure";
SRun("assign(@value, 'value')\n"
+ "assign(@arrayOut, array())\n"
+ "assign(@arrayIn, array())\n"
+ "assign(@arrayOut[0], @arrayIn)\n"
+ "assign(@arrayIn[0], @value)\n"
+ "msg(@arrayOut[0][0])", fakePlayer);
verify(fakePlayer).sendMessage(arrayOut[0][0]);
}
@Test public void testArrayAssign4() throws Exception{
SRun("assign(@array, array(outer: array(middle: array(inner: failure))))"
+ "assign(@array['outer']['middle']['inner'], 'value')\n"
+ "msg(@array['outer']['middle']['inner'])", fakePlayer);
verify(fakePlayer).sendMessage("value");
}
@Test public void testArrayAssign5() throws Exception{
SRun("assign(@array['outer']['middle']['inner'], 'value')\n"
+ "msg(@array)\n"
+ "msg(@array['outer']['middle']['inner'])", fakePlayer);
verify(fakePlayer).sendMessage("{outer: {middle: {inner: value}}}");
verify(fakePlayer).sendMessage("value");
}
@Test public void testArrayAssign6() throws Exception{
SRun("assign(@array, array(1))\n"
+ "assign(@array[1], 2)\n"
+ "msg(@array)", fakePlayer);
verify(fakePlayer).sendMessage("{1, 2}");
}
@Test public void testArrayAssign7() throws Exception{
SRun("assign(@array, array(1: 1))\n"
+ "assign(@array[0], array(1))\n"
+ "assign(@array[0][1], 2)\n"
+ "msg(@array)", fakePlayer);
verify(fakePlayer).sendMessage("{0: {1, 2}, 1: 1}");
}
@Test public void testInnerArrayIsArray() throws Exception{
SRun("assign(@pdata, array(value: array(1)))\n"
+ "msg(array_size(@pdata[value]))", fakePlayer);
verify(fakePlayer).sendMessage("1");
}
@Test public void testArrayKeysSortOrder() throws Exception{
for(int i = 0; i < 5; i++){
SRun("assign(@array, array())"
+ "array_push(@array, array(1))"
+ "array_push(@array, array(2))"
+ "array_push(@array, array(3))"
+ "foreach(array_keys(@array), @key, msg(@key))", fakePlayer);
verify(fakePlayer).sendMessage("0");
verify(fakePlayer).sendMessage("1");
verify(fakePlayer).sendMessage("2");
setUp();
}
}
@Test public void testArrayKeysSortOrderWithPersistence() throws Exception{
for(int i = 0; i < 5; i++){
InOrder inOrder = inOrder(fakePlayer);
when(fakePlayer.isOp()).thenReturn(true);
SRun("assign(@array, array())"
+ "array_push(@array, array(1))"
+ "array_push(@array, array(2))"
+ "array_push(@array, array(3))"
+ "store_value('array', @array)"
+ "assign(@array2, get_value('array'))"
+ "foreach(array_keys(@array2), @key, msg(@key))", fakePlayer);
inOrder.verify(fakePlayer).sendMessage("0");
inOrder.verify(fakePlayer).sendMessage("1");
inOrder.verify(fakePlayer).sendMessage("2");
setUp();
}
}
@Test public void testArrayForeachWithConstructorInitialization() throws Exception{
SRun("assign(@pdata, array('some': 'thing', 'is': 67890, 'over': 'there'))"
+ " msg(@pdata['some'])"
+ " foreach(@pdata, @thing, msg(@thing))", fakePlayer);
verify(fakePlayer, times(2)).sendMessage("thing");
verify(fakePlayer).sendMessage("67890");
verify(fakePlayer).sendMessage("there");
}
@Test public void testComplexGetter() throws Exception{
SRun("assign(@array, array(blah: 'blarg'))"
+ "msg(@array[to_lower('BLAH')])", fakePlayer);
verify(fakePlayer).sendMessage("blarg");
}
@Test(expected = CREIndexOverflowException.class)
public void testArrayUsageBeforeDefined() throws Exception{
SRun("@a[1]", fakePlayer);
}
@Test public void testDirectSquareBracketUsage() throws Exception{
SRun("msg(array(0, 1, 2)[0])", fakePlayer);
verify(fakePlayer).sendMessage("0");
}
@Test public void testArraySets() throws Exception{
SRun("@arr = array()\n"
+ "array_set(@arr,0,array())\n"
+ "array_remove(@arr,0)\n"
+ "array_set(@arr,0,array())", fakePlayer);
}
@Test public void testArraySetWithInternalVariable() throws Exception {
SRun("@array = associative_array()\n"
+ "@value = 'herp'\n"
+ "@md5 = md5(@value)\n"
+ "@array[md5(@value)] = 'derp'\n"
+ "msg(string(@array) == '{'.@md5.': derp}')", fakePlayer);
verify(fakePlayer).sendMessage("true");
}
@Test public void testArrayPushOperator() throws Exception {
SRun("@array = array()\n"
+ "@array[] = 'value'\n"
+ "msg(string(@array) == '{value}')", fakePlayer);
verify(fakePlayer).sendMessage("true");
}
//Data is lost in the compiler somewhere, so this isn't as easy to fix in
//the master branch. This test will be re-added in the NewCompiler branch.
// @Test(expected = ConfigCompileException.class)
// public void testArrayPushOperatorFailure() throws Exception {
// SRun("@array = array()\n"
// + "@array[] = array()\n"
// + "@array[][] = 5\n", fakePlayer);
// }
@Test public void testArrayMultiDimension() throws Exception {
SRun("@a = array()\n"
+ "@a[1][2] = 5\n"
+ "msg(@a[1][2])", fakePlayer);
verify(fakePlayer).sendMessage("5");
}
@Test public void testArrayPostIncrement() throws Exception {
SRun("@a = array(1)\n"
+ "(@a[0]++)\n"
+ "msg(@a[0])", fakePlayer);
verify(fakePlayer).sendMessage("2");
}
@Test public void testArrayPreIncrement() throws Exception {
SRun("@a = array(1)\n"
+ "(++@a[0])\n"
+ "msg(@a[0])", fakePlayer);
verify(fakePlayer).sendMessage("2");
}
@Test public void testArrayPostDecrement() throws Exception {
SRun("@a = array(1)\n"
+ "(@a[0]--)\n"
+ "msg(@a[0])", fakePlayer);
verify(fakePlayer).sendMessage("0");
}
@Test public void testArrayPreDecrement() throws Exception {
SRun("@a = array(1)\n"
+ "(--@a[0])\n"
+ "msg(@a[0])", fakePlayer);
verify(fakePlayer).sendMessage("0");
}
@Test
public void testArrayRecursionToString() throws Exception {
SRun("@a = array(); @b = array(@a); @a[] = @b; msg(@a);", fakePlayer);
verify(fakePlayer).sendMessage("{{{*recursion*}}}");
}
@Test
public void testArraySiblingsToString() throws Exception {
SRun("@a = array(); @b = array(); @a[] = @b; @a[] = @b; msg(@a);", fakePlayer);
verify(fakePlayer).sendMessage("{{}, {}}");
}
}