package com.laytonsmith.core.functions;
import com.laytonsmith.abstraction.MCPlayer;
import com.laytonsmith.core.Static;
import com.laytonsmith.core.constructs.CArray;
import com.laytonsmith.core.constructs.CInt;
import com.laytonsmith.core.constructs.CString;
import com.laytonsmith.core.constructs.Construct;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.environments.CommandHelperEnvironment;
import com.laytonsmith.core.exceptions.CancelCommandException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import com.laytonsmith.testing.C;
import com.laytonsmith.testing.StaticTest;
import static com.laytonsmith.testing.StaticTest.Run;
import static com.laytonsmith.testing.StaticTest.SRun;
import static com.laytonsmith.testing.StaticTest.TestClassDocs;
import static com.laytonsmith.testing.StaticTest.assertCEquals;
import static com.laytonsmith.testing.StaticTest.assertReturn;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
*
*
*/
public class ArrayHandlingTest {
MCPlayer fakePlayer;
CArray commonArray;
com.laytonsmith.core.environments.Environment env;
public ArrayHandlingTest() throws Exception {
StaticTest.InstallFakeServerFrontend();
env = Static.GenerateStandaloneEnvironment();
}
@Before
public void setUp() {
fakePlayer = StaticTest.GetOnlinePlayer();
commonArray = new CArray(Target.UNKNOWN, new CInt(1, Target.UNKNOWN), new CInt(2, Target.UNKNOWN), new CInt(3, Target.UNKNOWN));
env.getEnv(CommandHelperEnvironment.class).SetPlayer(fakePlayer);
}
/**
* Test of docs method, of class ArrayHandling.
*/
@Test(timeout = 10000)
public void testDocs() {
TestClassDocs(ArrayHandling.docs(), ArrayHandling.class);
}
@Test(timeout = 10000)
public void testArraySize() throws Exception, CancelCommandException {
ArrayHandling.array_size a = new ArrayHandling.array_size();
CArray arr = commonArray;
Construct ret = a.exec(Target.UNKNOWN, env, arr);
assertReturn(ret, C.Int);
assertCEquals(C.onstruct(3), ret);
}
@Test(expected = Exception.class, timeout = 10000)
public void testArraySizeEx() throws CancelCommandException {
ArrayHandling.array_size a = new ArrayHandling.array_size();
a.exec(Target.UNKNOWN, env, C.Int(0));
}
@Test//(timeout = 10000)
public void testArraySet1() throws Exception {
String script =
"assign(@array, array(1,2,3)) "
+ "msg(@array) "
+ "array_set(@array, 2, 1) "
+ "msg(@array)";
StaticTest.Run(script, fakePlayer);
verify(fakePlayer).sendMessage("{1, 2, 3}");
verify(fakePlayer).sendMessage("{1, 2, 1}");
}
@Test(timeout = 10000)
public void testArraySet2() throws Exception {
SRun("assign(@array, array(1, 2)) assign(@array2, @array) array_set(@array, 0, 2) msg(@array) msg(@array2)", fakePlayer);
verify(fakePlayer, times(2)).sendMessage("{2, 2}");
}
@Test(timeout = 10000)
public void testArrayReferenceBeingCorrect() throws Exception {
SRun("assign(@array, array(1, 2)) assign(@array2, @array[]) array_set(@array, 0, 2) msg(@array) msg(@array2)", fakePlayer);
verify(fakePlayer).sendMessage("{2, 2}");
verify(fakePlayer).sendMessage("{1, 2}");
}
@Test(timeout = 10000)
public void testArrayReferenceBeingCorrectWithArrayGet() throws Exception {
SRun("assign(@array, array(1, 2)) "
+ "assign(@array2, array_get(@array)) "
+ "array_set(@array, 0, 2) "
+ "msg(@array) "
+ "msg(@array2)", fakePlayer);
verify(fakePlayer).sendMessage("{2, 2}");
verify(fakePlayer).sendMessage("{1, 2}");
}
//This is valid behavior now.
// @Test(expected=ConfigRuntimeException.class)
// public void testArraySetEx() throws CancelCommandException, ConfigCompileException{
// String script =
// "assign(@array, array()) array_set(@array, 3, 1) msg(@array)";
// MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null)), env, null, null);
// }
@Test(timeout = 10000)
public void testArrayContains() throws CancelCommandException {
ArrayHandling.array_contains a = new ArrayHandling.array_contains();
assertCEquals(C.onstruct(true), a.exec(Target.UNKNOWN, env, commonArray, C.onstruct(1)));
assertCEquals(C.onstruct(false), a.exec(Target.UNKNOWN, env, commonArray, C.onstruct(55)));
}
@Test(timeout = 10000)
public void testArraySContains() throws CancelCommandException {
ArrayHandling.array_scontains a = new ArrayHandling.array_scontains();
assertCEquals(C.onstruct(true), a.exec(Target.UNKNOWN, env, commonArray, C.onstruct(1)));
assertCEquals(C.onstruct(false), a.exec(Target.UNKNOWN, env, commonArray, C.onstruct(55)));
assertCEquals(C.onstruct(false), a.exec(Target.UNKNOWN, env, commonArray, new CString("2", Target.UNKNOWN)));
}
@Test(expected = Exception.class, timeout = 10000)
public void testArrayContainsEx() throws CancelCommandException {
ArrayHandling.array_contains a = new ArrayHandling.array_contains();
a.exec(Target.UNKNOWN, env, C.Int(0), C.Int(1));
}
@Test(timeout = 10000)
public void testArrayGet() throws CancelCommandException {
ArrayHandling.array_get a = new ArrayHandling.array_get();
assertCEquals(C.onstruct(1), a.exec(Target.UNKNOWN, env, commonArray, C.onstruct(0)));
}
@Test(expected = Exception.class, timeout = 10000)
public void testArrayGetEx() throws CancelCommandException {
ArrayHandling.array_get a = new ArrayHandling.array_get();
a.exec(Target.UNKNOWN, env, C.Int(0), C.Int(1));
}
@Test(expected = ConfigRuntimeException.class, timeout = 10000)
public void testArrayGetBad() throws CancelCommandException {
ArrayHandling.array_get a = new ArrayHandling.array_get();
a.exec(Target.UNKNOWN, env, commonArray, C.onstruct(55));
}
@Test(timeout = 10000)
public void testArrayPush() throws CancelCommandException {
ArrayHandling.array_push a = new ArrayHandling.array_push();
assertReturn(a.exec(Target.UNKNOWN, env, commonArray, C.onstruct(4)), C.Void);
assertCEquals(C.onstruct(1), commonArray.get(0, Target.UNKNOWN));
assertCEquals(C.onstruct(2), commonArray.get(1, Target.UNKNOWN));
assertCEquals(C.onstruct(3), commonArray.get(2, Target.UNKNOWN));
assertCEquals(C.onstruct(4), commonArray.get(3, Target.UNKNOWN));
}
@Test(timeout = 10000)
public void testArrayPush2() throws Exception {
SRun("assign(@a, array(1))"
+ "array_push(@a, 2, 3)"
+ "msg(@a)", fakePlayer);
verify(fakePlayer).sendMessage("{1, 2, 3}");
}
@Test(expected = Exception.class)
public void testArrayPushEx() throws CancelCommandException {
ArrayHandling.array_push a = new ArrayHandling.array_push();
a.exec(Target.UNKNOWN, env, C.Int(0), C.Int(1));
}
@Test(timeout = 10000)
public void testArrayResize() throws Exception {
String script = "assign(@array, array(1)) msg(@array) array_resize(@array, 2) msg(@array) array_resize(@array, 3, 'hello') msg(@array)";
StaticTest.Run(script, fakePlayer);
verify(fakePlayer).sendMessage("{1}");
verify(fakePlayer).sendMessage("{1, null}");
verify(fakePlayer).sendMessage("{1, null, hello}");
}
/**
* Because we are testing a loop, we put in an infinite loop detection of 10
* seconds
*
* @throws Exception
*/
@Test(timeout = 10000)
public void testRange() throws Exception {
assertEquals("{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}", SRun("range(10)", fakePlayer));
assertEquals("{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}", SRun("range(1, 11)", fakePlayer));
assertEquals("{0, 5, 10, 15, 20, 25}", SRun("range(0, 30, 5)", fakePlayer));
assertEquals("{0, 3, 6, 9}", SRun("range(0, 10, 3)", fakePlayer));
assertEquals("{0, -1, -2, -3, -4, -5, -6, -7, -8, -9}", SRun("range(0, -10, -1)", fakePlayer));
assertEquals("{}", SRun("range(0)", fakePlayer));
assertEquals("{}", SRun("range(1, 0)", fakePlayer));
}
@Test
public void testArraySliceAndNegativeIndexes() throws Exception {
assertEquals("{a, b}", SRun("array(a, b, c, d, e)[..1]", null));
assertEquals("e", SRun("array(a, e)[-1]", null));
assertEquals("{a, b, c, d, e}", SRun("array(a, b, c, d, e)[]", null));
assertEquals("{b, c}", SRun("array(a, b, c, d, e)[1..2]", null));
assertEquals("{b, c, d, e}", SRun("array(a, b, c, d, e)[1..-1]", null));
assertEquals("1", SRun("array(a, array(1, 2), c, d, e)[0..1][1][0]", null));
assertEquals("{c, d, e}", SRun("array(a, b, c, d, e)[2..]", null));
assertEquals("{}", SRun("array(1, 2, 3, 4, 5)[3..0]", null));
assertEquals("{a, b}", SRun("array_get(array(a, b))", null));
assertEquals("{2, 3}", SRun("array(1, 2, 3)[1..-1]", null));
assertEquals("{2}", SRun("array(1, 2)[1..-1]", null));
assertEquals("{}", SRun("array(1)[1..-1]", null));
}
@Test(timeout = 10000)
public void testArrayMergeNormal() throws Exception {
assertEquals("{1, 2, 3, 4, 5, {6, 7}}", SRun("array_merge(array(1, 2, 3), array(4, 5, array(6, 7)))", fakePlayer));
}
@Test(timeout = 10000)
public void testArrayMergeAssociative() throws Exception {
assertEquals("{a: a, b: b, c: c, d: {1, 2}}", SRun("array_merge(array(a: a, b: b), array(c: c, d: array(1, 2)))", fakePlayer));
}
@Test(timeout = 10000)
public void testArrayRemove() throws Exception {
SRun("assign(@a, array(1, 2, 3)) array_remove(@a, 1) msg(@a)", fakePlayer);
verify(fakePlayer).sendMessage("{1, 3}");
SRun("assign(@a, array(a: a, b: b, c: c)) array_remove(@a, 'b') msg(@a)", fakePlayer);
verify(fakePlayer).sendMessage("{a: a, c: c}");
}
@Test(timeout = 10000)
public void testStringSlice() throws Exception {
SRun("msg('slice'[2..])", fakePlayer);
verify(fakePlayer).sendMessage("ice");
}
@Test public void testArraySort1() throws Exception{
Run("msg(array_sort(array(3, 1, 2)))", fakePlayer);
verify(fakePlayer).sendMessage("{1, 2, 3}");
}
@Test public void testArraySort2() throws Exception{
Run("msg(array_sort(array('002', '1', '03')))", fakePlayer);
verify(fakePlayer).sendMessage("{1, 002, 03}");
}
@Test public void testArraySort3() throws Exception{
Run("msg(array_sort(array('002', '1', '03'), STRING))", fakePlayer);
verify(fakePlayer).sendMessage("{002, 03, 1}");
}
@Test public void testArrayImplode1() throws Exception{
Run("msg(array_implode(array(1,2,3,4,5,6,7,8,9,1,2,3,4,5)))", fakePlayer);
verify(fakePlayer).sendMessage("1 2 3 4 5 6 7 8 9 1 2 3 4 5");
}
@Test public void testArrayRemoveValues() throws Exception{
Run("assign(@array, array(1, 2, 2, 3)) array_remove_values(@array, 2) msg(@array)", fakePlayer);
verify(fakePlayer).sendMessage("{1, 3}");
}
@Test public void testArrayIndex() throws Exception{
Run("assign(@array, array(1, 2, 2, 3)) msg(array_index(@array, 2))", fakePlayer);
verify(fakePlayer).sendMessage("1");
}
@Test public void testArrayIndexMissing() throws Exception{
Run("assign(@array, array(1, 3)) msg(array_index(@array, 2))", fakePlayer);
verify(fakePlayer).sendMessage("null");
}
@Test public void testArrayIndexes() throws Exception{
Run("assign(@array, array(1, 2, 2, 3)) msg(array_indexes(@array, 2))", fakePlayer);
verify(fakePlayer).sendMessage("{1, 2}");
}
@Test public void testArrayIndexesMissing() throws Exception{
Run("assign(@array, array(1, 3)) msg(array_indexes(@array, 2))", fakePlayer);
verify(fakePlayer).sendMessage("{}");
}
@Test public void testArrayRand() throws Exception{
assertEquals("{1}", SRun("array_rand(array(1, 1, 1), 1, false)", null));
String output = SRun("array_rand(array('a', 'b', 'c'))", null);
if(!"{0}".equals(output) && !"{1}".equals(output) && !"{2}".equals(output)){
throw new Exception("Did not return the expected value");
}
output = SRun("array_rand(array('a', 'b'), 2)", null);
if(!"{0, 1}".equals(output) && !"{1, 0}".equals(output)){
throw new Exception("Did not return the expected value");
}
}
@Test public void testArrayUnique1() throws Exception {
assertEquals("{1}", SRun("array_unique(array(1, 1, 1), false)", fakePlayer));
}
@Test public void testArrayUnique2() throws Exception {
assertEquals("{1, 1}", SRun("array_unique(array(1, '1'), true)", fakePlayer));
}
@Test public void testArrayUnique3() throws Exception {
assertEquals("{1}", SRun("array_unique(array(1, '1'), false)", fakePlayer));
}
@Test public void testArrayUnique4() throws Exception {
assertEquals("{1, 1}", SRun("array_unique(array(1, '1', 1), true)", fakePlayer));
}
@Test public void testArrayGetClone() throws Exception { // This is expected to be a deep clone.
Run("@a = array(array(array('value'))); @b = @a[]; @b[0][0][0] = 'changedValue'; msg(@a[0][0][0]); msg(@b[0][0][0]);", fakePlayer);
verify(fakePlayer).sendMessage("value");
verify(fakePlayer).sendMessage("changedValue");
}
@Test public void testArrayDeepClone() throws Exception {
Run("@a = array(array(array('value'))); @b = array_deep_clone(@a); @b[0][0][0] = 'changedValue'; msg(@a[0][0][0]); msg(@b[0][0][0]);", fakePlayer);
verify(fakePlayer).sendMessage("value");
verify(fakePlayer).sendMessage("changedValue");
}
@Test public void testArrayShallowClone() throws Exception {
Run("@a = array(array('value')); @b = array_shallow_clone(@a); @b[0][0] = 'changedValue'; msg(equals(@a[0][0], @b[0][0]));"
+ "msg(ref_equals(@a, @b)); msg(@a[0][0])", fakePlayer);
verify(fakePlayer).sendMessage("true");
verify(fakePlayer).sendMessage("false");
verify(fakePlayer).sendMessage("changedValue");
}
@Test public void testArrayGetCloneRefCouples() throws Exception {
Run("@a = array('Meow'); @b = array(@a, @a, array(@a)); @c = @b[]; msg((ref_equals(@c[0], @c[1]) && ref_equals(@c[0], @c[2][0])));", fakePlayer);
verify(fakePlayer).sendMessage("true");
}
@Test public void testArrayGetCloneRecursiveArray() throws Exception {
Run("@a = array(); @b = array(); @a[0] = @b; @b[0] = @a; @c = @a[]; msg((ref_equals(@c[0], @c[0][0][0]) && ref_equals(@c, @c[0][0])));", fakePlayer);
verify(fakePlayer).sendMessage("true");
}
@Test public void testArrayIterate() throws Exception {
Run("@a = array(1, 2, 3); array_iterate(@a, closure(@k, @v){ msg(@v); });", fakePlayer);
verify(fakePlayer).sendMessage("1");
verify(fakePlayer).sendMessage("2");
verify(fakePlayer).sendMessage("3");
}
@Test public void testArrayIterateAssociative() throws Exception {
Run("@a = array(a: 1, b: 2, c: 3); array_iterate(@a, closure(@k, @v){ msg(\"@k: @v\"); });", fakePlayer);
verify(fakePlayer).sendMessage("a: 1");
verify(fakePlayer).sendMessage("b: 2");
verify(fakePlayer).sendMessage("c: 3");
}
@Test public void testArrayReduce() throws Exception {
Run("msg(array_reduce(array(1, 2, 3), closure(@soFar, @next){ return(@soFar + @next); }));", fakePlayer);
verify(fakePlayer).sendMessage("6");
}
@Test public void testArrayReduce2() throws Exception {
Run("msg(array_reduce(array('a', 'b', 'c'), closure(@soFar, @next){ return(@soFar . @next); }));", fakePlayer);
verify(fakePlayer).sendMessage("abc");
}
@Test public void testArrayReduceRight() throws Exception {
Run("msg(array_reduce_right(array(1, 2, 3), closure(@soFar, @next){ return(@soFar + @next); }));", fakePlayer);
verify(fakePlayer).sendMessage("6");
}
@Test public void testArrayReduceRight2() throws Exception {
Run("msg(array_reduce_right(array('a', 'b', 'c'), closure(@soFar, @next){ return(@soFar . @next); }));", fakePlayer);
verify(fakePlayer).sendMessage("cba");
}
@Test public void testArrayEvery1() throws Exception {
Run("msg(array_every(array(1, 1, 1), closure(@value){ return(@value == 1); }));", fakePlayer);
verify(fakePlayer).sendMessage("true");
}
@Test public void testArrayEvery2() throws Exception {
Run("msg(array_every(array(1, 1, 2), closure(@value){ return(@value == 1); }));", fakePlayer);
verify(fakePlayer).sendMessage("false");
}
@Test public void testArrayEvery3() throws Exception {
Run("msg(array_every(array(), closure(@value){ return(@value == 1); }));", fakePlayer);
verify(fakePlayer).sendMessage("true");
}
@Test public void testArraySome1() throws Exception {
Run("msg(array_some (array(1, 1, 2), closure(@value){ return(@value == 1); }));", fakePlayer);
verify(fakePlayer).sendMessage("true");
}
@Test public void testArraySome2() throws Exception {
Run("msg(array_some (array(2, 2, 2), closure(@value){ return(@value == 1); }));", fakePlayer);
verify(fakePlayer).sendMessage("false");
}
@Test public void testArraySome3() throws Exception {
Run("msg(array_some (array(), closure(@value){ return(@value == 1); }));", fakePlayer);
verify(fakePlayer).sendMessage("false");
}
@Test public void testArrayMap() throws Exception {
Run("@areaOfSquare = closure(@sideLength){\n"
+ "\treturn(@sideLength * @sideLength);\n"
+ "};\n"
+ "// A collection of square sides\n"
+ "@squares = array(1, 4, 8);\n"
+ "@areas = array_map(@squares, @areaOfSquare);\n"
+ "msg(@areas);", fakePlayer);
verify(fakePlayer).sendMessage("{1, 16, 64}");
}
@Test public void testArrayReverse() throws Exception {
Run("@array = array(1, 2, 3, 4);\n"
+ "array_reverse(@array);\n"
+ "msg(@array);\n", fakePlayer);
verify(fakePlayer).sendMessage("{4, 3, 2, 1}");
}
}