/* * Copyright (C) 2014 Stratio (http://stratio.com) * * 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 com.stratio.qa.cucumber.converter; import com.stratio.qa.utils.ThreadProperty; import gherkin.events.PickleEvent; import gherkin.pickles.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class LoopConverter { public static List<PickleEvent> transformPickleEventWithLoopTags(PickleEvent pe) { List<PickleEvent> pickleEventList = new ArrayList<>(); for (PickleTag pickleTag : pe.pickle.getTags()) { // Loop if (pickleTag.getName().toUpperCase().matches("\\s*@LOOP.*")) { transformLoop(pe, pickleTag, pickleEventList); break; } // ProgLoop if (pickleTag.getName().toUpperCase().matches("\\s*@PROGLOOP.*")) { transformProgLoop(pe, pickleTag, pickleEventList); break; } // MultiLoop if (pickleTag.getName().toUpperCase().matches("\\s*@MULTILOOP.*")) { transformMultiLoop(pe, pickleTag, pickleEventList); break; } } if (pickleEventList.isEmpty()) { pickleEventList.add(pe); } return pickleEventList; } private static void transformLoop(PickleEvent pe, PickleTag pickleTag, List<PickleEvent> pickleEventList) { String listParams = pickleTag.getName().substring((pickleTag.getName().lastIndexOf("(") + 1), (pickleTag.getName().length()) - 1).split(",")[0]; try { String value = System.getProperty(listParams, ThreadProperty.get(listParams)); if (value == null) { throw new Exception("@errorMessage(Variable__" + listParams + "__is__not__defined.)"); } String[] elems = value.split(","); String paramReplace = pickleTag.getName().substring((pickleTag.getName().lastIndexOf("(") + 1), (pickleTag.getName().length()) - 1).split(",")[1]; int numElem = 0; for (String elem : elems) { pickleEventList.add(generatePickleEvent(elem, numElem, paramReplace, pe.uri, pe.pickle.getName(), pe.pickle.getLanguage(), pe.pickle.getSteps(), pe.pickle.getTags(), pe.pickle.getLocations())); numElem++; } } catch (Exception e) { String message = e.getMessage(); if (!message.contains("@errorMessage")) { message = "@errorMessage(" + message.replaceAll(" ", "__") + ".)"; } List<PickleTag> pickleTagList = pe.pickle.getTags(); pickleTagList.add(new PickleTag(pe.pickle.getLocations().get(0), "@error")); pickleTagList.add(new PickleTag(pe.pickle.getLocations().get(0), message)); Pickle pickle = new Pickle(pe.pickle.getName(), pe.pickle.getLanguage(), pe.pickle.getSteps(), pickleTagList, pe.pickle.getLocations()); pickleEventList.add(new PickleEvent(pe.uri, pickle)); } } private static void transformProgLoop(PickleEvent pe, PickleTag pickleTag, List<PickleEvent> pickleEventList) { String listParams = pickleTag.getName().substring((pickleTag.getName().lastIndexOf("(") + 1), (pickleTag.getName().length()) - 1).split(",")[0]; try { String elem = System.getProperty(listParams, ThreadProperty.get(listParams)); if (elem == null) { throw new Exception("@errorMessage(Variable__" + listParams + "__is__not__defined.)"); } int times = Integer.parseInt(elem); if (times < 1) { throw new Exception("@errorMessage(Variable__" + listParams + "__must__be__higher__than__0.)"); } else { String[] elems = new String[times]; for (Integer i = 1; i <= times; i++) { elems[i - 1] = i.toString(); } String paramReplace = pickleTag.getName().substring((pickleTag.getName().lastIndexOf("(") + 1), (pickleTag.getName().length()) - 1).split(",")[1]; int numElem = 0; for (String elemAux : elems) { pickleEventList.add(generatePickleEvent(elemAux, numElem, paramReplace, pe.uri, pe.pickle.getName(), pe.pickle.getLanguage(), pe.pickle.getSteps(), pe.pickle.getTags(), pe.pickle.getLocations())); numElem++; } } } catch (Exception e) { String message = e.getMessage(); if (e instanceof NumberFormatException) { message = "@errorMessage(Variable__" + listParams + "__is__not__an__integer.)"; } if (!message.contains("@errorMessage")) { message = "@errorMessage(" + message.replaceAll(" ", "__") + ".)"; } List<PickleTag> pickleTagList = pe.pickle.getTags(); pickleTagList.add(new PickleTag(pe.pickle.getLocations().get(0), "@error")); pickleTagList.add(new PickleTag(pe.pickle.getLocations().get(0), message)); Pickle pickle = new Pickle(pe.pickle.getName(), pe.pickle.getLanguage(), pe.pickle.getSteps(), pickleTagList, pe.pickle.getLocations()); pickleEventList.add(new PickleEvent(pe.uri, pickle)); } } private static void transformMultiLoop(PickleEvent pe, PickleTag pickleTag, List<PickleEvent> pickleEventList) { Map<String, String[]> params = new HashMap<>(); String[] elements = pickleTag.getName().substring((pickleTag.getName().lastIndexOf("(") + 1), (pickleTag.getName().length()) - 1).split(","); try { for (String element : elements) { String[] elementParts = element.split("=>"); String listParam = elementParts[0]; String paramName = elementParts[1]; String[] elems; String value = System.getProperty(listParam, ThreadProperty.get(listParam)); if (value == null) { throw new Exception("@errorMessage(Variable__" + listParam + "__is__not__defined.)"); } elems = value.split(","); params.put(paramName, elems); } String[] keys = params.keySet().toArray(new String[params.keySet().size()]); int numScenarios = 1; for (String key : keys) { numScenarios = numScenarios * params.get(key).length; } List<String[]> replacedValues = new ArrayList<>(); for (int i = 0; i < numScenarios; i++) { replacedValues.add(new String[keys.length]); } int numRepetitions = 0; for (int i = 0; i < keys.length; i++) { String key = keys[i]; String[] keyValues = params.get(key); int j = 0; int index = 0; while (j < numScenarios) { int totalAdded = 0; do { String[] replacedValuesAux = replacedValues.get(j); replacedValuesAux[i] = keyValues[index % keyValues.length]; replacedValues.set(j, replacedValuesAux); j++; totalAdded++; } while (totalAdded < numRepetitions); index++; } if (numRepetitions == 0) { numRepetitions = keyValues.length; } else { numRepetitions = numRepetitions * keyValues.length; } } for (String[] values : replacedValues) { pickleEventList.add(generatePickleEvent(keys, values, pe.uri, pe.pickle.getName(), pe.pickle.getLanguage(), pe.pickle.getSteps(), pe.pickle.getTags(), pe.pickle.getLocations())); } } catch (Exception e) { String message = e.getMessage(); if (!message.contains("@errorMessage")) { message = "@errorMessage(" + message.replaceAll(" ", "__") + ".)"; } List<PickleTag> pickleTagList = pe.pickle.getTags(); pickleTagList.add(new PickleTag(pe.pickle.getLocations().get(0), "@error")); pickleTagList.add(new PickleTag(pe.pickle.getLocations().get(0), message)); Pickle pickle = new Pickle(pe.pickle.getName(), pe.pickle.getLanguage(), pe.pickle.getSteps(), pickleTagList, pe.pickle.getLocations()); pickleEventList.add(new PickleEvent(pe.uri, pickle)); } } private static PickleEvent generatePickleEvent(String elem, int numElem, String paramReplace, String uri, String name, String language, List<PickleStep> steps, List<PickleTag> tags, List<PickleLocation> locations) { List<PickleStep> newSteps = new ArrayList<>(); for (PickleStep step : steps) { String newStepText = step.getText().replaceAll("<" + paramReplace + ">", elem).replaceAll("<" + paramReplace + ".id>", String.valueOf(numElem)); List<Argument> argumentListReplaced = replaceArguments("<" + paramReplace + ">", elem, step.getArgument()); argumentListReplaced = replaceArguments("<" + paramReplace + ".id>", elem, argumentListReplaced); newSteps.add(new PickleStep(newStepText, argumentListReplaced, step.getLocations())); } String newScenarioname = name.replaceAll("<" + paramReplace + ">", elem).replaceAll("<" + paramReplace + ".id>", String.valueOf(numElem)); Pickle pickle = new Pickle(newScenarioname, language, newSteps, tags, locations); return new PickleEvent(uri, pickle); } private static PickleEvent generatePickleEvent(String[] keys, String[] values, String uri, String name, String language, List<PickleStep> steps, List<PickleTag> tags, List<PickleLocation> locations) { List<PickleStep> newSteps = new ArrayList<>(); for (PickleStep step : steps) { String newStepText = step.getText(); List<Argument> argumentListReplaced = step.getArgument(); for (int i = 0; i < keys.length; i++) { newStepText = newStepText.replaceAll("<" + keys[i] + ">", values[i]); argumentListReplaced = replaceArguments("<" + keys[i] + ">", values[i], argumentListReplaced); } newSteps.add(new PickleStep(newStepText, argumentListReplaced, step.getLocations())); } String newScenarioname = name; for (int i = 0; i < keys.length; i++) { newScenarioname = newScenarioname.replaceAll("<" + keys[i] + ">", values[i]); } Pickle pickle = new Pickle(newScenarioname, language, newSteps, tags, locations); return new PickleEvent(uri, pickle); } private static List<Argument> replaceArguments(String textToReplace, String textReplaced, List<Argument> argumentsList) { List<Argument> argumentListReplaced = new ArrayList<>(); for (Argument argument : argumentsList) { if (argument instanceof PickleTable) { PickleTable pickleTable = (PickleTable) argument; List<PickleRow> pickleRowList = new ArrayList<>(pickleTable.getRows()); for (int r = 0; r < pickleRowList.size(); r++) { PickleRow pickleRow = pickleRowList.get(r); List<PickleCell> pickleCellList = new ArrayList<>(pickleRow.getCells()); for (int c = 0; c < pickleCellList.size(); c++) { PickleCell pickleCell = pickleCellList.get(c); pickleCellList.set(c, new PickleCell(pickleCell.getLocation(), pickleCell.getValue().replaceAll(textToReplace, textReplaced))); } pickleRowList.set(r, new PickleRow(pickleCellList)); } pickleTable = new PickleTable(pickleRowList); argumentListReplaced.add(pickleTable); } else { argumentListReplaced.add(argument); } } return argumentListReplaced; } }