package org.jbehave.eclipse.parser; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IMethod; import org.jbehave.core.steps.StepType; import org.jbehave.eclipse.editor.step.LocalizedStepSupport; import org.jbehave.eclipse.editor.step.ParametrizedStep; import org.jbehave.eclipse.editor.step.StepCandidate; import org.jbehave.eclipse.editor.step.ParametrizedStep.WeightChain; import org.jbehave.eclipse.parser.RegexUtils; import org.jbehave.eclipse.parser.ContentWithIgnorableEmitter; import org.jbehave.eclipse.parser.StoryElement; import org.junit.Before; import org.junit.Test; public class ContentWithIgnorableEmitterTest { private static final String STEP1 = "Given an account named '$name' with the following properties:$properties"; public static final String NL = "\n"; public static final String GIVEN1 = "Given an account named 'Travis' with the following properties:" + NL + "|key|value|" + NL + "!-- Some comment" + NL + "|Login|Travis|" + NL + "|Password|p4cm4n|" + NL; public static final String EXPECTED1 = "<D>Given an account named '</D><I>Travis</I><D>' with the following properties:</D><I>" + NL + "|key|value|" + NL + "</I>" + "<C>!-- Some comment" + NL + "</C>" + "<I>|Login|Travis|" + NL + "|Password|p4cm4n|" + NL + "</I>"; public static final String GIVEN2 = GIVEN1 + NL + "!-- Other comment" + NL; public static final String EXPECTED2 = "<D>Given an account named '</D><I>Travis</I><D>' with the following properties:</D><I>" + NL + "|key|value|" + NL + "</I>" + "<C>!-- Some comment" + NL + "</C>" + "<I>|Login|Travis|" + NL + "|Password|p4cm4n|" + NL + "</I>" + "<C>" + NL + "!-- Other comment" + NL + "</C>"; private StoryElement storyElement; private StepCandidate candidate; private ParametrizedStep parametrizedStep; private Collector collector; private LocalizedStepSupport localizedStepSupport; @Before public void setUp () { localizedStepSupport = new LocalizedStepSupport(); localizedStepSupport.setStoryLocale(Locale.ENGLISH); IMethod method = null; candidate = new StepCandidate(localizedStepSupport, "$", method, StepType.GIVEN, STEP1, 0); parametrizedStep = candidate.getParametrizedStep(); collector = new Collector(); } @Test public void useCase_exampleTableWithComment_case1 () { storyElement = new StoryElement(localizedStepSupport, 17, GIVEN1); String rawContent = storyElement.getContent(); ContentWithIgnorableEmitter emitter = new ContentWithIgnorableEmitter(RegexUtils.COMMENT_PATTERN, rawContent); String input = emitter.contentWithoutIgnorables(); int offset = 0; WeightChain chain = parametrizedStep.calculateWeightChain(input); List<String> chainTokens = chain.tokenize(); for(int i=0;i<chainTokens.size();i++) { org.jbehave.eclipse.editor.step.ParametrizedStep.Token pToken = parametrizedStep.getToken(i); // be aware that the token length can be shorter than the content length // because content can also contain comment :) String content = chainTokens.get(i); if(pToken.isIdentifier) { emitter.emitNext(offset, content.length(), collector, "I"); } else { emitter.emitNext(offset, content.length(), collector, "D"); } offset += content.length(); } assertThat(collector.emittedList.size(), equalTo(6)); assertThat(collector.applyOn(rawContent, false), equalTo(rawContent)); assertThat(collector.applyOn(rawContent, true), equalTo(EXPECTED1)); } @Test public void useCase_exampleTableWithComment_case2 () { storyElement = new StoryElement(localizedStepSupport, 17, GIVEN2); String rawContent = storyElement.getContent(); ContentWithIgnorableEmitter emitter = new ContentWithIgnorableEmitter(RegexUtils.COMMENT_PATTERN, rawContent); String input = emitter.contentWithoutIgnorables(); int offset = 0; WeightChain chain = parametrizedStep.calculateWeightChain(input); List<String> chainTokens = chain.tokenize(); for(int i=0;i<chainTokens.size();i++) { org.jbehave.eclipse.editor.step.ParametrizedStep.Token pToken = parametrizedStep.getToken(i); // be aware that the token length can be shorter than the content length // because content can also contain comment :) String content = chainTokens.get(i); if(pToken.isIdentifier) { emitter.emitNext(offset, content.length(), collector, "I"); } else { emitter.emitNext(offset, content.length(), collector, "D"); } offset += content.length(); } assertThat(collector.emittedList.size(), equalTo(7)); assertThat(collector.applyOn(rawContent, false), equalTo(rawContent)); assertThat(collector.applyOn(rawContent, true), equalTo(EXPECTED2)); } private static class Collector implements ContentWithIgnorableEmitter.Callback<String> { public final List<Emitted> emittedList = new ArrayList<Emitted>(); public void emit(String what, int offset, int length) { emittedList.add(new Emitted(offset, length, what)); } public String applyOn(String rawContent, boolean surroundWithTokenInfo) { StringBuilder builder = new StringBuilder (); for(Emitted emitted : emittedList) { if(surroundWithTokenInfo) { builder.append("<").append(emitted.what).append(">"); } builder.append(rawContent.substring(emitted.offset, emitted.offset+emitted.length)); if(surroundWithTokenInfo) { builder.append("</").append(emitted.what).append(">"); } } return builder.toString(); } public void emitIgnorable(int offset, int length) { emit("C", offset, length); } } private static class Emitted { public final int offset; public final int length; public final String what; public Emitted(int offset, int length, String what) { super(); this.offset = offset; this.length = length; this.what = what; } } }