/* * Copyright 2003-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.generator.test; import jetbrains.mps.generator.impl.template.VariableNameSource; import org.hamcrest.CoreMatchers; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ErrorCollector; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * @author Artem Tikhomirov */ public class VariableNameSourceTest { @Rule public final ErrorCollector myErrors = new ErrorCollector(); @Test public void testSubsequentNewName() { VariableNameSource ns = new VariableNameSource("ctx", new AtomicInteger(0)); // basic assumptions myErrors.checkThat(ns.getActualName(), CoreMatchers.equalTo("ctx")); myErrors.checkThat(ns.getNewName(), CoreMatchers.equalTo("ctx")); // construct a name myErrors.checkThat(ns.newName(), CoreMatchers.equalTo("ctx1")); myErrors.checkThat(ns.newName(), CoreMatchers.equalTo("ctx2")); myErrors.checkThat(ns.hasNewName(), CoreMatchers.equalTo(true)); VariableNameSource ns2 = ns.next(); myErrors.checkThat(ns2.getActualName(), CoreMatchers.equalTo("ctx2")); myErrors.checkThat(ns2.hasNewName(), CoreMatchers.equalTo(false)); myErrors.checkThat(ns2.newName(), CoreMatchers.equalTo("ctx3")); } /** * Verify use of nested sources don't affect actual source for the given execution level */ @Test public void testNameStacking() { VariableNameSource ns = new VariableNameSource("x", new AtomicInteger(0)); ArrayList<String> names = new ArrayList<>(); nestedUse(3, ns.next(), names); // we've passed nested context for modifications, original instance shall stay intact myErrors.checkThat(ns.hasNewName(), CoreMatchers.equalTo(false)); myErrors.checkThat(ns.getActualName(), CoreMatchers.equalTo("x")); myErrors.checkThat(names, CoreMatchers.equalTo(Arrays.asList("x", "x1", "x1", "x2", "x2", "x3", /*and now actual names of the corresponding level in reverse order*/ "x2", "x1", "x"))); } /** * Usecase similar to {@link #testNestedInLoop()}, with no newName on initial source. * reduce_If: optionally newName(), next(), next(), use actual. */ @Test public void testSubsequentNext() { VariableNameSource ns = new VariableNameSource("x"); nestedUse(1, ns.next(), new ArrayList<>()); nestedUse(1, ns.next(), new ArrayList<>()); myErrors.checkThat(ns.hasNewName(), CoreMatchers.equalTo(false)); myErrors.checkThat(ns.getActualName(), CoreMatchers.equalTo("x")); } @Test public void testNestedInLoop() { VariableNameSource ns = new VariableNameSource("x", new AtomicInteger(0)); ns.newName(); ArrayList<String> names = new ArrayList<>(); for (int i = 0; i < 3; i++) { nestedUse(1, ns.next(), names); } myErrors.checkThat(ns.getActualName(), CoreMatchers.equalTo("x")); myErrors.checkThat(ns.getNewName(), CoreMatchers.equalTo("x1")); myErrors.checkThat(names, CoreMatchers.equalTo(Arrays.asList(/*i==0*/"x1", "x2", "x1", /*i==1*/ "x1", "x3", "x1", /*i==2*/ "x1", "x4", "x1"))); } // each step adds 3 items into the list, first actual name and a newly constructed name, and after recursive call, actual name once again. private void nestedUse(int countdown, VariableNameSource ns, List<String> names) { if (countdown-- == 0) { return; } names.add(ns.getActualName()); names.add(ns.newName()); nestedUse(countdown, ns.next(), names); names.add(ns.getActualName()); } }