/******************************************************************************* * (c) Copyright 2016 Hewlett-Packard Development Company, L.P. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License v2.0 which accompany this distribution. * * The Apache License is available at * http://www.apache.org/licenses/LICENSE-2.0 * *******************************************************************************/ package io.cloudslang.lang.runtime.bindings; import io.cloudslang.lang.entities.ListLoopStatement; import io.cloudslang.lang.entities.LoopStatement; import io.cloudslang.lang.entities.SystemProperty; import io.cloudslang.lang.entities.bindings.ScriptFunction; import io.cloudslang.lang.entities.bindings.values.Value; import io.cloudslang.lang.entities.bindings.values.ValueFactory; import io.cloudslang.lang.runtime.bindings.scripts.ScriptEvaluator; import io.cloudslang.lang.runtime.env.Context; import io.cloudslang.lang.runtime.env.ForLoopCondition; import io.cloudslang.lang.runtime.env.LoopCondition; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.tuple.Pair; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.python.google.common.collect.Lists; import static org.mockito.Matchers.anyMapOf; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.anySetOf; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class LoopsBindingTest { @SuppressWarnings("unchecked") private static final Set<SystemProperty> EMPTY_SET = Collections.EMPTY_SET; @SuppressWarnings("unchecked") private static final Set<ScriptFunction> EMPTY_FUNCTION_SET = Collections.EMPTY_SET; @Rule public ExpectedException exception = ExpectedException.none(); @InjectMocks private LoopsBinding loopsBinding = new LoopsBinding(); @Mock private ScriptEvaluator scriptEvaluator; private LoopStatement createBasicForStatement() { return new ListLoopStatement("x", "[1]", new HashSet<ScriptFunction>(), new HashSet<String>(), false); } @Test public void whenValueIsNotThereItWillBeCreated() throws Exception { Context context = mock(Context.class); ArrayList<Value> result = Lists.newArrayList(ValueFactory.create(1)); when(scriptEvaluator.evalExpr( anyString(), anyMapOf(String.class, Value.class), anySetOf(SystemProperty.class), anySetOf(ScriptFunction.class)) ).thenReturn(ValueFactory.create(result)); Value loopCondition = ValueFactory.create(new ForLoopCondition(result)); when(context.getLanguageVariable(LoopCondition.LOOP_CONDITION_KEY)).thenReturn(null); context.putLanguageVariable(LoopCondition.LOOP_CONDITION_KEY, loopCondition); when(context.getLanguageVariable(LoopCondition.LOOP_CONDITION_KEY)).thenReturn(loopCondition); loopsBinding.getOrCreateLoopCondition(createBasicForStatement(), context, EMPTY_SET, "node"); verify(context).putLanguageVariable(LoopCondition.LOOP_CONDITION_KEY, loopCondition); } @Test public void whenExpressionIsEmptyThrowsException() throws Exception { Context context = mock(Context.class); when(scriptEvaluator.evalExpr(anyString(), anyMapOf(String.class, Value.class), eq(EMPTY_SET), eq(EMPTY_FUNCTION_SET))) .thenReturn(ValueFactory.create(Lists.newArrayList())); Map<String, Value> langVars = Collections.emptyMap(); when(context.getImmutableViewOfLanguageVariables()).thenReturn(langVars); exception.expectMessage("expression is empty"); exception.expect(RuntimeException.class); loopsBinding.getOrCreateLoopCondition(createBasicForStatement(), context, EMPTY_SET, "node"); } @Test(expected = RuntimeException.class) public void passingNullLoopStatementThrowsException() throws Exception { loopsBinding.getOrCreateLoopCondition(null, mock(Context.class), EMPTY_SET, "aa"); } @Test(expected = RuntimeException.class) public void passingNullContextThrowsException() throws Exception { loopsBinding.getOrCreateLoopCondition(createBasicForStatement(), null, EMPTY_SET, "aa"); } @Test(expected = RuntimeException.class) public void passingNullNodeNameThrowsException() throws Exception { loopsBinding.getOrCreateLoopCondition(createBasicForStatement(), mock(Context.class), EMPTY_SET, null); } @Test public void whenValueIsThereItWillBeReturned() throws Exception { Context context = mock(Context.class); ArrayList<Value> result = Lists.newArrayList(ValueFactory.create(1)); when(scriptEvaluator.evalExpr(anyString(), anyMapOf(String.class, Value.class), eq(EMPTY_SET), eq(EMPTY_FUNCTION_SET))) .thenReturn(ValueFactory.create(result)); Map<String, Value> langVars = new HashMap<>(); ForLoopCondition forLoopCondition = new ForLoopCondition(result); langVars.put(LoopCondition.LOOP_CONDITION_KEY, ValueFactory.create(forLoopCondition)); when(context.getLanguageVariable(LoopCondition.LOOP_CONDITION_KEY)) .thenReturn(langVars.get(LoopCondition.LOOP_CONDITION_KEY)); when(context.getImmutableViewOfLanguageVariables()) .thenReturn(Collections.unmodifiableMap(langVars)); loopsBinding.getOrCreateLoopCondition(createBasicForStatement(), context, EMPTY_SET, "node"); Assert.assertEquals(true, context.getImmutableViewOfLanguageVariables() .containsKey(LoopCondition.LOOP_CONDITION_KEY)); Assert.assertEquals(forLoopCondition, context.getImmutableViewOfLanguageVariables() .get(LoopCondition.LOOP_CONDITION_KEY).get()); } @Test public void testIncrementListForLoop() throws Exception { Serializable nextValue = "1"; Context context = mock(Context.class); ForLoopCondition forLoopCondition = mock(ForLoopCondition.class); when(forLoopCondition.next()).thenReturn(ValueFactory.create(nextValue)); loopsBinding.incrementListForLoop("varName", context, forLoopCondition); verify(forLoopCondition).next(); verify(context).putVariable("varName", ValueFactory.create(nextValue)); } @Test public void testIncrementMapForLoop() throws Exception { Context context = mock(Context.class); ForLoopCondition forLoopCondition = mock(ForLoopCondition.class); when(forLoopCondition.next()) .thenReturn(ValueFactory.create(Pair.of(ValueFactory.create("john"), ValueFactory.create(1)))); loopsBinding.incrementMapForLoop("k", "v", context, forLoopCondition); verify(forLoopCondition).next(); verify(context).putVariable("k", ValueFactory.create("john")); verify(context).putVariable("v", ValueFactory.create(1)); } }