From 60d7e78c90fd6fb5bdb7a72d1176b820c35b7469 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 18 Mar 2018 12:42:22 +1300 Subject: [PATCH 01/42] Initial fix, using ThreadLocal to pass fixture to example listeners --- src/main/java/org/concordion/Concordion.java | 2 +- .../api/SpecificationByExample.java | 3 +- .../concordion/api/listener/ExampleEvent.java | 9 +++- .../api/listener/OuterExampleEvent.java | 9 +++- .../internal/ConcordionBuilder.java | 2 +- ...cationToSpecificationByExampleAdaptor.java | 2 +- .../concordion/internal/XMLSpecification.java | 6 ++- .../internal/command/ExampleCommand.java | 14 ++++--- .../command/SpecificationCommand.java | 15 ++++--- .../internal/listener/FixtureExampleHook.java | 15 ++----- .../BeforeAndAfterMethodHooksFixture.java | 42 +++++++++++++++++++ .../annotation/BeforeAndAfterMethodHooks.md | 16 ++++++- 12 files changed, 104 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index 8451f4f91..5021ba411 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -100,7 +100,7 @@ public boolean hasExampleCommands(Fixture fixture) throws IOException { public ResultSummary processExample(Fixture fixture, String example) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(example); - getSpecification(fixture).processExample(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), example, resultRecorder); + getSpecification(fixture).processExample(fixture, evaluatorFactory.createEvaluator(fixture.getFixtureObject()), example, resultRecorder); return resultRecorder; } diff --git a/src/main/java/org/concordion/api/SpecificationByExample.java b/src/main/java/org/concordion/api/SpecificationByExample.java index d981b8b05..a93dd6873 100644 --- a/src/main/java/org/concordion/api/SpecificationByExample.java +++ b/src/main/java/org/concordion/api/SpecificationByExample.java @@ -41,11 +41,12 @@ public interface SpecificationByExample extends Specification { /** * Processes a single example. * + * @param fixture the example's fixture * @param evaluator evaluator * @param example name of the example * @param resultRecorder result recorder */ - void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder); + void processExample(Fixture fixture, Evaluator evaluator, String example, ResultRecorder resultRecorder); /** * Called once all examples have been executed so the spec can do things like "save HTML results to file". diff --git a/src/main/java/org/concordion/api/listener/ExampleEvent.java b/src/main/java/org/concordion/api/listener/ExampleEvent.java index 5705b45e1..fe26b3d6c 100644 --- a/src/main/java/org/concordion/api/listener/ExampleEvent.java +++ b/src/main/java/org/concordion/api/listener/ExampleEvent.java @@ -1,6 +1,7 @@ package org.concordion.api.listener; import org.concordion.api.Element; +import org.concordion.api.Fixture; import org.concordion.api.ResultSummary; /** @@ -11,11 +12,13 @@ public class ExampleEvent { private final Element element; private final ResultSummary resultSummary; private final String exampleName; + private final Fixture fixture; - public ExampleEvent(String exampleName, Element element, ResultSummary resultSummary) { + public ExampleEvent(String exampleName, Element element, ResultSummary resultSummary, Fixture fixture) { this.exampleName = exampleName; this.resultSummary = resultSummary; this.element = element; + this.fixture = fixture; } public Element getElement() { @@ -29,4 +32,8 @@ public ResultSummary getResultSummary() { public String getExampleName() { return exampleName; } + + public Fixture getFixture() { + return fixture; + } } diff --git a/src/main/java/org/concordion/api/listener/OuterExampleEvent.java b/src/main/java/org/concordion/api/listener/OuterExampleEvent.java index 9d5254c91..cadc830a6 100644 --- a/src/main/java/org/concordion/api/listener/OuterExampleEvent.java +++ b/src/main/java/org/concordion/api/listener/OuterExampleEvent.java @@ -1,6 +1,7 @@ package org.concordion.api.listener; import org.concordion.api.Element; +import org.concordion.api.Fixture; import org.concordion.api.ResultSummary; /** @@ -9,13 +10,15 @@ public class OuterExampleEvent { private final Element element; + private final Fixture fixture; private final ResultSummary resultSummary; private final String exampleName; - public OuterExampleEvent(String exampleName, Element element, ResultSummary resultSummary) { + public OuterExampleEvent(String exampleName, Element element, ResultSummary resultSummary, Fixture fixture) { this.exampleName = exampleName; this.resultSummary = resultSummary; this.element = element; + this.fixture = fixture; } public Element getElement() { @@ -29,4 +32,8 @@ public ResultSummary getResultSummary() { public String getExampleName() { return exampleName; } + + public Fixture getFixture() { + return fixture; + } } diff --git a/src/main/java/org/concordion/internal/ConcordionBuilder.java b/src/main/java/org/concordion/internal/ConcordionBuilder.java index 15e6a45e8..652eb4fdb 100644 --- a/src/main/java/org/concordion/internal/ConcordionBuilder.java +++ b/src/main/java/org/concordion/internal/ConcordionBuilder.java @@ -285,7 +285,7 @@ public Concordion build() throws UnableToBuildConcordionException { withThrowableListener(0, new ThrowableRenderer(resourceSource)); withRunListener(new RunResultRenderer(resourceSource)); - FixtureExampleHook fixtureExampleHook = new FixtureExampleHook(fixture); + FixtureExampleHook fixtureExampleHook = new FixtureExampleHook(); withOuterExampleListener(fixtureExampleHook); withExampleListener(fixtureExampleHook); diff --git a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java index 0939d6cde..b437520bf 100644 --- a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java +++ b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java @@ -25,7 +25,7 @@ public void setFixture(Fixture fixture) { testDescription = fixture.getSpecificationDescription(); } - public void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder) { + public void processExample(Fixture fixture, Evaluator evaluator, String example, ResultRecorder resultRecorder) { if (testDescription.equals(example)) { specification.process(evaluator, resultRecorder); } diff --git a/src/main/java/org/concordion/internal/XMLSpecification.java b/src/main/java/org/concordion/internal/XMLSpecification.java index 7b583cd0c..39ec9523a 100644 --- a/src/main/java/org/concordion/internal/XMLSpecification.java +++ b/src/main/java/org/concordion/internal/XMLSpecification.java @@ -11,6 +11,7 @@ public class XMLSpecification implements SpecificationByExample { public static final String OUTER_EXAMPLE_NAME = "[Outer]"; public static final String OUTER_EXAMPLE_SUFFIX = " " + OUTER_EXAMPLE_NAME; + public static final ThreadLocal FIXTURE_HOLDER = new ThreadLocal(); private String testDescription; private final CommandCall rootCommandNode; @@ -66,6 +67,8 @@ public void process(Evaluator evaluator, ResultRecorder resultRecorder) { } public void setFixture(Fixture fixture) { + FIXTURE_HOLDER.set(fixture); + if (hasExampleCommandNodes()) { testDescription = OUTER_EXAMPLE_NAME; } else { @@ -73,12 +76,13 @@ public void setFixture(Fixture fixture) { } } - public void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder) { + public void processExample(Fixture fixture, Evaluator evaluator, String example, ResultRecorder resultRecorder) { if (testDescription.equals(example)) { processNode(rootCommandNode, evaluator, resultRecorder); return; } + FIXTURE_HOLDER.set(fixture); for (ExampleCommandCall commandCall: examples) { if (commandCall.getExampleName().equals(example)) { resultRecorder.setForExample(true); diff --git a/src/main/java/org/concordion/internal/command/ExampleCommand.java b/src/main/java/org/concordion/internal/command/ExampleCommand.java index 70291b98d..2db5f2d46 100644 --- a/src/main/java/org/concordion/internal/command/ExampleCommand.java +++ b/src/main/java/org/concordion/internal/command/ExampleCommand.java @@ -35,7 +35,8 @@ public void execute(CommandCall node, Evaluator evaluator, ResultRecorder result specificationDescriber.getDescription(node.getResource(), exampleName)); if (!isBeforeExample) { - announceBeforeExample(exampleName, node.getElement(), resultRecorder); + Fixture fixture = XMLSpecification.FIXTURE_HOLDER.get(); + announceBeforeExample(exampleName, node.getElement(), resultRecorder, fixture); } try { @@ -46,7 +47,8 @@ public void execute(CommandCall node, Evaluator evaluator, ResultRecorder result setupCommandForExample(node, resultRecorder, exampleName); if (!isBeforeExample) { - announceAfterExample(exampleName, node.getElement(), resultRecorder); + Fixture fixture = XMLSpecification.FIXTURE_HOLDER.get(); + announceAfterExample(exampleName, node.getElement(), resultRecorder, fixture); } } @@ -110,15 +112,15 @@ public void setSpecificationDescriber(SpecificationDescriber specificationDescri this.specificationDescriber = specificationDescriber; } - private void announceBeforeExample(String exampleName, Element element, ResultRecorder resultRecorder) { + private void announceBeforeExample(String exampleName, Element element, ResultRecorder resultRecorder, Fixture fixture) { for (ExampleListener listener : listeners) { - listener.beforeExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder)resultRecorder)); + listener.beforeExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder)resultRecorder, fixture)); } } - private void announceAfterExample(String exampleName, Element element, ResultRecorder resultRecorder) { + private void announceAfterExample(String exampleName, Element element, ResultRecorder resultRecorder, Fixture fixture) { for (int i = listeners.size() - 1; i >= 0; i--) { - listeners.get(i).afterExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder)resultRecorder)); + listeners.get(i).afterExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder)resultRecorder, fixture)); } } } diff --git a/src/main/java/org/concordion/internal/command/SpecificationCommand.java b/src/main/java/org/concordion/internal/command/SpecificationCommand.java index a4cedc7dc..b689a8eca 100644 --- a/src/main/java/org/concordion/internal/command/SpecificationCommand.java +++ b/src/main/java/org/concordion/internal/command/SpecificationCommand.java @@ -11,6 +11,7 @@ import org.concordion.internal.FailFastException; import org.concordion.internal.SpecificationDescriber; import org.concordion.internal.SummarizingResultRecorder; +import org.concordion.internal.XMLSpecification; import static org.concordion.internal.XMLSpecification.OUTER_EXAMPLE_NAME; @@ -32,12 +33,14 @@ public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder } try { - announceBeforeOuterExampleEvent(commandCall.getElement(), (SummarizingResultRecorder) resultRecorder); + Fixture fixture = XMLSpecification.FIXTURE_HOLDER.get(); + announceBeforeOuterExampleEvent(commandCall.getElement(), (SummarizingResultRecorder) resultRecorder, fixture); commandCall.getChildren().processSequentially(evaluator, resultRecorder); } catch (FailFastException e) { // Ignore - it'll be re-thrown later if necessary. } finally { - announceAfterOuterExampleEvent(commandCall.getElement(), (SummarizingResultRecorder) resultRecorder); + Fixture fixture = XMLSpecification.FIXTURE_HOLDER.get(); + announceAfterOuterExampleEvent(commandCall.getElement(), (SummarizingResultRecorder) resultRecorder, fixture); } } @@ -90,15 +93,15 @@ private void announceBeforeProcessingEvent(Resource resource, Element element) { } } - private void announceBeforeOuterExampleEvent(Element element, ResultSummary resultSummary) { + private void announceBeforeOuterExampleEvent(Element element, ResultSummary resultSummary, Fixture fixture) { for (OuterExampleListener listener : outerExampleListeners) { - listener.beforeOuterExample(new OuterExampleEvent(OUTER_EXAMPLE_NAME, element, resultSummary)); + listener.beforeOuterExample(new OuterExampleEvent(OUTER_EXAMPLE_NAME, element, resultSummary, fixture)); } } - private void announceAfterOuterExampleEvent(Element element, ResultSummary resultSummary) { + private void announceAfterOuterExampleEvent(Element element, ResultSummary resultSummary, Fixture fixture) { for (int i = outerExampleListeners.size() - 1; i >= 0; i--) { - outerExampleListeners.get(i).afterOuterExample(new OuterExampleEvent(OUTER_EXAMPLE_NAME, element, resultSummary)); + outerExampleListeners.get(i).afterOuterExample(new OuterExampleEvent(OUTER_EXAMPLE_NAME, element, resultSummary, fixture)); } } } diff --git a/src/main/java/org/concordion/internal/listener/FixtureExampleHook.java b/src/main/java/org/concordion/internal/listener/FixtureExampleHook.java index e987fd377..f35fbf8b1 100644 --- a/src/main/java/org/concordion/internal/listener/FixtureExampleHook.java +++ b/src/main/java/org/concordion/internal/listener/FixtureExampleHook.java @@ -1,35 +1,28 @@ package org.concordion.internal.listener; -import org.concordion.api.Fixture; import org.concordion.api.listener.ExampleEvent; import org.concordion.api.listener.ExampleListener; import org.concordion.api.listener.OuterExampleEvent; import org.concordion.api.listener.OuterExampleListener; public class FixtureExampleHook implements OuterExampleListener, ExampleListener { - private final Fixture fixture; - - public FixtureExampleHook(Fixture fixture) { - this.fixture = fixture; - } - @Override public void beforeOuterExample(OuterExampleEvent event) { - fixture.beforeExample(event.getExampleName()); + event.getFixture().beforeExample(event.getExampleName()); } @Override public void afterOuterExample(OuterExampleEvent event) { - fixture.afterExample(event.getExampleName()); + event.getFixture().afterExample(event.getExampleName()); } @Override public void beforeExample(ExampleEvent event) { - fixture.beforeExample(event.getExampleName()); + event.getFixture().beforeExample(event.getExampleName()); } @Override public void afterExample(ExampleEvent event) { - fixture.afterExample(event.getExampleName()); + event.getFixture().afterExample(event.getExampleName()); } } \ No newline at end of file diff --git a/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java b/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java index 9b908e01b..bdc4ce08f 100644 --- a/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java +++ b/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java @@ -1,13 +1,20 @@ package spec.concordion.annotation; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.concordion.api.BeforeExample; +import org.concordion.api.ExampleName; +import org.concordion.api.Scope; +import org.concordion.api.ScopedObjectHolder; import org.concordion.integration.junit4.ConcordionRunner; import org.junit.runner.RunWith; import test.concordion.RunCommandSimulator; @RunWith(ConcordionRunner.class) public class BeforeAndAfterMethodHooksFixture { + private String exampleName; + public List getLog() { return BeforeAndAfterLoggingFixture.getLog(); } @@ -19,4 +26,39 @@ public List getListenerLog() { public void simulateRun(final String href) throws Exception { new RunCommandSimulator().simulate(href, this.getClass()); } + + @org.concordion.api.ConcordionScoped(Scope.EXAMPLE) + private ScopedObjectHolder exampleScopedCounter = new ScopedObjectHolder() { + @Override + protected AtomicInteger create() { + return new AtomicInteger(); + } + + @Override + protected void destroy(AtomicInteger counter) { + counter.set(-1); + } + + }; + + private int fieldCounter = 0; + + public int getFieldCounter() { + return fieldCounter; + } + + public int getExampleScopedCounter() { + return exampleScopedCounter.get().get(); + } + + @BeforeExample + public void incrementAllCounters(@ExampleName String name) { + exampleName = name; + fieldCounter++; + exampleScopedCounter.get().addAndGet(1); + } + + public String getExampleName() { + return exampleName; + } } diff --git a/src/test/resources/spec/concordion/annotation/BeforeAndAfterMethodHooks.md b/src/test/resources/spec/concordion/annotation/BeforeAndAfterMethodHooks.md index 45eb266ea..c72d503f3 100644 --- a/src/test/resources/spec/concordion/annotation/BeforeAndAfterMethodHooks.md +++ b/src/test/resources/spec/concordion/annotation/BeforeAndAfterMethodHooks.md @@ -11,7 +11,21 @@ Optionally, the method can have a String parameter annotated with `@ExampleName` @BeforeExample public void setupExample(@ExampleName exampleName) { - } + } + +We have two examples below. Each example increments an AtomicInteger that is [scoped](ConcordionScoped.md "c:run") differently and echoes the value. + +### [Test that increments counters](- "firstTest") + +* Example name is [firstTest](- "?=getExampleName()") +* Unannotated field value is [1](- "?=getFieldCounter()") +* Example scope value is [1](- "?=getExampleScopedCounter()") + +### [The same test again](- "secondTest") + +* Example name is [secondTest](- "?=getExampleName()") +* Unannotated field value is [1](- "?=getFieldCounter()") +* Example scope value is [1](- "?=getExampleScopedCounter()") ## Specification hooks From 8d5bc5b22a3956b986caddf377334083d92ac2cc Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 18 Mar 2018 13:14:40 +1300 Subject: [PATCH 02/42] Pass fixture as parameter as needed --- src/main/java/org/concordion/Concordion.java | 2 +- .../org/concordion/api/AbstractCommand.java | 4 ++-- .../api/AbstractCommandDecorator.java | 8 ++++---- src/main/java/org/concordion/api/Command.java | 4 ++-- .../java/org/concordion/api/CommandCall.java | 8 ++++---- .../org/concordion/api/CommandCallList.java | 14 +++++++------- .../java/org/concordion/api/Specification.java | 2 +- ...icationToSpecificationByExampleAdaptor.java | 6 +++--- .../concordion/internal/XMLSpecification.java | 18 +++++++----------- .../internal/command/AssertEqualsCommand.java | 2 +- .../internal/command/BooleanCommand.java | 6 +++--- .../internal/command/EchoCommand.java | 8 ++------ .../internal/command/ExampleCommand.java | 6 ++---- .../internal/command/RunCommand.java | 2 +- .../internal/command/SpecificationCommand.java | 8 +++----- .../internal/command/VerifyRowsCommand.java | 9 +++------ .../command/executeCommand/ExecuteCommand.java | 12 ++++++------ ...AbstractChangingOrderRowsMatchStrategy.java | 15 ++++++++------- .../command/strategies/BestMatchStrategy.java | 5 +++-- .../strategies/DefaultMatchStrategy.java | 4 ++-- .../command/strategies/KeyMatchStrategy.java | 4 ++-- .../command/strategies/RowsMatchStrategy.java | 7 ++----- .../BeforeAndAfterMethodHooksFixture.java | 3 ++- .../results/runTotals/RunTotalsFixture.java | 11 ++++++++++- .../test/concordion/RunCommandSimulator.java | 9 +++------ .../concordion/extension/CommandExtension.java | 10 +++------- 26 files changed, 87 insertions(+), 100 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index 5021ba411..394217b40 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -78,7 +78,7 @@ public void override(Resource resource) throws IOException { public ResultSummary process(Fixture fixture) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(); resultRecorder.setSpecificationDescription(fixture.getSpecificationDescription()); - getSpecification(fixture).process(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), resultRecorder); + getSpecification(fixture).process(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), resultRecorder, fixture); return resultRecorder; } diff --git a/src/main/java/org/concordion/api/AbstractCommand.java b/src/main/java/org/concordion/api/AbstractCommand.java index 4b8fd479d..531e0ad60 100644 --- a/src/main/java/org/concordion/api/AbstractCommand.java +++ b/src/main/java/org/concordion/api/AbstractCommand.java @@ -10,13 +10,13 @@ public List getExamples(CommandCall command) { return Collections.emptyList(); } - public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { } public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { } - public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { } public void modifyCommandCallTree(CommandCall element, List examples, List beforeExamples) { diff --git a/src/main/java/org/concordion/api/AbstractCommandDecorator.java b/src/main/java/org/concordion/api/AbstractCommandDecorator.java index 952bc97db..fa26c44c2 100644 --- a/src/main/java/org/concordion/api/AbstractCommandDecorator.java +++ b/src/main/java/org/concordion/api/AbstractCommandDecorator.java @@ -19,18 +19,18 @@ public void run() { }); } - public void execute(final CommandCall commandCall, final Evaluator evaluator, final ResultRecorder resultRecorder) { + public void execute(final CommandCall commandCall, final Evaluator evaluator, final ResultRecorder resultRecorder, final Fixture fixture) { process(commandCall, evaluator, resultRecorder, new Runnable() { public void run() { - command.execute(commandCall, evaluator, resultRecorder); + command.execute(commandCall, evaluator, resultRecorder, fixture); } }); } - public void verify(final CommandCall commandCall, final Evaluator evaluator, final ResultRecorder resultRecorder) { + public void verify(final CommandCall commandCall, final Evaluator evaluator, final ResultRecorder resultRecorder, final Fixture fixture) { process(commandCall, evaluator, resultRecorder, new Runnable() { public void run() { - command.verify(commandCall, evaluator, resultRecorder); + command.verify(commandCall, evaluator, resultRecorder, fixture); } }); } diff --git a/src/main/java/org/concordion/api/Command.java b/src/main/java/org/concordion/api/Command.java index 24c8790ae..6f819a7c4 100644 --- a/src/main/java/org/concordion/api/Command.java +++ b/src/main/java/org/concordion/api/Command.java @@ -6,9 +6,9 @@ public interface Command { void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder); - void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder); + void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture); - void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder); + void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture); /** * Used to modify the command call tree post parsing and before execution. Some things that might be done are: diff --git a/src/main/java/org/concordion/api/CommandCall.java b/src/main/java/org/concordion/api/CommandCall.java index e0b0491aa..0ae1b2a5c 100644 --- a/src/main/java/org/concordion/api/CommandCall.java +++ b/src/main/java/org/concordion/api/CommandCall.java @@ -64,16 +64,16 @@ public void setUp(Evaluator evaluator, ResultRecorder resultRecorder) { command.setUp(this, evaluator, resultRecorder); } - public void execute(Evaluator evaluator, ResultRecorder resultRecorder) { + public void execute(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { for (Map.Entry entry: constantsForExecution.entrySet()) { evaluator.setVariable(entry.getKey(), entry.getValue()); } - command.execute(this, evaluator, resultRecorder); + command.execute(this, evaluator, resultRecorder, fixture); } - public void verify(Evaluator evaluator, ResultRecorder resultRecorder) { - command.verify(this, evaluator, resultRecorder); + public void verify(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + command.verify(this, evaluator, resultRecorder, fixture); } public void appendChild(CommandCall commandNode) { diff --git a/src/main/java/org/concordion/api/CommandCallList.java b/src/main/java/org/concordion/api/CommandCallList.java index d12f4b119..5a88250ef 100644 --- a/src/main/java/org/concordion/api/CommandCallList.java +++ b/src/main/java/org/concordion/api/CommandCallList.java @@ -19,19 +19,19 @@ public void setUp(Evaluator evaluator, ResultRecorder resultRecorder) { for(CommandCall call : commandCalls) call.setUp(evaluator, resultRecorder); } - public void execute(Evaluator evaluator, ResultRecorder resultRecorder) { - for(CommandCall call : commandCalls) call.execute(evaluator, resultRecorder); + public void execute(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + for(CommandCall call : commandCalls) call.execute(evaluator, resultRecorder, fixture); } - public void verify(Evaluator evaluator, ResultRecorder resultRecorder) { - for(CommandCall call : commandCalls) call.verify(evaluator, resultRecorder); + public void verify(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + for(CommandCall call : commandCalls) call.verify(evaluator, resultRecorder, fixture); } - public void processSequentially(Evaluator evaluator, ResultRecorder resultRecorder) { + public void processSequentially(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { for(CommandCall call : commandCalls) { call.setUp(evaluator, resultRecorder); - call.execute(evaluator, resultRecorder); - call.verify(evaluator, resultRecorder); + call.execute(evaluator, resultRecorder, fixture); + call.verify(evaluator, resultRecorder, fixture); } } diff --git a/src/main/java/org/concordion/api/Specification.java b/src/main/java/org/concordion/api/Specification.java index 0121e5836..3106a6fdd 100644 --- a/src/main/java/org/concordion/api/Specification.java +++ b/src/main/java/org/concordion/api/Specification.java @@ -2,5 +2,5 @@ public interface Specification { - void process(Evaluator evaluator, ResultRecorder resultRecorder); + void process(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture); } diff --git a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java index b437520bf..2ca323bad 100644 --- a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java +++ b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java @@ -17,8 +17,8 @@ public SpecificationToSpecificationByExampleAdaptor(Specification s) { public void finish() { } - public void process(Evaluator evaluator, ResultRecorder resultRecorder) { - specification.process(evaluator, resultRecorder); + public void process(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + specification.process(evaluator, resultRecorder, fixture); } public void setFixture(Fixture fixture) { @@ -27,7 +27,7 @@ public void setFixture(Fixture fixture) { public void processExample(Fixture fixture, Evaluator evaluator, String example, ResultRecorder resultRecorder) { if (testDescription.equals(example)) { - specification.process(evaluator, resultRecorder); + specification.process(evaluator, resultRecorder, fixture); } } diff --git a/src/main/java/org/concordion/internal/XMLSpecification.java b/src/main/java/org/concordion/internal/XMLSpecification.java index 39ec9523a..1783d0810 100644 --- a/src/main/java/org/concordion/internal/XMLSpecification.java +++ b/src/main/java/org/concordion/internal/XMLSpecification.java @@ -11,7 +11,6 @@ public class XMLSpecification implements SpecificationByExample { public static final String OUTER_EXAMPLE_NAME = "[Outer]"; public static final String OUTER_EXAMPLE_SUFFIX = " " + OUTER_EXAMPLE_NAME; - public static final ThreadLocal FIXTURE_HOLDER = new ThreadLocal(); private String testDescription; private final CommandCall rootCommandNode; @@ -34,13 +33,13 @@ public XMLSpecification(CommandCall rootCommandNode, List ex this.beforeExamples = new ArrayList(beforeExamples); } - public void processNode(CommandCall node, Evaluator evaluator, ResultRecorder resultRecorder) { + public void processNode(CommandCall node, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { if (!node.getChildren().isEmpty()) { for (CommandCall before: beforeExamples) { SummarizingResultRecorder beforeResultRecorder = new SummarizingResultRecorder(); beforeResultRecorder.setSpecificationDescription("Running before for example " + node.getExpression()); - before.getCommand().execute(before, evaluator, beforeResultRecorder); + before.getCommand().execute(before, evaluator, beforeResultRecorder, fixture); String errorText = null; if (beforeResultRecorder.hasExceptions()) { errorText = SimpleFormatter.format("Exceptions occurred in the 'before' example in '%s'. See the output specification for details.\n", @@ -59,16 +58,14 @@ public void processNode(CommandCall node, Evaluator evaluator, ResultRecorder re } } - node.execute(evaluator, resultRecorder); + node.execute(evaluator, resultRecorder, fixture); } - public void process(Evaluator evaluator, ResultRecorder resultRecorder) { - processNode(rootCommandNode, evaluator, resultRecorder); + public void process(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + processNode(rootCommandNode, evaluator, resultRecorder, fixture); } public void setFixture(Fixture fixture) { - FIXTURE_HOLDER.set(fixture); - if (hasExampleCommandNodes()) { testDescription = OUTER_EXAMPLE_NAME; } else { @@ -78,15 +75,14 @@ public void setFixture(Fixture fixture) { public void processExample(Fixture fixture, Evaluator evaluator, String example, ResultRecorder resultRecorder) { if (testDescription.equals(example)) { - processNode(rootCommandNode, evaluator, resultRecorder); + processNode(rootCommandNode, evaluator, resultRecorder, fixture); return; } - FIXTURE_HOLDER.set(fixture); for (ExampleCommandCall commandCall: examples) { if (commandCall.getExampleName().equals(example)) { resultRecorder.setForExample(true); - processNode(commandCall.getCommandCall(), evaluator, resultRecorder); + processNode(commandCall.getCommandCall(), evaluator, resultRecorder, fixture); } } } diff --git a/src/main/java/org/concordion/internal/command/AssertEqualsCommand.java b/src/main/java/org/concordion/internal/command/AssertEqualsCommand.java index 894fc606c..a187a8342 100644 --- a/src/main/java/org/concordion/internal/command/AssertEqualsCommand.java +++ b/src/main/java/org/concordion/internal/command/AssertEqualsCommand.java @@ -33,7 +33,7 @@ public void removeAssertEqualsListener(AssertEqualsListener listener) { } @Override - public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { Check.isFalse(commandCall.hasChildCommands(), "Nesting commands inside an 'assertEquals' is not supported"); Element element = commandCall.getElement(); diff --git a/src/main/java/org/concordion/internal/command/BooleanCommand.java b/src/main/java/org/concordion/internal/command/BooleanCommand.java index 4c1b56bb2..136bf29c1 100644 --- a/src/main/java/org/concordion/internal/command/BooleanCommand.java +++ b/src/main/java/org/concordion/internal/command/BooleanCommand.java @@ -22,12 +22,12 @@ public void removeAssertListener(AssertListener listener) { } @Override - public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { // Check.isFalse(commandCall.hasChildCommands(), "Nesting commands inside an 'assertTrue' is not supported"); CommandCallList childCommands = commandCall.getChildren(); childCommands.setUp(evaluator, resultRecorder); - childCommands.execute(evaluator, resultRecorder); - childCommands.verify(evaluator, resultRecorder); + childCommands.execute(evaluator, resultRecorder, fixture); + childCommands.verify(evaluator, resultRecorder, fixture); String expression = commandCall.getExpression(); Object result = evaluator.evaluate(expression); diff --git a/src/main/java/org/concordion/internal/command/EchoCommand.java b/src/main/java/org/concordion/internal/command/EchoCommand.java index 5ad7cb29d..faee61191 100644 --- a/src/main/java/org/concordion/internal/command/EchoCommand.java +++ b/src/main/java/org/concordion/internal/command/EchoCommand.java @@ -1,16 +1,12 @@ package org.concordion.internal.command; -import org.concordion.api.AbstractCommand; -import org.concordion.api.CommandCall; -import org.concordion.api.Element; -import org.concordion.api.Evaluator; -import org.concordion.api.ResultRecorder; +import org.concordion.api.*; import org.concordion.internal.util.Check; public class EchoCommand extends AbstractCommand { @Override - public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { Check.isFalse(commandCall.hasChildCommands(), "Nesting commands inside an 'echo' is not supported"); Object result = evaluator.evaluate(commandCall.getExpression()); diff --git a/src/main/java/org/concordion/internal/command/ExampleCommand.java b/src/main/java/org/concordion/internal/command/ExampleCommand.java index 2db5f2d46..b357430e4 100644 --- a/src/main/java/org/concordion/internal/command/ExampleCommand.java +++ b/src/main/java/org/concordion/internal/command/ExampleCommand.java @@ -26,7 +26,7 @@ public void removeExampleListener(ExampleListener exampleListener) { listeners.remove(exampleListener); } - public void execute(CommandCall node, Evaluator evaluator, ResultRecorder resultRecorder) { + public void execute(CommandCall node, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { String exampleName = getExampleName(node); boolean isBeforeExample = isBeforeExample(node); @@ -35,19 +35,17 @@ public void execute(CommandCall node, Evaluator evaluator, ResultRecorder result specificationDescriber.getDescription(node.getResource(), exampleName)); if (!isBeforeExample) { - Fixture fixture = XMLSpecification.FIXTURE_HOLDER.get(); announceBeforeExample(exampleName, node.getElement(), resultRecorder, fixture); } try { - node.getChildren().processSequentially(evaluator, resultRecorder); + node.getChildren().processSequentially(evaluator, resultRecorder, fixture); } catch (FailFastException f) { // Ignore - it'll be re-thrown later by the implementation status checker if necessary. } setupCommandForExample(node, resultRecorder, exampleName); if (!isBeforeExample) { - Fixture fixture = XMLSpecification.FIXTURE_HOLDER.get(); announceAfterExample(exampleName, node.getElement(), resultRecorder, fixture); } } diff --git a/src/main/java/org/concordion/internal/command/RunCommand.java b/src/main/java/org/concordion/internal/command/RunCommand.java index 21400d976..62bccf44b 100644 --- a/src/main/java/org/concordion/internal/command/RunCommand.java +++ b/src/main/java/org/concordion/internal/command/RunCommand.java @@ -37,7 +37,7 @@ public RunCommand() { } @Override - public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { Check.isFalse(commandCall.hasChildCommands(), "Nesting commands inside an 'run' is not supported"); Element element = commandCall.getElement(); diff --git a/src/main/java/org/concordion/internal/command/SpecificationCommand.java b/src/main/java/org/concordion/internal/command/SpecificationCommand.java index b689a8eca..7572c0cb5 100644 --- a/src/main/java/org/concordion/internal/command/SpecificationCommand.java +++ b/src/main/java/org/concordion/internal/command/SpecificationCommand.java @@ -27,19 +27,17 @@ public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder r } @Override - public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { if (specificationDescriber != null) { resultRecorder.setSpecificationDescription(getSpecificationDescription(commandCall)); } try { - Fixture fixture = XMLSpecification.FIXTURE_HOLDER.get(); announceBeforeOuterExampleEvent(commandCall.getElement(), (SummarizingResultRecorder) resultRecorder, fixture); - commandCall.getChildren().processSequentially(evaluator, resultRecorder); + commandCall.getChildren().processSequentially(evaluator, resultRecorder, fixture); } catch (FailFastException e) { // Ignore - it'll be re-thrown later if necessary. } finally { - Fixture fixture = XMLSpecification.FIXTURE_HOLDER.get(); announceAfterOuterExampleEvent(commandCall.getElement(), (SummarizingResultRecorder) resultRecorder, fixture); } } @@ -57,7 +55,7 @@ public void finish(CommandCall commandCall) { } @Override - public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { throw new IllegalStateException("Unexpected call to " + getClass().getSimpleName() + "'s verify() method. Only the execute() method should be called."); } diff --git a/src/main/java/org/concordion/internal/command/VerifyRowsCommand.java b/src/main/java/org/concordion/internal/command/VerifyRowsCommand.java index 032190fc9..06512a2f7 100644 --- a/src/main/java/org/concordion/internal/command/VerifyRowsCommand.java +++ b/src/main/java/org/concordion/internal/command/VerifyRowsCommand.java @@ -9,10 +9,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.concordion.api.AbstractCommand; -import org.concordion.api.CommandCall; -import org.concordion.api.Evaluator; -import org.concordion.api.ResultRecorder; +import org.concordion.api.*; import org.concordion.api.listener.VerifyRowsListener; import org.concordion.internal.command.strategies.DefaultMatchStrategy; import org.concordion.internal.command.strategies.RowsMatchStrategy; @@ -32,7 +29,7 @@ public void removeVerifyRowsListener(VerifyRowsListener listener) { @SuppressWarnings("unchecked") @Override - public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { Pattern pattern = Pattern.compile("(#.+?) *: *(.+)"); Matcher matcher = pattern.matcher(commandCall.getExpression()); if (!matcher.matches()) { @@ -47,7 +44,7 @@ public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder Check.isTrue(!(obj instanceof HashSet) || (obj instanceof LinkedHashSet), obj.getClass().getCanonicalName() + " does not have a predictable iteration order"); Iterable iterable = (Iterable) obj; - newStrategyInstance(detectStrategyClass(commandCall), commandCall, evaluator, resultRecorder, loopVariableName, iterable).verify(); + newStrategyInstance(detectStrategyClass(commandCall), commandCall, evaluator, resultRecorder, loopVariableName, iterable).verify(fixture); } private static final String DEFAULT_STRATEGIES_PACKAGE = DefaultMatchStrategy.class.getPackage().getName() + '.'; diff --git a/src/main/java/org/concordion/internal/command/executeCommand/ExecuteCommand.java b/src/main/java/org/concordion/internal/command/executeCommand/ExecuteCommand.java index c8b6d85be..3fd54f90e 100644 --- a/src/main/java/org/concordion/internal/command/executeCommand/ExecuteCommand.java +++ b/src/main/java/org/concordion/internal/command/executeCommand/ExecuteCommand.java @@ -57,25 +57,25 @@ public void removeExecuteListener(ExecuteListener listener) { } @Override - public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { // bypass normal execution if the modification required it. if (commandCall.bypassExecution()) { - commandCall.getChildren().execute(evaluator, resultRecorder); + commandCall.getChildren().execute(evaluator, resultRecorder, fixture); return; } - normalExecution(commandCall, evaluator, resultRecorder); + normalExecution(commandCall, evaluator, resultRecorder, fixture); } - private void normalExecution(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + private void normalExecution(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { CommandCallList childCommands = commandCall.getChildren(); childCommands.setUp(evaluator, resultRecorder); evaluator.evaluate(commandCall.getExpression()); - childCommands.execute(evaluator, resultRecorder); + childCommands.execute(evaluator, resultRecorder, fixture); announceExecuteCompleted(commandCall.getElement()); - childCommands.verify(evaluator, resultRecorder); + childCommands.verify(evaluator, resultRecorder, fixture); } diff --git a/src/main/java/org/concordion/internal/command/strategies/AbstractChangingOrderRowsMatchStrategy.java b/src/main/java/org/concordion/internal/command/strategies/AbstractChangingOrderRowsMatchStrategy.java index 38c0852c8..f4f74cafd 100644 --- a/src/main/java/org/concordion/internal/command/strategies/AbstractChangingOrderRowsMatchStrategy.java +++ b/src/main/java/org/concordion/internal/command/strategies/AbstractChangingOrderRowsMatchStrategy.java @@ -4,6 +4,7 @@ import org.concordion.api.CommandCall; import org.concordion.api.Evaluator; +import org.concordion.api.Fixture; import org.concordion.api.ResultRecorder; import org.concordion.api.listener.VerifyRowsListener; import org.concordion.internal.Row; @@ -16,31 +17,31 @@ public AbstractChangingOrderRowsMatchStrategy(CommandCall commandCall, Evaluator } @Override - public void verify() { + public void verify(Fixture fixture) { announceExpressionEvaluated(commandCall.getElement()); for (Row expectedRow : expectedRows) { - Object row = findMatchingRow(expectedRow); + Object row = findMatchingRow(expectedRow, fixture); tableSupport.copyCommandCallsTo(expectedRow); if (row != null) { evaluator.setVariable(loopVariableName, row); - commandCall.getChildren().verify(evaluator, resultRecorder); + commandCall.getChildren().verify(evaluator, resultRecorder, fixture); actualRows.remove(row); } else { announceMissingRow(expectedRow.getElement()); } } - reportSurplusRows(); + reportSurplusRows(fixture); } - protected abstract Object findMatchingRow(Row expectedRow); + protected abstract Object findMatchingRow(Row expectedRow, Fixture fixture); - private void reportSurplusRows() { + private void reportSurplusRows(Fixture fixture) { for (Object surplusRow : actualRows) { evaluator.setVariable(loopVariableName, surplusRow); Row detailRow = tableSupport.addDetailRow(); announceSurplusRow(detailRow.getElement()); tableSupport.copyCommandCallsTo(detailRow); - commandCall.getChildren().verify(evaluator, resultRecorder); + commandCall.getChildren().verify(evaluator, resultRecorder, fixture); } } } diff --git a/src/main/java/org/concordion/internal/command/strategies/BestMatchStrategy.java b/src/main/java/org/concordion/internal/command/strategies/BestMatchStrategy.java index a75440e65..fa16769a8 100644 --- a/src/main/java/org/concordion/internal/command/strategies/BestMatchStrategy.java +++ b/src/main/java/org/concordion/internal/command/strategies/BestMatchStrategy.java @@ -4,6 +4,7 @@ import org.concordion.api.CommandCall; import org.concordion.api.Evaluator; +import org.concordion.api.Fixture; import org.concordion.api.ResultRecorder; import org.concordion.api.listener.VerifyRowsListener; import org.concordion.internal.Row; @@ -17,7 +18,7 @@ public BestMatchStrategy(CommandCall commandCall, Evaluator evaluator, ResultRec } @Override - protected Object findMatchingRow(Row expectedRow) { + protected Object findMatchingRow(Row expectedRow, Fixture fixture) { long bestResult = Integer.MIN_VALUE; Object bestMatchingRow = null; @@ -27,7 +28,7 @@ protected Object findMatchingRow(Row expectedRow) { tableSupport.copyCommandCallsTo(expectedRow.deepClone()); evaluator.setVariable(loopVariableName, row); - commandCall.getChildren().verify(evaluator, backgroundResultRecorder); + commandCall.getChildren().verify(evaluator, backgroundResultRecorder, fixture); long total = backgroundResultRecorder.getTotalCount(); long success = backgroundResultRecorder.getSuccessCount(); diff --git a/src/main/java/org/concordion/internal/command/strategies/DefaultMatchStrategy.java b/src/main/java/org/concordion/internal/command/strategies/DefaultMatchStrategy.java index 693131f4a..32cd8e79c 100644 --- a/src/main/java/org/concordion/internal/command/strategies/DefaultMatchStrategy.java +++ b/src/main/java/org/concordion/internal/command/strategies/DefaultMatchStrategy.java @@ -16,7 +16,7 @@ public DefaultMatchStrategy(CommandCall commandCall, Evaluator evaluator, Result } @Override - public void verify() { + public void verify(Fixture fixture) { announceExpressionEvaluated(commandCall.getElement()); int index = 0; @@ -30,7 +30,7 @@ public void verify() { announceSurplusRow(detailRow.getElement()); } tableSupport.copyCommandCallsTo(detailRow); - commandCall.getChildren().verify(evaluator, resultRecorder); + commandCall.getChildren().verify(evaluator, resultRecorder, fixture); index++; } diff --git a/src/main/java/org/concordion/internal/command/strategies/KeyMatchStrategy.java b/src/main/java/org/concordion/internal/command/strategies/KeyMatchStrategy.java index c5a1acdeb..c95b6fd3e 100644 --- a/src/main/java/org/concordion/internal/command/strategies/KeyMatchStrategy.java +++ b/src/main/java/org/concordion/internal/command/strategies/KeyMatchStrategy.java @@ -15,7 +15,7 @@ public KeyMatchStrategy(CommandCall commandCall, Evaluator evaluator, ResultReco } @Override - protected Object findMatchingRow(Row expectedRow) { + protected Object findMatchingRow(Row expectedRow, Fixture fixture) { Element[] headerCells = tableSupport.getLastHeaderRow().getCells(); CommandCallList childrenCalls = commandCall.getChildren(); @@ -32,7 +32,7 @@ protected Object findMatchingRow(Row expectedRow) { long success = 0; for (CommandCall columnCommand : childrenCalls.asCollection()) { - columnCommand.verify(evaluator, backgroundResultRecorder); + columnCommand.verify(evaluator, backgroundResultRecorder, fixture); String matchingRole = columnCommand.getParameter("matchingRole", "matching-role"); if (matchingRole != null && matchingRole.equalsIgnoreCase("key")) { diff --git a/src/main/java/org/concordion/internal/command/strategies/RowsMatchStrategy.java b/src/main/java/org/concordion/internal/command/strategies/RowsMatchStrategy.java index 94e36156d..6fa10d3bc 100644 --- a/src/main/java/org/concordion/internal/command/strategies/RowsMatchStrategy.java +++ b/src/main/java/org/concordion/internal/command/strategies/RowsMatchStrategy.java @@ -1,9 +1,6 @@ package org.concordion.internal.command.strategies; -import org.concordion.api.CommandCall; -import org.concordion.api.Element; -import org.concordion.api.Evaluator; -import org.concordion.api.ResultRecorder; +import org.concordion.api.*; import org.concordion.api.listener.ExpressionEvaluatedEvent; import org.concordion.api.listener.MissingRowEvent; import org.concordion.api.listener.SurplusRowEvent; @@ -42,7 +39,7 @@ public RowsMatchStrategy(CommandCall commandCall, Evaluator evaluator, ResultRec this.actualRows = copy(actualRows); } - public abstract void verify(); + public abstract void verify(Fixture fixture); protected void announceExpressionEvaluated(Element element) { for (VerifyRowsListener listener : listeners) { diff --git a/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java b/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java index bdc4ce08f..8a9d2031b 100644 --- a/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java +++ b/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java @@ -8,6 +8,7 @@ import org.concordion.api.Scope; import org.concordion.api.ScopedObjectHolder; import org.concordion.integration.junit4.ConcordionRunner; +import org.concordion.internal.FixtureInstance; import org.junit.runner.RunWith; import test.concordion.RunCommandSimulator; @@ -24,7 +25,7 @@ public List getListenerLog() { } public void simulateRun(final String href) throws Exception { - new RunCommandSimulator().simulate(href, this.getClass()); + new RunCommandSimulator().simulate(href, this.getClass(), new FixtureInstance(this)); } @org.concordion.api.ConcordionScoped(Scope.EXAMPLE) diff --git a/src/test/java/spec/concordion/common/results/runTotals/RunTotalsFixture.java b/src/test/java/spec/concordion/common/results/runTotals/RunTotalsFixture.java index 0688adee6..4a588d144 100644 --- a/src/test/java/spec/concordion/common/results/runTotals/RunTotalsFixture.java +++ b/src/test/java/spec/concordion/common/results/runTotals/RunTotalsFixture.java @@ -2,7 +2,9 @@ import java.util.Map; +import org.concordion.api.Fixture; import org.concordion.integration.junit4.ConcordionRunner; +import org.concordion.internal.FixtureInstance; import org.junit.runner.RunWith; import test.concordion.RunCommandSimulator; @@ -10,9 +12,16 @@ public class RunTotalsFixture { private Class testClass; + private Fixture fixture; public RunTotalsFixture() { withTestClass(getClass()); + withFixture(new FixtureInstance(this)); + } + + private RunTotalsFixture withFixture(FixtureInstance fixture) { + this.fixture = fixture; + return this; } public RunTotalsFixture withTestClass(Class fixtureClass) { @@ -21,6 +30,6 @@ public RunTotalsFixture withTestClass(Class fixtureClass) { } public Map simulateRun(final String href) throws Exception { - return new RunCommandSimulator().simulate(href, testClass); + return new RunCommandSimulator().simulate(href, testClass, fixture); } } diff --git a/src/test/java/test/concordion/RunCommandSimulator.java b/src/test/java/test/concordion/RunCommandSimulator.java index 57293819c..c97e00085 100644 --- a/src/test/java/test/concordion/RunCommandSimulator.java +++ b/src/test/java/test/concordion/RunCommandSimulator.java @@ -1,9 +1,6 @@ package test.concordion; -import org.concordion.api.CommandCall; -import org.concordion.api.Element; -import org.concordion.api.Resource; -import org.concordion.api.ResultSummary; +import org.concordion.api.*; import org.concordion.internal.*; import org.concordion.internal.command.RunCommand; @@ -12,7 +9,7 @@ import java.util.Map; public class RunCommandSimulator { - public Map simulate(String href, Class testClass) { + public Map simulate(String href, Class testClass, Fixture fixture) { final Element element = new Element("a"); element.addAttribute("href", href); @@ -30,7 +27,7 @@ public Map simulate(String href, Class testClass) { recorder.setSpecificationDescription(""); try { - commandCall.execute(null, recorder); + commandCall.execute(null, recorder, fixture); } catch (FailFastException ffe) { System.out.println("Caught fail fast exception thrown by the fixture under test. Ignoring..."); } diff --git a/src/test/java/test/concordion/extension/CommandExtension.java b/src/test/java/test/concordion/extension/CommandExtension.java index aef0aa992..dc8b2b31b 100644 --- a/src/test/java/test/concordion/extension/CommandExtension.java +++ b/src/test/java/test/concordion/extension/CommandExtension.java @@ -3,13 +3,9 @@ import java.io.PrintStream; import java.util.List; -import org.concordion.api.Command; -import org.concordion.api.CommandCall; -import org.concordion.api.Evaluator; -import org.concordion.api.ResultRecorder; +import org.concordion.api.*; import org.concordion.api.extension.ConcordionExtender; import org.concordion.api.extension.ConcordionExtension; -import org.concordion.api.ExampleCommandCall; public class CommandExtension implements ConcordionExtension { @@ -23,7 +19,7 @@ public CommandExtension withStream(PrintStream stream) { public void addTo(ConcordionExtender concordionExtender) { concordionExtender.withCommand("http://myorg.org/my/extension", "log", new Command() { - public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { } public void modifyCommandCallTree(CommandCall element, List examples, List beforeExamples) { @@ -32,7 +28,7 @@ public void modifyCommandCallTree(CommandCall element, List public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { } - public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { stream.println(commandCall.getElement().getText()); } }); From 720b52136e773c6d77919b353d5f91d27f39b679 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 18 Mar 2018 22:58:43 +1300 Subject: [PATCH 03/42] Made fixture the last parameter in processExample for consistency --- src/main/java/org/concordion/Concordion.java | 2 +- .../java/org/concordion/api/SpecificationByExample.java | 7 +++---- .../SpecificationToSpecificationByExampleAdaptor.java | 2 +- .../java/org/concordion/internal/XMLSpecification.java | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index 394217b40..6531be67a 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -100,7 +100,7 @@ public boolean hasExampleCommands(Fixture fixture) throws IOException { public ResultSummary processExample(Fixture fixture, String example) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(example); - getSpecification(fixture).processExample(fixture, evaluatorFactory.createEvaluator(fixture.getFixtureObject()), example, resultRecorder); + getSpecification(fixture).processExample(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), example, resultRecorder, fixture); return resultRecorder; } diff --git a/src/main/java/org/concordion/api/SpecificationByExample.java b/src/main/java/org/concordion/api/SpecificationByExample.java index a93dd6873..7aab64d4b 100644 --- a/src/main/java/org/concordion/api/SpecificationByExample.java +++ b/src/main/java/org/concordion/api/SpecificationByExample.java @@ -40,13 +40,12 @@ public interface SpecificationByExample extends Specification { /** * Processes a single example. - * - * @param fixture the example's fixture - * @param evaluator evaluator + * @param evaluator evaluator * @param example name of the example * @param resultRecorder result recorder + * @param fixture the example's fixture */ - void processExample(Fixture fixture, Evaluator evaluator, String example, ResultRecorder resultRecorder); + void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder, Fixture fixture); /** * Called once all examples have been executed so the spec can do things like "save HTML results to file". diff --git a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java index 2ca323bad..e79792970 100644 --- a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java +++ b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java @@ -25,7 +25,7 @@ public void setFixture(Fixture fixture) { testDescription = fixture.getSpecificationDescription(); } - public void processExample(Fixture fixture, Evaluator evaluator, String example, ResultRecorder resultRecorder) { + public void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder, Fixture fixture) { if (testDescription.equals(example)) { specification.process(evaluator, resultRecorder, fixture); } diff --git a/src/main/java/org/concordion/internal/XMLSpecification.java b/src/main/java/org/concordion/internal/XMLSpecification.java index 1783d0810..546058354 100644 --- a/src/main/java/org/concordion/internal/XMLSpecification.java +++ b/src/main/java/org/concordion/internal/XMLSpecification.java @@ -73,7 +73,7 @@ public void setFixture(Fixture fixture) { } } - public void processExample(Fixture fixture, Evaluator evaluator, String example, ResultRecorder resultRecorder) { + public void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder, Fixture fixture) { if (testDescription.equals(example)) { processNode(rootCommandNode, evaluator, resultRecorder, fixture); return; From 0c489a6c22726d71d221d50f94c41c99011b1b09 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 18 Mar 2018 23:02:16 +1300 Subject: [PATCH 04/42] Added fixture to Command.setup() method for consistency with other Command methods --- src/main/java/org/concordion/api/AbstractCommand.java | 2 +- .../java/org/concordion/api/AbstractCommandDecorator.java | 4 ++-- src/main/java/org/concordion/api/Command.java | 2 +- src/main/java/org/concordion/api/CommandCall.java | 4 ++-- src/main/java/org/concordion/api/CommandCallList.java | 6 +++--- .../org/concordion/internal/command/BooleanCommand.java | 2 +- .../java/org/concordion/internal/command/SetCommand.java | 2 +- .../concordion/internal/command/SpecificationCommand.java | 3 +-- .../internal/command/executeCommand/ExecuteCommand.java | 2 +- .../java/test/concordion/extension/CommandExtension.java | 2 +- 10 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/concordion/api/AbstractCommand.java b/src/main/java/org/concordion/api/AbstractCommand.java index 531e0ad60..29163390f 100644 --- a/src/main/java/org/concordion/api/AbstractCommand.java +++ b/src/main/java/org/concordion/api/AbstractCommand.java @@ -13,7 +13,7 @@ public List getExamples(CommandCall command) { public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { } - public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { } public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { diff --git a/src/main/java/org/concordion/api/AbstractCommandDecorator.java b/src/main/java/org/concordion/api/AbstractCommandDecorator.java index fa26c44c2..64a91f177 100644 --- a/src/main/java/org/concordion/api/AbstractCommandDecorator.java +++ b/src/main/java/org/concordion/api/AbstractCommandDecorator.java @@ -11,10 +11,10 @@ public AbstractCommandDecorator(Command command) { this.command = command; } - public void setUp(final CommandCall commandCall, final Evaluator evaluator, final ResultRecorder resultRecorder) { + public void setUp(final CommandCall commandCall, final Evaluator evaluator, final ResultRecorder resultRecorder, final Fixture fixture) { process(commandCall, evaluator, resultRecorder, new Runnable() { public void run() { - command.setUp(commandCall, evaluator, resultRecorder); + command.setUp(commandCall, evaluator, resultRecorder, fixture); } }); } diff --git a/src/main/java/org/concordion/api/Command.java b/src/main/java/org/concordion/api/Command.java index 6f819a7c4..a1c5ee2b4 100644 --- a/src/main/java/org/concordion/api/Command.java +++ b/src/main/java/org/concordion/api/Command.java @@ -4,7 +4,7 @@ public interface Command { - void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder); + void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture); void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture); diff --git a/src/main/java/org/concordion/api/CommandCall.java b/src/main/java/org/concordion/api/CommandCall.java index 0ae1b2a5c..8a4c23cbe 100644 --- a/src/main/java/org/concordion/api/CommandCall.java +++ b/src/main/java/org/concordion/api/CommandCall.java @@ -59,9 +59,9 @@ public CommandCall getParent() { return this.parent; } - public void setUp(Evaluator evaluator, ResultRecorder resultRecorder) { + public void setUp(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { - command.setUp(this, evaluator, resultRecorder); + command.setUp(this, evaluator, resultRecorder, fixture); } public void execute(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { diff --git a/src/main/java/org/concordion/api/CommandCallList.java b/src/main/java/org/concordion/api/CommandCallList.java index 5a88250ef..fa6f0e6e3 100644 --- a/src/main/java/org/concordion/api/CommandCallList.java +++ b/src/main/java/org/concordion/api/CommandCallList.java @@ -15,8 +15,8 @@ public boolean isEmpty() { return commandCalls.isEmpty(); } - public void setUp(Evaluator evaluator, ResultRecorder resultRecorder) { - for(CommandCall call : commandCalls) call.setUp(evaluator, resultRecorder); + public void setUp(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + for(CommandCall call : commandCalls) call.setUp(evaluator, resultRecorder, fixture); } public void execute(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { @@ -29,7 +29,7 @@ public void verify(Evaluator evaluator, ResultRecorder resultRecorder, Fixture f public void processSequentially(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { for(CommandCall call : commandCalls) { - call.setUp(evaluator, resultRecorder); + call.setUp(evaluator, resultRecorder, fixture); call.execute(evaluator, resultRecorder, fixture); call.verify(evaluator, resultRecorder, fixture); } diff --git a/src/main/java/org/concordion/internal/command/BooleanCommand.java b/src/main/java/org/concordion/internal/command/BooleanCommand.java index 136bf29c1..610e90eee 100644 --- a/src/main/java/org/concordion/internal/command/BooleanCommand.java +++ b/src/main/java/org/concordion/internal/command/BooleanCommand.java @@ -25,7 +25,7 @@ public void removeAssertListener(AssertListener listener) { public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { // Check.isFalse(commandCall.hasChildCommands(), "Nesting commands inside an 'assertTrue' is not supported"); CommandCallList childCommands = commandCall.getChildren(); - childCommands.setUp(evaluator, resultRecorder); + childCommands.setUp(evaluator, resultRecorder, fixture); childCommands.execute(evaluator, resultRecorder, fixture); childCommands.verify(evaluator, resultRecorder, fixture); diff --git a/src/main/java/org/concordion/internal/command/SetCommand.java b/src/main/java/org/concordion/internal/command/SetCommand.java index d628476b8..aa8a00ff5 100644 --- a/src/main/java/org/concordion/internal/command/SetCommand.java +++ b/src/main/java/org/concordion/internal/command/SetCommand.java @@ -21,7 +21,7 @@ public void removeSetListener(SetListener listener) { } @Override - public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { Check.isFalse(commandCall.hasChildCommands(), "Nesting commands inside a 'set' is not supported"); evaluator.setVariable(commandCall.getExpression(), commandCall.getElement().getText()); announceSetCompleted(commandCall.getElement(), commandCall.getExpression()); diff --git a/src/main/java/org/concordion/internal/command/SpecificationCommand.java b/src/main/java/org/concordion/internal/command/SpecificationCommand.java index 7572c0cb5..0feb81991 100644 --- a/src/main/java/org/concordion/internal/command/SpecificationCommand.java +++ b/src/main/java/org/concordion/internal/command/SpecificationCommand.java @@ -11,7 +11,6 @@ import org.concordion.internal.FailFastException; import org.concordion.internal.SpecificationDescriber; import org.concordion.internal.SummarizingResultRecorder; -import org.concordion.internal.XMLSpecification; import static org.concordion.internal.XMLSpecification.OUTER_EXAMPLE_NAME; @@ -22,7 +21,7 @@ public class SpecificationCommand extends AbstractCommand { private SpecificationDescriber specificationDescriber; @Override - public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { throw new IllegalStateException("Unexpected call to " + getClass().getSimpleName() + "'s setUp() method. Only the execute() method should be called."); } diff --git a/src/main/java/org/concordion/internal/command/executeCommand/ExecuteCommand.java b/src/main/java/org/concordion/internal/command/executeCommand/ExecuteCommand.java index 3fd54f90e..20fc9c371 100644 --- a/src/main/java/org/concordion/internal/command/executeCommand/ExecuteCommand.java +++ b/src/main/java/org/concordion/internal/command/executeCommand/ExecuteCommand.java @@ -71,7 +71,7 @@ public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder private void normalExecution(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { CommandCallList childCommands = commandCall.getChildren(); - childCommands.setUp(evaluator, resultRecorder); + childCommands.setUp(evaluator, resultRecorder, fixture); evaluator.evaluate(commandCall.getExpression()); childCommands.execute(evaluator, resultRecorder, fixture); announceExecuteCompleted(commandCall.getElement()); diff --git a/src/test/java/test/concordion/extension/CommandExtension.java b/src/test/java/test/concordion/extension/CommandExtension.java index dc8b2b31b..1d0f93e29 100644 --- a/src/test/java/test/concordion/extension/CommandExtension.java +++ b/src/test/java/test/concordion/extension/CommandExtension.java @@ -25,7 +25,7 @@ public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder public void modifyCommandCallTree(CommandCall element, List examples, List beforeExamples) { } - public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { } public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { From e05834c28f67dbb5de41540a6ad75275b51f0e1e Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 18 Mar 2018 23:25:23 +1300 Subject: [PATCH 05/42] Added out folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dff809386..4272228bb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ bin/ # IDEA .idea/ +out/ *.iml # Infer From 39a9bc00e68c1ca13583bb5415b117da538d8105 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 24 Mar 2018 12:18:39 +1300 Subject: [PATCH 06/42] Added JDK10 to Travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index af9604b9f..9a3dc6482 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ addons: language: java jdk: + - oraclejdk10 - oraclejdk9 - oraclejdk8 - openjdk7 From 12f2d566738d6da2f521de1e77fb719891f4c4bd Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 31 Mar 2018 16:21:50 +1300 Subject: [PATCH 07/42] Removed deprecated methods --- .../org/concordion/api/ResultSummary.java | 20 ------------------- .../internal/AbstractResultSummary.java | 15 -------------- 2 files changed, 35 deletions(-) diff --git a/src/main/java/org/concordion/api/ResultSummary.java b/src/main/java/org/concordion/api/ResultSummary.java index d6666b6ce..f2184675c 100644 --- a/src/main/java/org/concordion/api/ResultSummary.java +++ b/src/main/java/org/concordion/api/ResultSummary.java @@ -4,12 +4,6 @@ public interface ResultSummary { - /** - * @deprecated As of release 2.0, replaced by {@link #assertIsSatisfied(Fixture fixture)} - * @param fixture fixture instance - */ - @Deprecated void assertIsSatisfied(Object fixture); - void assertIsSatisfied(Fixture fixture); boolean hasExceptions(); @@ -22,22 +16,8 @@ public interface ResultSummary { long getIgnoredCount(); - /** - * @deprecated As of release 2.0, replaced by {@link #print(PrintStream, Fixture)} - * @param out stream to print result summary to - * @param fixture fixture instance - */ - @Deprecated void print(PrintStream out, Object fixture); - void print(PrintStream out, Fixture fixture); - /** - * @deprecated As of release 2.0, replaced by {@link #printCountsToString(Fixture)} - * @param fixture fixture instance - * @return string containing results - */ - @Deprecated String printCountsToString(Object fixture); - String printCountsToString(Fixture fixture); String getSpecificationDescription(); diff --git a/src/main/java/org/concordion/internal/AbstractResultSummary.java b/src/main/java/org/concordion/internal/AbstractResultSummary.java index 762b3e54d..6f39e94b6 100644 --- a/src/main/java/org/concordion/internal/AbstractResultSummary.java +++ b/src/main/java/org/concordion/internal/AbstractResultSummary.java @@ -16,11 +16,6 @@ public boolean isForExample() { return false; } - @Override @Deprecated - public void print(PrintStream out, Object fixture) { - print(out, new FixtureInstance(fixture)); - } - @Override public void print(PrintStream out, Fixture fixture) { out.print(printToString(fixture)); @@ -39,11 +34,6 @@ String printToString(Fixture fixture) { return builder.toString(); } - @Override @Deprecated - public String printCountsToString(Object fixture) { - return printCountsToString(new FixtureInstance(fixture)); - } - @Override public String printCountsToString(Fixture fixture) { StringBuilder builder = new StringBuilder(); @@ -93,9 +83,4 @@ public ImplementationStatusChecker getImplementationStatusChecker(Fixture fixtur } return ImplementationStatusChecker.implementationStatusCheckerFor(implementationStatus); } - - @Override @Deprecated - public void assertIsSatisfied(Object fixture) { - assertIsSatisfied(new FixtureInstance(fixture)); - } } From b801bd1f304982dff8fb79d1f691f06cf911252c Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 31 Mar 2018 16:22:46 +1300 Subject: [PATCH 08/42] Remove unused code --- .../annotation/BeforeAndAfterMethodHooksFixture.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java b/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java index 8a9d2031b..6a3dafd14 100644 --- a/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java +++ b/src/test/java/spec/concordion/annotation/BeforeAndAfterMethodHooksFixture.java @@ -24,10 +24,6 @@ public List getListenerLog() { return BeforeAndAfterLoggingWithListenerFixture.getLog(); } - public void simulateRun(final String href) throws Exception { - new RunCommandSimulator().simulate(href, this.getClass(), new FixtureInstance(this)); - } - @org.concordion.api.ConcordionScoped(Scope.EXAMPLE) private ScopedObjectHolder exampleScopedCounter = new ScopedObjectHolder() { @Override From da3729489325512dc8d2921807def6031295301a Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 31 Mar 2018 19:54:29 +1300 Subject: [PATCH 09/42] Changed Fixture to FixtureType for ResultSummary methods --- .../java/org/concordion/api/ResultSummary.java | 8 +++++--- .../integration/junit4/ConcordionRunner.java | 4 ++-- .../internal/AbstractResultSummary.java | 18 +++++++++--------- .../org/concordion/internal/FixtureRunner.java | 10 +++++----- .../internal/SingleResultSummary.java | 4 ++-- .../internal/SummarizingResultRecorder.java | 4 ++-- .../internal/cache/CacheResultSummary.java | 3 ++- 7 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/concordion/api/ResultSummary.java b/src/main/java/org/concordion/api/ResultSummary.java index f2184675c..4fe90d04c 100644 --- a/src/main/java/org/concordion/api/ResultSummary.java +++ b/src/main/java/org/concordion/api/ResultSummary.java @@ -1,10 +1,12 @@ package org.concordion.api; +import org.concordion.internal.FixtureType; + import java.io.PrintStream; public interface ResultSummary { - void assertIsSatisfied(Fixture fixture); + void assertIsSatisfied(FixtureType fixtureType); boolean hasExceptions(); @@ -16,9 +18,9 @@ public interface ResultSummary { long getIgnoredCount(); - void print(PrintStream out, Fixture fixture); + void print(PrintStream out, FixtureType fixtureType); - String printCountsToString(Fixture fixture); + String printCountsToString(FixtureType fixtureType); String getSpecificationDescription(); diff --git a/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java b/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java index eb32f7047..d824b4540 100644 --- a/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java +++ b/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java @@ -159,7 +159,7 @@ public void run(RunNotifier notifier) { if (results != null) { synchronized (System.out) { - results.getActualResultSummary().print(System.out, setupFixture); + results.getActualResultSummary().print(System.out, new FixtureType(setupFixture.getFixtureClass())); } } } catch (RuntimeException e) { @@ -205,7 +205,7 @@ void invoke(ConcordionFrameworkMethod concordionFrameworkMethod, Object target) try { ResultSummary result = fixtureRunner.run(example, fixture); - result.assertIsSatisfied(fixture); + result.assertIsSatisfied(new FixtureType(fixture.getFixtureClass())); } catch (ConcordionAssertionError e) { throw e; diff --git a/src/main/java/org/concordion/internal/AbstractResultSummary.java b/src/main/java/org/concordion/internal/AbstractResultSummary.java index 6f39e94b6..a542e426d 100644 --- a/src/main/java/org/concordion/internal/AbstractResultSummary.java +++ b/src/main/java/org/concordion/internal/AbstractResultSummary.java @@ -17,16 +17,16 @@ public boolean isForExample() { } @Override - public void print(PrintStream out, Fixture fixture) { - out.print(printToString(fixture)); + public void print(PrintStream out, FixtureType fixtureType) { + out.print(printToString(fixtureType)); } - String printToString(Fixture fixture) { + String printToString(FixtureType fixtureType) { StringBuilder builder = new StringBuilder(); builder.append("\n"); builder.append(specificationDescription); builder.append("\n"); - String counts = printCountsToString(fixture); + String counts = printCountsToString(fixtureType); if (counts != null) { builder.append(counts).append("\n"); } @@ -35,7 +35,7 @@ String printToString(Fixture fixture) { } @Override - public String printCountsToString(Fixture fixture) { + public String printCountsToString(FixtureType fixtureType) { StringBuilder builder = new StringBuilder(); builder.append("Successes: "); @@ -51,7 +51,7 @@ public String printCountsToString(Fixture fixture) { builder.append(getExceptionCount()); } - builder.append(getImplementationStatusChecker(fixture).printNoteToString()); + builder.append(getImplementationStatusChecker(fixtureType).printNoteToString()); return builder.toString(); } @@ -74,12 +74,12 @@ public void setImplementationStatus(ImplementationStatus implementationStatus) { this.implementationStatus = implementationStatus; } - public ImplementationStatusChecker getImplementationStatusChecker(Fixture fixture) { + public ImplementationStatusChecker getImplementationStatusChecker(FixtureType fixtureType) { ImplementationStatus implementationStatus; - if (isForExample() || fixture == null) { + if (isForExample() || fixtureType == null) { implementationStatus = getImplementationStatus(); } else { - implementationStatus = fixture.getDeclaredImplementationStatus(); + implementationStatus = fixtureType.getDeclaredImplementationStatus(); } return ImplementationStatusChecker.implementationStatusCheckerFor(implementationStatus); } diff --git a/src/main/java/org/concordion/internal/FixtureRunner.java b/src/main/java/org/concordion/internal/FixtureRunner.java index a7fa94fd5..c1c7da262 100644 --- a/src/main/java/org/concordion/internal/FixtureRunner.java +++ b/src/main/java/org/concordion/internal/FixtureRunner.java @@ -65,19 +65,19 @@ public ResultSummary run(String example, Fixture fixture) throws IOException { } if (actualResultSummary.isForExample()) { - printResultSummary(fixture, example, actualResultSummary, additionalInformation); + printResultSummary(new FixtureType(fixture.getFixtureClass()), example, actualResultSummary, additionalInformation); } return actualResultSummary; } - private void printResultSummary(Fixture fixture, String example, ResultSummary resultSummary, String additionalInformation) { + private void printResultSummary(FixtureType fixtureType, String example, ResultSummary resultSummary, String additionalInformation) { synchronized (System.out) { if (additionalInformation != null) { System.out.print(additionalInformation); } - resultSummary.print(System.out, fixture); - resultSummary.assertIsSatisfied(fixture); + resultSummary.print(System.out, fixtureType); + resultSummary.assertIsSatisfied(fixtureType); } } @@ -103,7 +103,7 @@ public ResultSummary run(Fixture fixture) throws IOException { if (results == null) { concordion.finish(); } - resultSummary.print(System.out, fixture); + resultSummary.print(System.out, new FixtureType(fixture.getFixtureClass())); return resultSummary; } } diff --git a/src/main/java/org/concordion/internal/SingleResultSummary.java b/src/main/java/org/concordion/internal/SingleResultSummary.java index 82bf22dff..a7734fbb2 100644 --- a/src/main/java/org/concordion/internal/SingleResultSummary.java +++ b/src/main/java/org/concordion/internal/SingleResultSummary.java @@ -57,8 +57,8 @@ public int hashCode() { } @Override - public void assertIsSatisfied(Fixture fixture) { - getImplementationStatusChecker(fixture).assertIsSatisfied(this, null); + public void assertIsSatisfied(FixtureType fixtureType) { + getImplementationStatusChecker(fixtureType).assertIsSatisfied(this, null); } @Override diff --git a/src/main/java/org/concordion/internal/SummarizingResultRecorder.java b/src/main/java/org/concordion/internal/SummarizingResultRecorder.java index 20fb40b35..d7a0b86d6 100644 --- a/src/main/java/org/concordion/internal/SummarizingResultRecorder.java +++ b/src/main/java/org/concordion/internal/SummarizingResultRecorder.java @@ -41,8 +41,8 @@ public void record(ResultSummary result) { } @Override - public void assertIsSatisfied(Fixture fixture) { - getImplementationStatusChecker(fixture).assertIsSatisfied(this, failFastException); + public void assertIsSatisfied(FixtureType fixtureType) { + getImplementationStatusChecker(fixtureType).assertIsSatisfied(this, failFastException); } @Override diff --git a/src/main/java/org/concordion/internal/cache/CacheResultSummary.java b/src/main/java/org/concordion/internal/cache/CacheResultSummary.java index 5903cbfcb..0958dda0d 100644 --- a/src/main/java/org/concordion/internal/cache/CacheResultSummary.java +++ b/src/main/java/org/concordion/internal/cache/CacheResultSummary.java @@ -2,6 +2,7 @@ import org.concordion.api.Fixture; import org.concordion.api.Result; +import org.concordion.internal.FixtureType; import org.concordion.internal.SingleResultSummary; class CacheResultSummary extends SingleResultSummary { @@ -11,7 +12,7 @@ public CacheResultSummary(Result result, String specificationDescription) { } @Override - public String printCountsToString(Fixture fixture) { + public String printCountsToString(FixtureType fixtureType) { // no counts for cached result summary return null; } From f4428cf734e965aa712f70ad4ff202cbda3f647f Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 31 Mar 2018 19:59:32 +1300 Subject: [PATCH 10/42] Remove unused method --- .../internal/SingleResultSummary.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/main/java/org/concordion/internal/SingleResultSummary.java b/src/main/java/org/concordion/internal/SingleResultSummary.java index a7734fbb2..8436f3536 100644 --- a/src/main/java/org/concordion/internal/SingleResultSummary.java +++ b/src/main/java/org/concordion/internal/SingleResultSummary.java @@ -11,29 +11,6 @@ public SingleResultSummary(Result result) { this.result = result; } - public SingleResultSummary(ResultSummary resultSummary) { - // exceptions always override - if (resultSummary.getExceptionCount() > 0) { - result = Result.EXCEPTION; - } else if (resultSummary.getFailureCount() > 0) { - // a single failure makes the whole thing fail - - result = Result.FAILURE; - } else if (resultSummary.getSuccessCount() > 0) { - // check success count before ignore count - as if there is a single successfull test - // then the result summary is not completly ignored. - - result = Result.SUCCESS; - } else if (resultSummary.getIgnoredCount() > 0) { - result = Result.IGNORED; - } else { - - // result summary has no tests in it. - result = Result.SUCCESS; - } - setImplementationStatus(resultSummary.getImplementationStatus()); - } - public SingleResultSummary(final Result result, String specificationDescription) { this.result = result; this.setSpecificationDescription(specificationDescription); From 32ada565734e1d85977e961f3c2a62fb044d7517 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 1 Apr 2018 13:26:05 +1200 Subject: [PATCH 11/42] Cleaned up unneeded methods --- src/main/java/org/concordion/Concordion.java | 16 ----- .../concordion/api/SpecificationLocator.java | 9 --- .../ClassNameBasedSpecificationLocator.java | 6 -- .../internal/FileTargetWithSuffix.java | 66 ------------------- .../concordion/internal/FixtureRunner.java | 2 +- .../internal/cache/RunResultsCache.java | 2 +- .../java/org/concordion/BeforeExample.java | 25 +++++++ src/test/java/test/concordion/TestRig.java | 2 +- .../resources/org/concordion/BeforeExample.md | 9 +++ 9 files changed, 37 insertions(+), 100 deletions(-) delete mode 100644 src/main/java/org/concordion/internal/FileTargetWithSuffix.java create mode 100644 src/test/java/org/concordion/BeforeExample.java create mode 100644 src/test/resources/org/concordion/BeforeExample.md diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index 6531be67a..48710dbb7 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -17,22 +17,6 @@ public class Concordion { private SpecificationByExample specification; private String specificationDescription; - /** - * @deprecated use {@link #Concordion(List, SpecificationLocator, SpecificationReader, EvaluatorFactory, Fixture)} instead - * @param specificationLocator locates the specification based on the specification type - * @param specificationReader specification reader - * @param evaluatorFactory evaluator factory - * @param fixture fixture instance - * @throws IOException on i/o error - */ - @Deprecated - public Concordion(SpecificationLocator specificationLocator, SpecificationReader specificationReader, EvaluatorFactory evaluatorFactory, Fixture fixture) throws IOException { - this.specificationReader = specificationReader; - this.evaluatorFactory = evaluatorFactory; - - resource = specificationLocator.locateSpecification(fixture.getFixtureObject()); - } - /** * Constructor. Locates the specification with a type from the specificationTypes list. * Errors if unable to find exactly one specification of all the specified types. diff --git a/src/main/java/org/concordion/api/SpecificationLocator.java b/src/main/java/org/concordion/api/SpecificationLocator.java index a6dcfd9eb..181fd51f2 100644 --- a/src/main/java/org/concordion/api/SpecificationLocator.java +++ b/src/main/java/org/concordion/api/SpecificationLocator.java @@ -1,15 +1,6 @@ package org.concordion.api; public interface SpecificationLocator { - /** - * @deprecated - use {@link #locateSpecification(Object, String)} instead - * Locates the specification for the named fixture, assuming a fixed type suffix (eg. HTML). - * @param fixture the fixture to find the specification for - * @return the resource for the specification, which may or may not actually exist - */ - @Deprecated - Resource locateSpecification(Object fixture); - /** * Locates a specification, allowing the type suffix of the specification to be specified. * @param fixtureObject the fixture to find the specification for diff --git a/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java b/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java index 7ea9f6cd8..495230065 100644 --- a/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java +++ b/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java @@ -16,12 +16,6 @@ public ClassNameBasedSpecificationLocator(String specificationSuffix) { this.specificationSuffix = specificationSuffix; } - @Override - public Resource locateSpecification(Object fixture) { - Check.notNull(fixture, "Fixture is null"); - return FixtureSpecificationMapper.toSpecificationResource(fixture, specificationSuffix); - } - @Override public Resource locateSpecification(Object fixture, String typeSuffix) { Check.notNull(fixture, "Fixture is null"); diff --git a/src/main/java/org/concordion/internal/FileTargetWithSuffix.java b/src/main/java/org/concordion/internal/FileTargetWithSuffix.java deleted file mode 100644 index 22836bcaa..000000000 --- a/src/main/java/org/concordion/internal/FileTargetWithSuffix.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.concordion.internal; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.concordion.api.Resource; -import org.concordion.api.Target; - -/** - * @deprecated Since this is overzealous and renames other resources, eg screenshots when using ScreenshotExtension. - * See issue #129. - * Users are encouraged to create their own implementations instead - eg. - * - * ExcelSuffixRenamingTarget. - */ -@Deprecated -public class FileTargetWithSuffix implements Target { - - private static final String PROPERTY_OUTPUT_DIR = "concordion.output.dir"; - private String suffix; - private FileTarget target; - - public FileTargetWithSuffix(String suffix) { - this.suffix = suffix; - target = new FileTarget(getBaseOutputDir()); - } - - private File getBaseOutputDir() { - String outputPath = System.getProperty(PROPERTY_OUTPUT_DIR); - if (outputPath == null) { - return new File(System.getProperty("java.io.tmpdir"), "concordion"); - } - return new File(outputPath); - } - - - public void write(Resource resource, String s) throws IOException { - target.write(rename(resource), s); - } - - public void copyTo(Resource resource, InputStream inputStream) throws IOException { - target.copyTo(rename(resource), inputStream); - } - - public OutputStream getOutputStream(Resource resource) throws IOException { - return target.getOutputStream(rename(resource)); - } - - public void delete(Resource resource) throws IOException { - target.delete(rename(resource)); - } - - public boolean exists(Resource resource) { - return target.exists(rename(resource)); - } - - public String resolvedPathFor(Resource resource) { - return target.resolvedPathFor(rename(resource)); - } - - private Resource rename(Resource resource) { - return new Resource(resource.getPath().replaceFirst("\\..*$", "\\." + suffix)); - } -} diff --git a/src/main/java/org/concordion/internal/FixtureRunner.java b/src/main/java/org/concordion/internal/FixtureRunner.java index c1c7da262..67e37c17c 100644 --- a/src/main/java/org/concordion/internal/FixtureRunner.java +++ b/src/main/java/org/concordion/internal/FixtureRunner.java @@ -95,7 +95,7 @@ public synchronized Concordion getConcordion() { */ @Deprecated public ResultSummary run(Fixture fixture) throws IOException { - RunOutput results = RunResultsCache.SINGLETON.getFromCache(fixture, null); + RunOutput results = RunResultsCache.SINGLETON.getFromCache(fixture.getFixtureClass(), null); ResultSummary resultSummary = run(null, fixture); diff --git a/src/main/java/org/concordion/internal/cache/RunResultsCache.java b/src/main/java/org/concordion/internal/cache/RunResultsCache.java index 0459a1682..a2c4a4d45 100644 --- a/src/main/java/org/concordion/internal/cache/RunResultsCache.java +++ b/src/main/java/org/concordion/internal/cache/RunResultsCache.java @@ -116,7 +116,7 @@ private RunOutput setResultsForExample(Fixture fixture, String example, ResultSu } private void addResultsToFixtureTotal(Fixture fixture, RunOutput exampleRunOutput) { - CompositeRunOutput fixtureRunOutput = (CompositeRunOutput) getFromCache(fixture, null); + CompositeRunOutput fixtureRunOutput = (CompositeRunOutput) getFromCache(fixture.getFixtureClass(), null); fixtureRunOutput.add(exampleRunOutput); } diff --git a/src/test/java/org/concordion/BeforeExample.java b/src/test/java/org/concordion/BeforeExample.java new file mode 100644 index 000000000..437f6e806 --- /dev/null +++ b/src/test/java/org/concordion/BeforeExample.java @@ -0,0 +1,25 @@ +package org.concordion; + +import org.concordion.integration.junit4.ConcordionRunner; +import org.junit.runner.RunWith; + +@RunWith(ConcordionRunner.class) +public class BeforeExample { + private String VBTest; + + @org.concordion.api.BeforeExample + public void init() { + System.out.println("init"); + VBTest = "Tony"; + } + + public int getSum(int a, int b) { + System.out.println(VBTest); + return a + b; + } + + public int getQuotient(int a, int b) { + System.out.println(VBTest); + return a / b; + } +} diff --git a/src/test/java/test/concordion/TestRig.java b/src/test/java/test/concordion/TestRig.java index 481c1f27a..9f41c7909 100644 --- a/src/test/java/test/concordion/TestRig.java +++ b/src/test/java/test/concordion/TestRig.java @@ -49,7 +49,7 @@ public ProcessingResult process(Resource resource) { fixture = new FixtureInstance(new DummyFixture()); withResource(new Resource("/test/concordion/Dummy.html"), ""); } else { - withResource(new ClassNameBasedSpecificationLocator("html").locateSpecification(fixture.getFixtureObject()), ""); + withResource(new ClassNameBasedSpecificationLocator("html").locateSpecification(fixture.getFixtureObject(), "html"), ""); } ConcordionBuilder concordionBuilder = new ConcordionBuilder() .withAssertEqualsListener(eventRecorder) diff --git a/src/test/resources/org/concordion/BeforeExample.md b/src/test/resources/org/concordion/BeforeExample.md new file mode 100644 index 000000000..0275b6501 --- /dev/null +++ b/src/test/resources/org/concordion/BeforeExample.md @@ -0,0 +1,9 @@ +## Sum and Divide Example + +### [Example 1. 2 + 4](- "sum2-4") +The sum of two numbers [2] (- "#firstNumber") + and [4] (- "#secondNumber") will be [6] (- "?=getSum(#firstNumber, #secondNumber)"). + +### [Example 2. 4 / 2](- "divide4-2") +Division of two numbers [4] (- "#firstNumber") + and [2] (- "#secondNumber") will be [2] (- "?=getQuotient(#firstNumber, #secondNumber)"). \ No newline at end of file From 8b9da87e78e22700c8c5a093bcdc17b277925059 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 1 Apr 2018 13:53:57 +1200 Subject: [PATCH 12/42] FixtureInstance now delegates to rather than extends FixtureType --- src/main/java/org/concordion/api/Fixture.java | 2 +- .../concordion/internal/FixtureInstance.java | 40 +++++++++++++++++-- .../results/runTotals/RunTotalsExtension.java | 3 +- .../java/org/concordion/BeforeExample.java | 25 ------------ .../test/concordion/RunCommandSimulator.java | 2 +- .../resources/org/concordion/BeforeExample.md | 9 ----- 6 files changed, 41 insertions(+), 40 deletions(-) delete mode 100644 src/test/java/org/concordion/BeforeExample.java delete mode 100644 src/test/resources/org/concordion/BeforeExample.md diff --git a/src/main/java/org/concordion/api/Fixture.java b/src/main/java/org/concordion/api/Fixture.java index 0378e0c3e..b916ff4c7 100644 --- a/src/main/java/org/concordion/api/Fixture.java +++ b/src/main/java/org/concordion/api/Fixture.java @@ -18,7 +18,7 @@ public interface Fixture extends FixtureDeclarations { /** * @return the class of the fixture instance. */ - Class getFixtureClass(); + Class getFixtureClass(); /** * @return a list of the absolute paths on the class path. diff --git a/src/main/java/org/concordion/internal/FixtureInstance.java b/src/main/java/org/concordion/internal/FixtureInstance.java index 1be932ed9..e3afe6e79 100644 --- a/src/main/java/org/concordion/internal/FixtureInstance.java +++ b/src/main/java/org/concordion/internal/FixtureInstance.java @@ -13,16 +13,20 @@ import java.util.List; import org.concordion.api.*; +import org.concordion.api.option.ConcordionOptions; import org.concordion.internal.scopedObjects.ScopedFieldStore; import org.concordion.internal.util.SimpleFormatter; -public class FixtureInstance extends FixtureType implements Fixture, FixtureDeclarations { +public class FixtureInstance implements Fixture, FixtureDeclarations { private final Object fixtureObject; private final ScopedFieldStore scopedFieldStore; + private final Class fixtureClass; + private final FixtureType fixtureType; public FixtureInstance(Object fixtureObject) { - super(fixtureObject.getClass()); this.fixtureObject = fixtureObject; + this.fixtureClass = fixtureObject.getClass(); + this.fixtureType = new FixtureType(fixtureClass); scopedFieldStore = new ScopedFieldStore(this); } @@ -126,7 +130,7 @@ public void afterProcessExample(String exampleName) { @Override public List> getClassHierarchyParentFirst() { - return super.getClassHierarchyParentFirst(); + return fixtureType.getClassHierarchyParentFirst(); } private void invokeMethods(Class methodAnnotation) { @@ -166,4 +170,34 @@ private void invokeMethods(Class methodAnnotation, Paramet } } } + + @Override + public boolean declaresFullOGNL() { + return fixtureType.declaresFullOGNL(); + } + + @Override + public boolean declaresFailFast() { + return fixtureType.declaresFailFast(); + } + + @Override + public Class[] getDeclaredFailFastExceptions() { + return fixtureType.getDeclaredFailFastExceptions(); + } + + @Override + public boolean declaresResources() { + return fixtureType.declaresResources(); + } + + @Override + public ImplementationStatus getDeclaredImplementationStatus() { + return fixtureType.getDeclaredImplementationStatus(); + } + + @Override + public List getDeclaredConcordionOptionsParentFirst() { + return fixtureType.getDeclaredConcordionOptionsParentFirst(); + } } diff --git a/src/test-dummies/java/spec/concordion/common/results/runTotals/RunTotalsExtension.java b/src/test-dummies/java/spec/concordion/common/results/runTotals/RunTotalsExtension.java index eb0ee999d..84cb806d3 100644 --- a/src/test-dummies/java/spec/concordion/common/results/runTotals/RunTotalsExtension.java +++ b/src/test-dummies/java/spec/concordion/common/results/runTotals/RunTotalsExtension.java @@ -5,6 +5,7 @@ import org.concordion.api.extension.ConcordionExtension; import org.concordion.api.listener.*; import org.concordion.internal.FixtureInstance; +import org.concordion.internal.FixtureType; public class RunTotalsExtension implements ConcordionExtension, RunListener { @@ -36,7 +37,7 @@ public void ignoredReported(RunIgnoreEvent event) { } private void writeText(AbstractRunEvent event) { - writeText(event.getElement(), event.getResultSummary().printCountsToString(new FixtureInstance(new Object()))); + writeText(event.getElement(), event.getResultSummary().printCountsToString(new FixtureType(Object.class))); } private void writeText(Element element, String text) { diff --git a/src/test/java/org/concordion/BeforeExample.java b/src/test/java/org/concordion/BeforeExample.java deleted file mode 100644 index 437f6e806..000000000 --- a/src/test/java/org/concordion/BeforeExample.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.concordion; - -import org.concordion.integration.junit4.ConcordionRunner; -import org.junit.runner.RunWith; - -@RunWith(ConcordionRunner.class) -public class BeforeExample { - private String VBTest; - - @org.concordion.api.BeforeExample - public void init() { - System.out.println("init"); - VBTest = "Tony"; - } - - public int getSum(int a, int b) { - System.out.println(VBTest); - return a + b; - } - - public int getQuotient(int a, int b) { - System.out.println(VBTest); - return a / b; - } -} diff --git a/src/test/java/test/concordion/RunCommandSimulator.java b/src/test/java/test/concordion/RunCommandSimulator.java index c97e00085..de71dc8dd 100644 --- a/src/test/java/test/concordion/RunCommandSimulator.java +++ b/src/test/java/test/concordion/RunCommandSimulator.java @@ -49,7 +49,7 @@ public Map createMap(ResultSummary recorder, boolean isOutputGen result.put("ignoredCount", Long.toString(recorder.getIgnoredCount())); result.put("exceptionCount", Long.toString(recorder.getExceptionCount())); - String counts = recorder.printCountsToString(new FixtureInstance(new Object())); + String counts = recorder.printCountsToString(new FixtureType(Object.class)); result.put("totalsString", counts); return result; diff --git a/src/test/resources/org/concordion/BeforeExample.md b/src/test/resources/org/concordion/BeforeExample.md deleted file mode 100644 index 0275b6501..000000000 --- a/src/test/resources/org/concordion/BeforeExample.md +++ /dev/null @@ -1,9 +0,0 @@ -## Sum and Divide Example - -### [Example 1. 2 + 4](- "sum2-4") -The sum of two numbers [2] (- "#firstNumber") - and [4] (- "#secondNumber") will be [6] (- "?=getSum(#firstNumber, #secondNumber)"). - -### [Example 2. 4 / 2](- "divide4-2") -Division of two numbers [4] (- "#firstNumber") - and [2] (- "#secondNumber") will be [2] (- "?=getQuotient(#firstNumber, #secondNumber)"). \ No newline at end of file From e9a25a9db0f39c642a253c40d62ba52b9f0c8a39 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Mon, 2 Apr 2018 22:12:31 +1200 Subject: [PATCH 13/42] Fixed FileSuffixExtensionsTest not failing due to change to lookup of specification types --- .../extension/FileSuffixExtensionsTest.java | 2 +- .../common/extension/SxhtmlExtension.java | 23 +++++++++++++++++++ .../common/extension/XhtmlExtension.java | 15 ------------ ...ions.xhtml => FileSuffixExtensions.sxhtml} | 2 +- 4 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 src/test/java/spec/concordion/common/extension/SxhtmlExtension.java delete mode 100644 src/test/java/spec/concordion/common/extension/XhtmlExtension.java rename src/test/resources/spec/concordion/common/extension/{FileSuffixExtensions.xhtml => FileSuffixExtensions.sxhtml} (80%) diff --git a/src/test/java/spec/concordion/common/extension/FileSuffixExtensionsTest.java b/src/test/java/spec/concordion/common/extension/FileSuffixExtensionsTest.java index 6865985cd..fd937fb38 100644 --- a/src/test/java/spec/concordion/common/extension/FileSuffixExtensionsTest.java +++ b/src/test/java/spec/concordion/common/extension/FileSuffixExtensionsTest.java @@ -5,7 +5,7 @@ import org.junit.runner.RunWith; @RunWith(ConcordionRunner.class) -@Extensions(XhtmlExtension.class) +@Extensions(SxhtmlExtension.class) public class FileSuffixExtensionsTest { public boolean hasBeenProcessed() { diff --git a/src/test/java/spec/concordion/common/extension/SxhtmlExtension.java b/src/test/java/spec/concordion/common/extension/SxhtmlExtension.java new file mode 100644 index 000000000..23467b48a --- /dev/null +++ b/src/test/java/spec/concordion/common/extension/SxhtmlExtension.java @@ -0,0 +1,23 @@ +package spec.concordion.common.extension; + +import org.concordion.api.SpecificationConverter; +import org.concordion.api.extension.ConcordionExtender; +import org.concordion.api.extension.ConcordionExtension; +import org.concordion.internal.ClassNameBasedSpecificationLocator; + +import java.io.IOException; +import java.io.InputStream; + +public class SxhtmlExtension implements ConcordionExtension { + + public void addTo(ConcordionExtender concordionExtender) { + concordionExtender + .withSpecificationType("sxhtml", new SpecificationConverter() { + @Override + public InputStream convert(InputStream inputStream, String specificationName) throws IOException { + return inputStream; + } + }); + } + +} diff --git a/src/test/java/spec/concordion/common/extension/XhtmlExtension.java b/src/test/java/spec/concordion/common/extension/XhtmlExtension.java deleted file mode 100644 index 24f22bdc8..000000000 --- a/src/test/java/spec/concordion/common/extension/XhtmlExtension.java +++ /dev/null @@ -1,15 +0,0 @@ -package spec.concordion.common.extension; - -import org.concordion.api.extension.ConcordionExtender; -import org.concordion.api.extension.ConcordionExtension; -import org.concordion.internal.ClassNameBasedSpecificationLocator; - -public class XhtmlExtension implements ConcordionExtension { - - public void addTo(ConcordionExtender concordionExtender) { - concordionExtender - .withSpecificationLocator(new ClassNameBasedSpecificationLocator("xhtml")) - .withTarget(new FileTargetWithSuffix("html")); - } - -} diff --git a/src/test/resources/spec/concordion/common/extension/FileSuffixExtensions.xhtml b/src/test/resources/spec/concordion/common/extension/FileSuffixExtensions.sxhtml similarity index 80% rename from src/test/resources/spec/concordion/common/extension/FileSuffixExtensions.xhtml rename to src/test/resources/spec/concordion/common/extension/FileSuffixExtensions.sxhtml index 78b3439c0..5f1050350 100644 --- a/src/test/resources/spec/concordion/common/extension/FileSuffixExtensions.xhtml +++ b/src/test/resources/spec/concordion/common/extension/FileSuffixExtensions.sxhtml @@ -13,7 +13,7 @@

Example

-

This specification uses a suffix of ".xhtml" and has been processed by Concordion.

+

This specification uses a suffix of ".sxhtml" and has been processed by Concordion.

See FileSuffixExtensionsTest.java for implementation details.

From ba5d39f88543e013eb4b74ae8b478e44b8d50c98 Mon Sep 17 00:00:00 2001 From: Ian Bondoc Date: Thu, 10 May 2018 16:53:26 +1200 Subject: [PATCH 14/42] Provide an extension point to allow filtering/skipping specification examples --- .../org/concordion/api/ExampleFilter.java | 20 +++++++++ .../concordion/api/ImplementationStatus.java | 3 +- src/main/java/org/concordion/api/Skipped.java | 8 ++++ .../api/extension/ConcordionExtender.java | 8 ++++ .../internal/ConcordionBuilder.java | 6 +++ .../internal/ImplementationStatusChecker.java | 29 +++++++++++++ .../internal/command/ExampleCommand.java | 34 +++++++++------ .../common/extension/ExampleFilterTest.java | 39 ++++++++++++++++++ src/test/java/test/concordion/TestRig.java | 4 +- .../common/extension/ExampleFilter.html | 41 +++++++++++++++++++ .../common/extension/Extension.html | 1 + 11 files changed, 178 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/concordion/api/ExampleFilter.java create mode 100644 src/main/java/org/concordion/api/Skipped.java create mode 100644 src/test/java/spec/concordion/common/extension/ExampleFilterTest.java create mode 100644 src/test/resources/spec/concordion/common/extension/ExampleFilter.html diff --git a/src/main/java/org/concordion/api/ExampleFilter.java b/src/main/java/org/concordion/api/ExampleFilter.java new file mode 100644 index 000000000..5254e46bb --- /dev/null +++ b/src/main/java/org/concordion/api/ExampleFilter.java @@ -0,0 +1,20 @@ +package org.concordion.api; + +/** + * An extension point to allow for skipping the execution of an example command. If the method evaluates to true then + * the the example would be marked as {@link ImplementationStatus#SKIPPED} and all the commands under the example won't + * be executed. + * + * @author Ian Bondoc + */ +public interface ExampleFilter { + + /** + * Evaluates if an example element should be skipped or not. + * + * @param exampleElement the element to evaluate + * @return true if example should be skipped, false otherwise + */ + boolean shouldSkip(Element exampleElement); + +} diff --git a/src/main/java/org/concordion/api/ImplementationStatus.java b/src/main/java/org/concordion/api/ImplementationStatus.java index e8dcb7ac5..e549f9334 100644 --- a/src/main/java/org/concordion/api/ImplementationStatus.java +++ b/src/main/java/org/concordion/api/ImplementationStatus.java @@ -5,7 +5,8 @@ public enum ImplementationStatus { UNIMPLEMENTED("Unimplemented", Unimplemented.class), EXPECTED_TO_FAIL("ExpectedToFail", ExpectedToFail.class), - EXPECTED_TO_PASS("ExpectedToPass", ExpectedToPass.class); + EXPECTED_TO_PASS("ExpectedToPass", ExpectedToPass.class), + SKIPPED("Skipped", Skipped.class); private final String tag; private final Class annotation; diff --git a/src/main/java/org/concordion/api/Skipped.java b/src/main/java/org/concordion/api/Skipped.java new file mode 100644 index 000000000..e2cfc7db5 --- /dev/null +++ b/src/main/java/org/concordion/api/Skipped.java @@ -0,0 +1,8 @@ +package org.concordion.api; + +import java.lang.annotation.*; + +@java.lang.annotation.Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Skipped { +} diff --git a/src/main/java/org/concordion/api/extension/ConcordionExtender.java b/src/main/java/org/concordion/api/extension/ConcordionExtender.java index dcebd7a52..0162627db 100644 --- a/src/main/java/org/concordion/api/extension/ConcordionExtender.java +++ b/src/main/java/org/concordion/api/extension/ConcordionExtender.java @@ -100,6 +100,14 @@ public interface ConcordionExtender { */ ConcordionExtender withExampleListener(ExampleListener listener); + /** + * Adds a filter which Concordion can apply to each specification example to decide if it should be skipped. + * + * @param filter the filter + * @return this + */ + ConcordionExtender withExampleFilter(ExampleFilter filter); + /** * Adds a listener that is invoked before and after Concordion has processed the "outer" example (which includes * all commands in a specification not inside an example command). diff --git a/src/main/java/org/concordion/internal/ConcordionBuilder.java b/src/main/java/org/concordion/internal/ConcordionBuilder.java index 15e6a45e8..f3f6671e9 100644 --- a/src/main/java/org/concordion/internal/ConcordionBuilder.java +++ b/src/main/java/org/concordion/internal/ConcordionBuilder.java @@ -435,6 +435,12 @@ public ConcordionExtender withExampleListener(ExampleListener listener) { return this; } + @Override + public ConcordionExtender withExampleFilter(ExampleFilter filter) { + exampleCommand.setExampleFilter(filter); + return this; + } + public ConcordionExtender withOuterExampleListener(OuterExampleListener listener) { specificationCommand.addOuterExampleListener(listener); return this; diff --git a/src/main/java/org/concordion/internal/ImplementationStatusChecker.java b/src/main/java/org/concordion/internal/ImplementationStatusChecker.java index 152ac7264..463f48600 100644 --- a/src/main/java/org/concordion/internal/ImplementationStatusChecker.java +++ b/src/main/java/org/concordion/internal/ImplementationStatusChecker.java @@ -121,6 +121,35 @@ public ResultSummary convertForCache(ResultSummary rs) { // if we're expected to pass, then just use the result summary. return rs; } + }, + SKIPPED(ImplementationStatus.SKIPPED) { + @Override + public void assertIsSatisfied(ResultSummary rs, FailFastException ffe) { + if (rs.getSuccessCount() + rs.getFailureCount() + rs.getExceptionCount() + rs.getIgnoredCount() > 0 || ffe != null) { + throw new ConcordionAssertionError("Example is expected to be skipped but is currently reporting.", rs); + } + } + + @Override + public String printNoteToString() { + return " <-- Note: This example has been marked as SKIPPED"; + } + + @Override + public ResultSummary getMeaningfulResultSummary(ResultSummary rs, FailFastException ffe) { + assertIsSatisfied(rs, ffe); + return new SingleResultSummary(Result.IGNORED); + } + + @Override + public ResultSummary convertForCache(ResultSummary rs) { + try { + assertIsSatisfied(rs, null); + return new SingleResultSummary(Result.IGNORED, rs.getSpecificationDescription()); + } catch (ConcordionAssertionError cce) { + return new SingleResultSummary(Result.FAILURE, rs.getSpecificationDescription()); + } + } }; private final ImplementationStatus implementationStatus; diff --git a/src/main/java/org/concordion/internal/command/ExampleCommand.java b/src/main/java/org/concordion/internal/command/ExampleCommand.java index 70291b98d..a594ffe48 100644 --- a/src/main/java/org/concordion/internal/command/ExampleCommand.java +++ b/src/main/java/org/concordion/internal/command/ExampleCommand.java @@ -13,6 +13,7 @@ public class ExampleCommand extends AbstractCommand { private List listeners = new ArrayList(); private SpecificationDescriber specificationDescriber; + private ExampleFilter exampleFilter; public List getExamples(CommandCall command) { return Arrays.asList(command); @@ -39,7 +40,11 @@ public void execute(CommandCall node, Evaluator evaluator, ResultRecorder result } try { - node.getChildren().processSequentially(evaluator, resultRecorder); + if (exampleFilter != null && exampleFilter.shouldSkip(node.getElement())) { + resultRecorder.setImplementationStatus(ImplementationStatus.SKIPPED); + } else { + node.getChildren().processSequentially(evaluator, resultRecorder); + } } catch (FailFastException f) { // Ignore - it'll be re-thrown later by the implementation status checker if necessary. } @@ -88,22 +93,23 @@ public static void setupCommandForExample(CommandCall node, ResultRecorder resul node.getElement().addAttribute("id", exampleName); String params = node.getParameter("status"); + // declared status supersedes manually set status if (params != null) { ImplementationStatus implementationStatus = ImplementationStatus.implementationStatusFor(params); resultRecorder.setImplementationStatus(implementationStatus); - // let's be really nice and add the implementation status text into the element itself. - ImplementationStatusChecker checker = ImplementationStatusChecker.implementationStatusCheckerFor(implementationStatus); + } + // let's be really nice and add the implementation status text into the element itself. + ImplementationStatusChecker checker = ImplementationStatusChecker.implementationStatusCheckerFor(resultRecorder.getImplementationStatus()); - String note; - if (checker != null) { - note = checker.printNoteToString(); - } else { - note = "Invalid status expression " + params; - } - Element fixtureNode = new Element("p"); - fixtureNode.appendText(note); - node.getElement().prependChild(fixtureNode); + String note; + if (checker != null) { + note = checker.printNoteToString(); + } else { + note = "Invalid status expression " + params; } + Element fixtureNode = new Element("p"); + fixtureNode.appendText(note); + node.getElement().prependChild(fixtureNode); } public void setSpecificationDescriber(SpecificationDescriber specificationDescriber) { @@ -121,4 +127,8 @@ private void announceAfterExample(String exampleName, Element element, ResultRec listeners.get(i).afterExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder)resultRecorder)); } } + + public void setExampleFilter(ExampleFilter exampleFilter) { + this.exampleFilter = exampleFilter; + } } diff --git a/src/test/java/spec/concordion/common/extension/ExampleFilterTest.java b/src/test/java/spec/concordion/common/extension/ExampleFilterTest.java new file mode 100644 index 000000000..108eb1f0c --- /dev/null +++ b/src/test/java/spec/concordion/common/extension/ExampleFilterTest.java @@ -0,0 +1,39 @@ +package spec.concordion.common.extension; + +import org.concordion.api.Element; +import org.concordion.api.ExampleFilter; +import org.concordion.api.FullOGNL; +import org.concordion.api.extension.ConcordionExtender; +import org.concordion.api.extension.ConcordionExtension; +import org.concordion.integration.junit4.ConcordionRunner; +import org.concordion.internal.ConcordionBuilder; +import org.junit.runner.RunWith; +import test.concordion.ProcessingResult; + +/** + * Created by bondocaadmin on 10/05/2018. + */ +@RunWith(ConcordionRunner.class) +@FullOGNL +public class ExampleFilterTest extends AbstractExtensionTestCase { + + public void addExampleFilterExtension() { + setExtension(new ConcordionExtension() { + @Override + public void addTo(ConcordionExtender concordionExtender) { + concordionExtender.withExampleFilter(new ExampleFilter() { + @Override + public boolean shouldSkip(Element exampleElement) { + String exampleName = exampleElement.getAttributeValue("example", ConcordionBuilder.NAMESPACE_CONCORDION_2007); + return exampleName.startsWith("skipped"); + } + }); + } + }); + } + + @Override + public ProcessingResult getProcessingResult() { + return super.getProcessingResult(); + } +} diff --git a/src/test/java/test/concordion/TestRig.java b/src/test/java/test/concordion/TestRig.java index 481c1f27a..b35fa7c16 100644 --- a/src/test/java/test/concordion/TestRig.java +++ b/src/test/java/test/concordion/TestRig.java @@ -72,12 +72,12 @@ public ProcessingResult process(Resource resource) { try { - ResultSummary resultSummary = null; + SummarizingResultRecorder resultSummary = new SummarizingResultRecorder(); concordion.override(resource); List examples = concordion.getExampleNames(fixture); if (!examples.isEmpty()) { for (String example : examples) { - resultSummary = concordion.processExample(fixture, example); + resultSummary.record(concordion.processExample(fixture, example)); } } concordion.finish(); diff --git a/src/test/resources/spec/concordion/common/extension/ExampleFilter.html b/src/test/resources/spec/concordion/common/extension/ExampleFilter.html new file mode 100644 index 000000000..3a7bf116c --- /dev/null +++ b/src/test/resources/spec/concordion/common/extension/ExampleFilter.html @@ -0,0 +1,41 @@ + + + +

Example Filter

+ +

+ An example filter allows a user to introduce conditional logic to decide whether concordion should skip the + execution of an example. The filter can be injected via the concordion + extensions. If provided, concordion would consult the filter prior to executing each + example in the specification. The user can create the conditional logic based on the example element (usually a <div>). +

+ +
+ +

Example

+ +

An example filter is installed that skips examples + if their name starts with skipped. +

+

Running a specification containing:

+
+<div concordion:example="aPassingExample">
+    <span concordion:set="#char">a</span> == <span concordion:assert-equals="#char">a</span>
+</div>
+<div concordion:example="aFailingExample">
+    <span concordion:set="#char">a</span> == <span concordion:assert-equals="#char">b</span>
+</div>
+<div concordion:example="skippedExample">
+    <span concordion:set="#char">c</span> == <span concordion:assert-equals="#char">c</span>
+</div>
+

Would result in +

    +
  • Success: 1
  • +
  • Failed: 1
  • +
  • Exceptions: 0
  • +
+

+
+ + + \ No newline at end of file diff --git a/src/test/resources/spec/concordion/common/extension/Extension.html b/src/test/resources/spec/concordion/common/extension/Extension.html index 01aab0a91..d391d367b 100644 --- a/src/test/resources/spec/concordion/common/extension/Extension.html +++ b/src/test/resources/spec/concordion/common/extension/Extension.html @@ -14,6 +14,7 @@

Extension

  • Create resources in the Concordion output folder
  • Add CSS or JavaScript to the Concordion output
  • Read and write to files using different file suffixes
  • +
  • Skip examples at runtime using an example filter
  • Further Questions

    From 130d3372b3da7bd0500b53853e1665ad2d52d8f6 Mon Sep 17 00:00:00 2001 From: Ian Bondoc Date: Mon, 14 May 2018 23:15:56 +1200 Subject: [PATCH 15/42] Changed ExampleFilter to ImplementationStatusModifier and changed SKIPPED to IGNORED --- .../org/concordion/api/ExampleFilter.java | 20 --------- .../concordion/api/ImplementationStatus.java | 4 +- .../api/ImplementationStatusModifier.java | 20 +++++++++ src/main/java/org/concordion/api/Skipped.java | 8 ---- .../api/extension/ConcordionExtender.java | 6 +-- .../internal/ConcordionBuilder.java | 4 +- .../internal/ImplementationStatusChecker.java | 8 ++-- .../internal/command/ExampleCommand.java | 44 ++++++++++-------- ... => ImplementationStatusModifierTest.java} | 17 ++++--- .../test/concordion/ProcessingResult.java | 4 ++ .../common/extension/ExampleFilter.html | 41 ----------------- .../common/extension/Extension.html | 2 +- .../ImplementationStatusModifier.html | 45 +++++++++++++++++++ 13 files changed, 119 insertions(+), 104 deletions(-) delete mode 100644 src/main/java/org/concordion/api/ExampleFilter.java create mode 100644 src/main/java/org/concordion/api/ImplementationStatusModifier.java delete mode 100644 src/main/java/org/concordion/api/Skipped.java rename src/test/java/spec/concordion/common/extension/{ExampleFilterTest.java => ImplementationStatusModifierTest.java} (60%) delete mode 100644 src/test/resources/spec/concordion/common/extension/ExampleFilter.html create mode 100644 src/test/resources/spec/concordion/common/extension/ImplementationStatusModifier.html diff --git a/src/main/java/org/concordion/api/ExampleFilter.java b/src/main/java/org/concordion/api/ExampleFilter.java deleted file mode 100644 index 5254e46bb..000000000 --- a/src/main/java/org/concordion/api/ExampleFilter.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.concordion.api; - -/** - * An extension point to allow for skipping the execution of an example command. If the method evaluates to true then - * the the example would be marked as {@link ImplementationStatus#SKIPPED} and all the commands under the example won't - * be executed. - * - * @author Ian Bondoc - */ -public interface ExampleFilter { - - /** - * Evaluates if an example element should be skipped or not. - * - * @param exampleElement the element to evaluate - * @return true if example should be skipped, false otherwise - */ - boolean shouldSkip(Element exampleElement); - -} diff --git a/src/main/java/org/concordion/api/ImplementationStatus.java b/src/main/java/org/concordion/api/ImplementationStatus.java index e549f9334..5045ceba8 100644 --- a/src/main/java/org/concordion/api/ImplementationStatus.java +++ b/src/main/java/org/concordion/api/ImplementationStatus.java @@ -1,12 +1,14 @@ package org.concordion.api; +import org.junit.Ignore; + import java.lang.annotation.Annotation; public enum ImplementationStatus { UNIMPLEMENTED("Unimplemented", Unimplemented.class), EXPECTED_TO_FAIL("ExpectedToFail", ExpectedToFail.class), EXPECTED_TO_PASS("ExpectedToPass", ExpectedToPass.class), - SKIPPED("Skipped", Skipped.class); + IGNORED("Ignored", Ignore.class); private final String tag; private final Class annotation; diff --git a/src/main/java/org/concordion/api/ImplementationStatusModifier.java b/src/main/java/org/concordion/api/ImplementationStatusModifier.java new file mode 100644 index 000000000..1d13b9aac --- /dev/null +++ b/src/main/java/org/concordion/api/ImplementationStatusModifier.java @@ -0,0 +1,20 @@ +package org.concordion.api; + +/** + * Examples can be marked as {@code Unimplemented}, {@code ExpectedToFail}, or {@code Ignored} declaratively via + * c:status attribute. If the status needs to be determined at runtime, this extension point can be used. + * + * @author Ian Bondoc + * @see ImplementationStatus + */ +public interface ImplementationStatusModifier { + + /** + * Determine an example element's {@code ImplementationStatus} + * + * @param exampleElement the element to evaluate + * @return the status based on the exampleElement + */ + ImplementationStatus getStatusForExample(Element exampleElement); + +} diff --git a/src/main/java/org/concordion/api/Skipped.java b/src/main/java/org/concordion/api/Skipped.java deleted file mode 100644 index e2cfc7db5..000000000 --- a/src/main/java/org/concordion/api/Skipped.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.concordion.api; - -import java.lang.annotation.*; - -@java.lang.annotation.Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Skipped { -} diff --git a/src/main/java/org/concordion/api/extension/ConcordionExtender.java b/src/main/java/org/concordion/api/extension/ConcordionExtender.java index 0162627db..aebb823d2 100644 --- a/src/main/java/org/concordion/api/extension/ConcordionExtender.java +++ b/src/main/java/org/concordion/api/extension/ConcordionExtender.java @@ -101,12 +101,12 @@ public interface ConcordionExtender { ConcordionExtender withExampleListener(ExampleListener listener); /** - * Adds a filter which Concordion can apply to each specification example to decide if it should be skipped. + * Adds a status modifier which Concordion can apply to each specification example to override their status. * - * @param filter the filter + * @param statusModifier the status modifier * @return this */ - ConcordionExtender withExampleFilter(ExampleFilter filter); + ConcordionExtender withImplementationStatusModifier(ImplementationStatusModifier statusModifier); /** * Adds a listener that is invoked before and after Concordion has processed the "outer" example (which includes diff --git a/src/main/java/org/concordion/internal/ConcordionBuilder.java b/src/main/java/org/concordion/internal/ConcordionBuilder.java index f3f6671e9..743ea7348 100644 --- a/src/main/java/org/concordion/internal/ConcordionBuilder.java +++ b/src/main/java/org/concordion/internal/ConcordionBuilder.java @@ -436,8 +436,8 @@ public ConcordionExtender withExampleListener(ExampleListener listener) { } @Override - public ConcordionExtender withExampleFilter(ExampleFilter filter) { - exampleCommand.setExampleFilter(filter); + public ConcordionExtender withImplementationStatusModifier(ImplementationStatusModifier statusModifier) { + exampleCommand.setImplementationStatusModifier(statusModifier); return this; } diff --git a/src/main/java/org/concordion/internal/ImplementationStatusChecker.java b/src/main/java/org/concordion/internal/ImplementationStatusChecker.java index 463f48600..d75367cdc 100644 --- a/src/main/java/org/concordion/internal/ImplementationStatusChecker.java +++ b/src/main/java/org/concordion/internal/ImplementationStatusChecker.java @@ -122,17 +122,17 @@ public ResultSummary convertForCache(ResultSummary rs) { return rs; } }, - SKIPPED(ImplementationStatus.SKIPPED) { + IGNORED(ImplementationStatus.IGNORED) { @Override public void assertIsSatisfied(ResultSummary rs, FailFastException ffe) { - if (rs.getSuccessCount() + rs.getFailureCount() + rs.getExceptionCount() + rs.getIgnoredCount() > 0 || ffe != null) { - throw new ConcordionAssertionError("Example is expected to be skipped but is currently reporting.", rs); + if (rs.getIgnoredCount() != 1 || rs.getSuccessCount() + rs.getFailureCount() + rs.getExceptionCount() > 0 || ffe != null) { + throw new ConcordionAssertionError("Example is expected to be ignored but is currently reporting.", rs); } } @Override public String printNoteToString() { - return " <-- Note: This example has been marked as SKIPPED"; + return " <-- Note: This example has been marked as IGNORED"; } @Override diff --git a/src/main/java/org/concordion/internal/command/ExampleCommand.java b/src/main/java/org/concordion/internal/command/ExampleCommand.java index a594ffe48..9feefeeb4 100644 --- a/src/main/java/org/concordion/internal/command/ExampleCommand.java +++ b/src/main/java/org/concordion/internal/command/ExampleCommand.java @@ -13,7 +13,7 @@ public class ExampleCommand extends AbstractCommand { private List listeners = new ArrayList(); private SpecificationDescriber specificationDescriber; - private ExampleFilter exampleFilter; + private ImplementationStatusModifier implementationStatusModifier; public List getExamples(CommandCall command) { return Arrays.asList(command); @@ -40,8 +40,10 @@ public void execute(CommandCall node, Evaluator evaluator, ResultRecorder result } try { - if (exampleFilter != null && exampleFilter.shouldSkip(node.getElement())) { - resultRecorder.setImplementationStatus(ImplementationStatus.SKIPPED); + ImplementationStatus status = getImplementationStatus(node); + resultRecorder.setImplementationStatus(status); + if (status == ImplementationStatus.IGNORED) { + resultRecorder.record(Result.IGNORED); } else { node.getChildren().processSequentially(evaluator, resultRecorder); } @@ -89,26 +91,32 @@ protected boolean isBeforeExample(CommandCall element) { return element.getExpression().equals("before"); } - public static void setupCommandForExample(CommandCall node, ResultRecorder resultRecorder, String exampleName) { - node.getElement().addAttribute("id", exampleName); - + private ImplementationStatus getImplementationStatus(CommandCall node) { + // by default the implementation status is expected to pass + ImplementationStatus implementationStatus = ImplementationStatus.EXPECTED_TO_PASS; + // if there's a status param, it overrides expected to pass String params = node.getParameter("status"); - // declared status supersedes manually set status if (params != null) { - ImplementationStatus implementationStatus = ImplementationStatus.implementationStatusFor(params); - resultRecorder.setImplementationStatus(implementationStatus); + implementationStatus = ImplementationStatus.implementationStatusFor(params); } + // if there's a status modifier and there's a status for the example, it overrides status param + if (implementationStatusModifier != null) { + ImplementationStatus runtimeImplementation = implementationStatusModifier.getStatusForExample(node.getElement()); + if (runtimeImplementation != null) { + implementationStatus = runtimeImplementation; + } + } + return implementationStatus; + } + + public static void setupCommandForExample(CommandCall node, ResultRecorder resultRecorder, String exampleName) { + node.getElement().addAttribute("id", exampleName); + // let's be really nice and add the implementation status text into the element itself. ImplementationStatusChecker checker = ImplementationStatusChecker.implementationStatusCheckerFor(resultRecorder.getImplementationStatus()); - String note; - if (checker != null) { - note = checker.printNoteToString(); - } else { - note = "Invalid status expression " + params; - } Element fixtureNode = new Element("p"); - fixtureNode.appendText(note); + fixtureNode.appendText(checker.printNoteToString()); node.getElement().prependChild(fixtureNode); } @@ -128,7 +136,7 @@ private void announceAfterExample(String exampleName, Element element, ResultRec } } - public void setExampleFilter(ExampleFilter exampleFilter) { - this.exampleFilter = exampleFilter; + public void setImplementationStatusModifier(ImplementationStatusModifier implementationStatusModifier) { + this.implementationStatusModifier = implementationStatusModifier; } } diff --git a/src/test/java/spec/concordion/common/extension/ExampleFilterTest.java b/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java similarity index 60% rename from src/test/java/spec/concordion/common/extension/ExampleFilterTest.java rename to src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java index 108eb1f0c..575409264 100644 --- a/src/test/java/spec/concordion/common/extension/ExampleFilterTest.java +++ b/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java @@ -1,7 +1,8 @@ package spec.concordion.common.extension; import org.concordion.api.Element; -import org.concordion.api.ExampleFilter; +import org.concordion.api.ImplementationStatus; +import org.concordion.api.ImplementationStatusModifier; import org.concordion.api.FullOGNL; import org.concordion.api.extension.ConcordionExtender; import org.concordion.api.extension.ConcordionExtension; @@ -15,17 +16,21 @@ */ @RunWith(ConcordionRunner.class) @FullOGNL -public class ExampleFilterTest extends AbstractExtensionTestCase { +public class ImplementationStatusModifierTest extends AbstractExtensionTestCase { - public void addExampleFilterExtension() { + public void addExtension() { setExtension(new ConcordionExtension() { @Override public void addTo(ConcordionExtender concordionExtender) { - concordionExtender.withExampleFilter(new ExampleFilter() { + concordionExtender.withImplementationStatusModifier(new ImplementationStatusModifier() { @Override - public boolean shouldSkip(Element exampleElement) { + public ImplementationStatus getStatusForExample(Element exampleElement) { String exampleName = exampleElement.getAttributeValue("example", ConcordionBuilder.NAMESPACE_CONCORDION_2007); - return exampleName.startsWith("skipped"); + if (exampleName.endsWith("Ignored")) { + return ImplementationStatus.IGNORED; + } else { + return null; + } } }); } diff --git a/src/test/java/test/concordion/ProcessingResult.java b/src/test/java/test/concordion/ProcessingResult.java index 5c02f0432..5a558bba6 100644 --- a/src/test/java/test/concordion/ProcessingResult.java +++ b/src/test/java/test/concordion/ProcessingResult.java @@ -36,6 +36,10 @@ public long getExceptionCount() { return resultSummary.getExceptionCount(); } + public long getIgnoredCount() { + return resultSummary.getIgnoredCount(); + } + public AssertFailureEvent getLastAssertFailureEvent() { return (AssertFailureEvent) eventRecorder.getLast(AssertFailureEvent.class); } diff --git a/src/test/resources/spec/concordion/common/extension/ExampleFilter.html b/src/test/resources/spec/concordion/common/extension/ExampleFilter.html deleted file mode 100644 index 3a7bf116c..000000000 --- a/src/test/resources/spec/concordion/common/extension/ExampleFilter.html +++ /dev/null @@ -1,41 +0,0 @@ - - - -

    Example Filter

    - -

    - An example filter allows a user to introduce conditional logic to decide whether concordion should skip the - execution of an example. The filter can be injected via the concordion - extensions. If provided, concordion would consult the filter prior to executing each - example in the specification. The user can create the conditional logic based on the example element (usually a <div>). -

    - -
    - -

    Example

    - -

    An example filter is installed that skips examples - if their name starts with skipped. -

    -

    Running a specification containing:

    -
    -<div concordion:example="aPassingExample">
    -    <span concordion:set="#char">a</span> == <span concordion:assert-equals="#char">a</span>
    -</div>
    -<div concordion:example="aFailingExample">
    -    <span concordion:set="#char">a</span> == <span concordion:assert-equals="#char">b</span>
    -</div>
    -<div concordion:example="skippedExample">
    -    <span concordion:set="#char">c</span> == <span concordion:assert-equals="#char">c</span>
    -</div>
    -

    Would result in -

      -
    • Success: 1
    • -
    • Failed: 1
    • -
    • Exceptions: 0
    • -
    -

    -
    - - - \ No newline at end of file diff --git a/src/test/resources/spec/concordion/common/extension/Extension.html b/src/test/resources/spec/concordion/common/extension/Extension.html index d391d367b..dbe007ae7 100644 --- a/src/test/resources/spec/concordion/common/extension/Extension.html +++ b/src/test/resources/spec/concordion/common/extension/Extension.html @@ -14,7 +14,7 @@

    Extension

  • Create resources in the Concordion output folder
  • Add CSS or JavaScript to the Concordion output
  • Read and write to files using different file suffixes
  • -
  • Skip examples at runtime using an example filter
  • +
  • Modify ImplementationStatus of examples at runtime
  • Further Questions

    diff --git a/src/test/resources/spec/concordion/common/extension/ImplementationStatusModifier.html b/src/test/resources/spec/concordion/common/extension/ImplementationStatusModifier.html new file mode 100644 index 000000000..918775223 --- /dev/null +++ b/src/test/resources/spec/concordion/common/extension/ImplementationStatusModifier.html @@ -0,0 +1,45 @@ + + + +

    ImplementationStatusModifier

    + +

    + An ImplementationStatusModifier allows a user to specify an example's + ImplementationStatus at runtime. The status modifier can be injected via the concordion extensions. + If provided, it will override a declared implementation status via c:status attribute. The user can + create the conditional logic based on the example element (usually a <div>). +

    + +
    + +

    Example

    + +

    An ImplementationStatusModifier is installed that sets the + status of an example to IGNORED if the example name ends in Ignored. +

    +

    Running a specification containing:

    +
    +<div concordion:example="aPassingExample">
    +    <span concordion:set="#char">a</span> == <span concordion:assert-equals="#char">a</span>
    +</div>
    +<div concordion:example="aFailingExample">
    +    <span concordion:set="#char">a</span> == <span concordion:assert-equals="#char">b</span>
    +</div>
    +<div concordion:example="expectedToFailExample" concordion:status="ExpectedToFail">
    +    <span concordion:set="#char">c</span> == <span concordion:assert-equals="#char">d</span>
    +</div>
    +<div concordion:example="expectedToFailExampleButIgnored" concordion:status="ExpectedToFail">
    +    <span concordion:set="#char">a</span> == <span concordion:assert-equals="#char">b</span>
    +</div>
    +

    Would result in +

      +
    • Success: 1
    • +
    • Failed: 2
    • +
    • Exceptions: 0
    • +
    • Ignored: 1
    • +
    +

    +
    + + + \ No newline at end of file From cb0592132d712f9b1dcea613afcd6887cd905afa Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 2 Jun 2018 07:16:48 +1200 Subject: [PATCH 16/42] Moved methods from Fixture to FixtureType --- src/main/java/org/concordion/Concordion.java | 43 ++++----- src/main/java/org/concordion/api/Fixture.java | 29 +----- .../api/SpecificationByExample.java | 10 +- .../concordion/api/SpecificationLocator.java | 6 +- .../api/SpecificationLocatorWithType.java | 10 -- .../junit3/ConcordionTestCase.java | 4 +- .../integration/junit4/ConcordionRunner.java | 12 +-- ...sNameAndTypeBasedSpecificationLocator.java | 5 +- .../ClassNameBasedSpecificationLocator.java | 17 +--- .../internal/ConcordionBuilder.java | 18 ++-- .../concordion/internal/FixtureInstance.java | 92 ++----------------- .../internal/FixtureOptionsLoader.java | 5 +- .../concordion/internal/FixtureRunner.java | 24 +++-- .../internal/FixtureSpecificationMapper.java | 4 +- .../org/concordion/internal/FixtureType.java | 49 +++++++++- .../internal/ImplementationStatusChecker.java | 4 +- .../concordion/internal/ResourceFinder.java | 10 +- ...cationToSpecificationByExampleAdaptor.java | 4 +- .../concordion/internal/XMLSpecification.java | 4 +- .../internal/cache/RunResultsCache.java | 83 ++++++++--------- .../extension/FixtureExtensionLoader.java | 2 +- .../scopedObjects/ScopedFieldStore.java | 35 +++++-- ...lassNameBasedSpecificationLocatorTest.java | 9 +- .../runner/CachedResultsUnitTest.java | 17 ++-- src/test/java/test/concordion/TestRig.java | 6 +- 25 files changed, 224 insertions(+), 278 deletions(-) delete mode 100644 src/main/java/org/concordion/api/SpecificationLocatorWithType.java diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index 48710dbb7..9c769a848 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -4,6 +4,7 @@ import java.util.List; import org.concordion.api.*; +import org.concordion.internal.FixtureType; import org.concordion.internal.SpecificationToSpecificationByExampleAdaptor; import org.concordion.internal.SpecificationType; import org.concordion.internal.SummarizingResultRecorder; @@ -35,17 +36,17 @@ public Concordion(List specificationTypes, SpecificationLocat SpecificationType specificationType = null; for (SpecificationType currentType : specificationTypes) { - Resource currentResource = specificationLocator.locateSpecification(fixture.getFixtureObject(), currentType.getTypeSuffix()); + Resource currentResource = specificationLocator.locateSpecification(fixture.getFixtureType(), currentType.getTypeSuffix()); if (specificationReader.canFindSpecification(currentResource)) { if (specificationType != null) { - throw new RuntimeException(createMultipleSpecsMessage(fixture, specificationType, currentType)); + throw new RuntimeException(createMultipleSpecsMessage(fixture.getFixtureType(), specificationType, currentType)); } specificationType = currentType; resource = currentResource; } } if (specificationType == null) { - throw new RuntimeException(createUnableToFindSpecMessage(fixture, specificationTypes)); + throw new RuntimeException(createUnableToFindSpecMessage(fixture.getFixtureType(), specificationTypes)); } specificationReader.setSpecificationConverter(specificationType.getConverter()); } @@ -61,42 +62,42 @@ public void override(Resource resource) throws IOException { public ResultSummary process(Fixture fixture) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(); - resultRecorder.setSpecificationDescription(fixture.getSpecificationDescription()); - getSpecification(fixture).process(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), resultRecorder, fixture); + resultRecorder.setSpecificationDescription(fixture.getFixtureType().getSpecificationDescription()); + getSpecification(fixture.getFixtureType()).process(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), resultRecorder, fixture); return resultRecorder; } - private SpecificationByExample getSpecification(Fixture fixture) throws IOException { + private SpecificationByExample getSpecification(FixtureType fixtureType) throws IOException { if (specification == null) { - specification = loadSpecificationFromResource(fixture, resource); + specification = loadSpecificationFromResource(resource, fixtureType); specificationDescription = specification.getSpecificationDescription(); } return specification; } - public List getExampleNames(Fixture fixture) throws IOException { - return getSpecification(fixture).getExampleNames(); + public List getExampleNames(FixtureType fixtureType) throws IOException { + return getSpecification(fixtureType).getExampleNames(); } - public boolean hasExampleCommands(Fixture fixture) throws IOException { - return getSpecification(fixture).hasExampleCommandNodes(); + public boolean hasExampleCommands(FixtureType fixtureType) throws IOException { + return getSpecification(fixtureType).hasExampleCommandNodes(); } public ResultSummary processExample(Fixture fixture, String example) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(example); - getSpecification(fixture).processExample(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), example, resultRecorder, fixture); + getSpecification(fixture.getFixtureType()).processExample(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), example, resultRecorder, fixture); return resultRecorder; } /** * Loads the specification for the specified fixture. * - * @param fixture the fixture instance * @param resource the resource to load + * @param fixtureType * @return a SpecificationByExample object to use * @throws IOException if the resource cannot be loaded */ - private SpecificationByExample loadSpecificationFromResource(Fixture fixture, Resource resource) throws IOException { + private SpecificationByExample loadSpecificationFromResource(Resource resource, FixtureType fixtureType) throws IOException { Specification specification= specificationReader.readSpecification(resource); SpecificationByExample specificationByExample; @@ -105,7 +106,7 @@ private SpecificationByExample loadSpecificationFromResource(Fixture fixture, Re } else { specificationByExample = new SpecificationToSpecificationByExampleAdaptor(specification); } - specificationByExample.setFixture(fixture); + specificationByExample.setFixture(fixtureType); return specificationByExample; } @@ -113,21 +114,21 @@ public void finish() { specification.finish(); } - public void checkValidStatus(Fixture fixture) throws IOException { - if (getSpecification(fixture).hasExampleCommandNodes() && fixture.getDeclaredImplementationStatus() != ImplementationStatus.EXPECTED_TO_PASS) { + public void checkValidStatus(FixtureType fixtureType) throws IOException { + if (hasExampleCommands(fixtureType) && fixtureType.getDeclaredImplementationStatus() != ImplementationStatus.EXPECTED_TO_PASS) { throw new IllegalStateException("Error: When the specification contains examples, " + "the Implementation Status (ExpectedToFail or Unimplemented) must be set on the example command in the specification, " + "and not as an annotation on the fixture."); } } - private String createMultipleSpecsMessage(Fixture fixture, SpecificationType type1, SpecificationType type2) { - String fixturePathWithoutSuffix = fixture.getFixturePathWithoutSuffix(); + private String createMultipleSpecsMessage(FixtureType fixtureType, SpecificationType type1, SpecificationType type2) { + String fixturePathWithoutSuffix = fixtureType.getFixturePathWithoutSuffix(); return SimpleFormatter.format("Found multiple matching specifications: '%s.%s' and '%s.%s'", fixturePathWithoutSuffix, type1.getTypeSuffix(), fixturePathWithoutSuffix, type2.getTypeSuffix()); } - private String createUnableToFindSpecMessage(Fixture fixture, List specificationTypes) { + private String createUnableToFindSpecMessage(FixtureType fixtureType, List specificationTypes) { String msg = "Unable to find specification: '"; boolean first = true; for (SpecificationType specificationType : specificationTypes) { @@ -136,7 +137,7 @@ private String createUnableToFindSpecMessage(Fixture fixture, List getFixtureClass(); - - /** - * @return a list of the absolute paths on the class path. - */ - List getClassPathRoots(); - - /** - * @return the fixture class and all of its superclasses, excluding java.lang.Object, - * ordered from the most super class to the fixture class. - */ - List> getClassHierarchyParentFirst(); - - /** - * @return a description of the specification containing the fixture name. - */ - String getSpecificationDescription(); - - /** - * @return the absolute path to the fixture, omitting the suffix. + * @return the FixtureType, which is a wrapper around the fixtureObject's class. */ - String getFixturePathWithoutSuffix(); + FixtureType getFixtureType(); /** * Setup the fixture for the next run, hence the need to pass in a fixture object. diff --git a/src/main/java/org/concordion/api/SpecificationByExample.java b/src/main/java/org/concordion/api/SpecificationByExample.java index 7aab64d4b..fb0f9e3e4 100644 --- a/src/main/java/org/concordion/api/SpecificationByExample.java +++ b/src/main/java/org/concordion/api/SpecificationByExample.java @@ -1,5 +1,7 @@ package org.concordion.api; +import org.concordion.internal.FixtureType; + import java.util.List; /** @@ -13,9 +15,9 @@ public interface SpecificationByExample extends Specification { * Sets the fixture. Will be called before the other methods are called so that * the class can process the fixture to determine examples, etc. * - * @param fixture the fixture instance - */ - void setFixture(Fixture fixture); + * @param fixtureType + */ + void setFixture(FixtureType fixtureType); /** * Returns whether the specification contains example nodes. @@ -40,7 +42,7 @@ public interface SpecificationByExample extends Specification { /** * Processes a single example. - * @param evaluator evaluator + * @param evaluator evaluator * @param example name of the example * @param resultRecorder result recorder * @param fixture the example's fixture diff --git a/src/main/java/org/concordion/api/SpecificationLocator.java b/src/main/java/org/concordion/api/SpecificationLocator.java index 181fd51f2..b3bf4a0a4 100644 --- a/src/main/java/org/concordion/api/SpecificationLocator.java +++ b/src/main/java/org/concordion/api/SpecificationLocator.java @@ -1,13 +1,15 @@ package org.concordion.api; +import org.concordion.internal.FixtureType; + public interface SpecificationLocator { /** * Locates a specification, allowing the type suffix of the specification to be specified. - * @param fixtureObject the fixture to find the specification for + * @param fixtureType the fixture type to find the specification for * @param typeSuffix the suffix of the specification * @return the resource for the specification, which may or may not actually exist * * @since 2.0.0 */ - Resource locateSpecification(Object fixtureObject, String typeSuffix); + Resource locateSpecification(FixtureType fixtureType, String typeSuffix); } diff --git a/src/main/java/org/concordion/api/SpecificationLocatorWithType.java b/src/main/java/org/concordion/api/SpecificationLocatorWithType.java deleted file mode 100644 index 8d8c0e1d6..000000000 --- a/src/main/java/org/concordion/api/SpecificationLocatorWithType.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.concordion.api; - -/** - * Locates a specification, allowing the type suffix of the specification to be specified. - * - * @since 2.0.0 - */ -public interface SpecificationLocatorWithType { - Resource locateSpecification(Object fixtureObject, String typeSuffix); -} diff --git a/src/main/java/org/concordion/integration/junit3/ConcordionTestCase.java b/src/main/java/org/concordion/integration/junit3/ConcordionTestCase.java index e9d9569dd..5abcde81e 100644 --- a/src/main/java/org/concordion/integration/junit3/ConcordionTestCase.java +++ b/src/main/java/org/concordion/integration/junit3/ConcordionTestCase.java @@ -3,7 +3,7 @@ import junit.framework.TestCase; import org.concordion.api.Fixture; -import org.concordion.internal.ClassNameAndTypeBasedSpecificationLocator; +import org.concordion.internal.ClassNameBasedSpecificationLocator; import org.concordion.internal.FixtureInstance; import org.concordion.internal.FixtureRunner; @@ -20,7 +20,7 @@ public void testProcessSpecification() throws Throwable { Fixture fixture = new FixtureInstance(this); fixture.beforeSpecification(); fixture.setupForRun(this); - new FixtureRunner(fixture, new ClassNameAndTypeBasedSpecificationLocator()).run(fixture); + new FixtureRunner(fixture, new ClassNameBasedSpecificationLocator()).run(fixture); fixture.afterSpecification(); } } diff --git a/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java b/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java index d824b4540..1261fffd5 100644 --- a/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java +++ b/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java @@ -66,9 +66,9 @@ public ConcordionRunner(Class fixtureClass) throws InitializationError { concordion = fixtureRunner.getConcordion(); try { - concordion.checkValidStatus(setupFixture); + concordion.checkValidStatus(setupFixture.getFixtureType()); - List examples = concordion.getExampleNames(setupFixture); + List examples = concordion.getExampleNames(setupFixture.getFixtureType()); verifyUniqueExampleMethods(examples); @@ -82,7 +82,7 @@ public ConcordionRunner(Class fixtureClass) throws InitializationError { } protected SpecificationLocator getSpecificationLocator() { - return new ClassNameAndTypeBasedSpecificationLocator(); + return new ClassNameBasedSpecificationLocator(); } private void verifyUniqueExampleMethods(List exampleNames) throws InitializationError { @@ -143,7 +143,7 @@ public void run(RunNotifier notifier) { // only setup the fixture if it hasn't been run before if (firstRun) { - runResultsCache.startFixtureRun(setupFixture, concordion.getSpecificationDescription()); + runResultsCache.startFixtureRun(setupFixture.getFixtureType(), concordion.getSpecificationDescription()); setupFixture.beforeSpecification(); } @@ -159,7 +159,7 @@ public void run(RunNotifier notifier) { if (results != null) { synchronized (System.out) { - results.getActualResultSummary().print(System.out, new FixtureType(setupFixture.getFixtureClass())); + results.getActualResultSummary().print(System.out, setupFixture.getFixtureType()); } } } catch (RuntimeException e) { @@ -205,7 +205,7 @@ void invoke(ConcordionFrameworkMethod concordionFrameworkMethod, Object target) try { ResultSummary result = fixtureRunner.run(example, fixture); - result.assertIsSatisfied(new FixtureType(fixture.getFixtureClass())); + result.assertIsSatisfied(fixture.getFixtureType()); } catch (ConcordionAssertionError e) { throw e; diff --git a/src/main/java/org/concordion/internal/ClassNameAndTypeBasedSpecificationLocator.java b/src/main/java/org/concordion/internal/ClassNameAndTypeBasedSpecificationLocator.java index b344cd078..b0510b3c2 100644 --- a/src/main/java/org/concordion/internal/ClassNameAndTypeBasedSpecificationLocator.java +++ b/src/main/java/org/concordion/internal/ClassNameAndTypeBasedSpecificationLocator.java @@ -1,6 +1,7 @@ package org.concordion.internal; -import org.concordion.api.SpecificationLocatorWithType; +import org.concordion.api.Resource; -public class ClassNameAndTypeBasedSpecificationLocator extends ClassNameBasedSpecificationLocator implements SpecificationLocatorWithType { +public abstract class ClassNameAndTypeBasedSpecificationLocator extends ClassNameBasedSpecificationLocator { + public abstract Resource locateSpecification(FixtureType fixtureType, String typeSuffix); } diff --git a/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java b/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java index 495230065..8ca15b383 100644 --- a/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java +++ b/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java @@ -5,20 +5,9 @@ import org.concordion.internal.util.Check; public class ClassNameBasedSpecificationLocator implements SpecificationLocator { - - private String specificationSuffix; - - public ClassNameBasedSpecificationLocator() { - this("html"); - } - - public ClassNameBasedSpecificationLocator(String specificationSuffix) { - this.specificationSuffix = specificationSuffix; - } - @Override - public Resource locateSpecification(Object fixture, String typeSuffix) { - Check.notNull(fixture, "Fixture is null"); - return FixtureSpecificationMapper.toSpecificationResource(fixture, typeSuffix); + public Resource locateSpecification(FixtureType fixtureType, String typeSuffix) { + Check.notNull(fixtureType, "Fixture is null"); + return FixtureSpecificationMapper.toSpecificationResource(fixtureType, typeSuffix); } } diff --git a/src/main/java/org/concordion/internal/ConcordionBuilder.java b/src/main/java/org/concordion/internal/ConcordionBuilder.java index 652eb4fdb..4c148d324 100644 --- a/src/main/java/org/concordion/internal/ConcordionBuilder.java +++ b/src/main/java/org/concordion/internal/ConcordionBuilder.java @@ -36,7 +36,7 @@ public class ConcordionBuilder implements ConcordionExtender { private static final String EMBEDDED_STYLESHEET_RESOURCE = "/org/concordion/internal/resource/embedded.css"; private static File baseOutputDir; - private SpecificationLocator specificationLocator = new ClassNameAndTypeBasedSpecificationLocator(); + private SpecificationLocator specificationLocator = new ClassNameBasedSpecificationLocator(); private Map sources = new HashMap(); private Target target = null; private CommandRegistry commandRegistry = new CommandRegistry(); @@ -415,15 +415,15 @@ public ConcordionBuilder withFailFast(Class[] failFastExcep return this; } - public ConcordionBuilder withFixture(Fixture fixture) { + public ConcordionBuilder withFixture(Fixture fixture, FixtureType fixtureType) { this.fixture = fixture; - withResources(fixture); + withResources(fixtureType); - if (fixture.declaresFailFast()) { - withFailFast(fixture.getDeclaredFailFastExceptions()); + if (fixtureType.declaresFailFast()) { + withFailFast(fixtureType.getDeclaredFailFastExceptions()); } - if (fixture.declaresFullOGNL()) { + if (fixtureType.declaresFullOGNL()) { withEvaluatorFactory(new OgnlEvaluatorFactory()); } @@ -440,12 +440,12 @@ public ConcordionExtender withOuterExampleListener(OuterExampleListener listener return this; } - public ConcordionBuilder withResources(Fixture fixture) { + public ConcordionBuilder withResources(FixtureType fixtureType) { boolean includeDefaultStyling = true; Source resourceSource = sources.get(SourceType.RESOURCE); - if (fixture.declaresResources()) { - ResourceFinder resources = new ResourceFinder(fixture); + if (fixtureType.declaresResources()) { + ResourceFinder resources = new ResourceFinder(fixtureType); List sourceFiles = resources.getResourcesToCopy(); for (ResourceToCopy sourceFile : sourceFiles) { diff --git a/src/main/java/org/concordion/internal/FixtureInstance.java b/src/main/java/org/concordion/internal/FixtureInstance.java index e3afe6e79..baad579cb 100644 --- a/src/main/java/org/concordion/internal/FixtureInstance.java +++ b/src/main/java/org/concordion/internal/FixtureInstance.java @@ -1,23 +1,14 @@ package org.concordion.internal; -import java.io.File; -import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.AnnotationFormatError; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; import org.concordion.api.*; -import org.concordion.api.option.ConcordionOptions; import org.concordion.internal.scopedObjects.ScopedFieldStore; -import org.concordion.internal.util.SimpleFormatter; -public class FixtureInstance implements Fixture, FixtureDeclarations { +public class FixtureInstance implements Fixture { private final Object fixtureObject; private final ScopedFieldStore scopedFieldStore; private final Class fixtureClass; @@ -39,48 +30,12 @@ public String toString() { public Object getFixtureObject() { return fixtureObject; } - - @Override - public Class getFixtureClass() { - return fixtureClass; - } - - @Override - public String getSpecificationDescription() { - String name = removeSuffix(fixtureClass.getSimpleName()); - return SimpleFormatter.format("[Concordion Specification for '%s']", name); // Based on suggestion by Danny Guerrier - } @Override - public String getFixturePathWithoutSuffix() { - String slashedClassName = fixtureClass.getName().replaceAll("\\.", "/"); - return removeSuffix(slashedClassName); - } - - private String removeSuffix(String fixtureName) { - return FixtureSpecificationMapper.removeSuffixFromFixtureName(fixtureName); + public FixtureType getFixtureType() { + return fixtureType; } - - @Override - public List getClassPathRoots() { - List rootPaths = new ArrayList(); - - Enumeration resources; - try { - resources = fixtureClass.getClassLoader().getResources(""); - - while (resources.hasMoreElements()) { - rootPaths.add(new File(resources.nextElement().toURI())); - } - } catch (IOException e) { - throw new RuntimeException("Unable to get root path", e); - } catch (URISyntaxException e) { - throw new RuntimeException("Unable to get root path", e); - } - - return rootPaths; - } - + @Override public void setupForRun(Object fixtureObject) { scopedFieldStore.loadValuesIntoFields(fixtureObject, Scope.SPECIFICATION); @@ -127,18 +82,13 @@ public void afterExample(String exampleName) { public void afterProcessExample(String exampleName) { scopedFieldStore.destroyFields(fixtureObject, Scope.EXAMPLE); } - - @Override - public List> getClassHierarchyParentFirst() { - return fixtureType.getClassHierarchyParentFirst(); - } - + private void invokeMethods(Class methodAnnotation) { invokeMethods(methodAnnotation, null); } private void invokeMethods(Class methodAnnotation, ParameterSupplier parameterSupplier) { - for (Class clazz : getClassHierarchyParentFirst()) { + for (Class clazz : fixtureType.getClassHierarchyParentFirst()) { Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { @@ -170,34 +120,4 @@ private void invokeMethods(Class methodAnnotation, Paramet } } } - - @Override - public boolean declaresFullOGNL() { - return fixtureType.declaresFullOGNL(); - } - - @Override - public boolean declaresFailFast() { - return fixtureType.declaresFailFast(); - } - - @Override - public Class[] getDeclaredFailFastExceptions() { - return fixtureType.getDeclaredFailFastExceptions(); - } - - @Override - public boolean declaresResources() { - return fixtureType.declaresResources(); - } - - @Override - public ImplementationStatus getDeclaredImplementationStatus() { - return fixtureType.getDeclaredImplementationStatus(); - } - - @Override - public List getDeclaredConcordionOptionsParentFirst() { - return fixtureType.getDeclaredConcordionOptionsParentFirst(); - } } diff --git a/src/main/java/org/concordion/internal/FixtureOptionsLoader.java b/src/main/java/org/concordion/internal/FixtureOptionsLoader.java index 0778b532c..2211e123d 100644 --- a/src/main/java/org/concordion/internal/FixtureOptionsLoader.java +++ b/src/main/java/org/concordion/internal/FixtureOptionsLoader.java @@ -2,12 +2,11 @@ import java.util.List; -import org.concordion.api.FixtureDeclarations; import org.concordion.api.option.ConcordionOptions; public class FixtureOptionsLoader { - public void addOptions(FixtureDeclarations fixture, ConcordionBuilder concordionBuilder) { - List classAnnotations = fixture.getDeclaredConcordionOptionsParentFirst(); + public void addOptions(FixtureType fixtureType, ConcordionBuilder concordionBuilder) { + List classAnnotations = fixtureType.getDeclaredConcordionOptionsParentFirst(); for (ConcordionOptions options : classAnnotations) { concordionBuilder.configureWith(options); } diff --git a/src/main/java/org/concordion/internal/FixtureRunner.java b/src/main/java/org/concordion/internal/FixtureRunner.java index 67e37c17c..30a497cd0 100644 --- a/src/main/java/org/concordion/internal/FixtureRunner.java +++ b/src/main/java/org/concordion/internal/FixtureRunner.java @@ -14,15 +14,15 @@ public class FixtureRunner { private Concordion concordion; public FixtureRunner(Fixture fixture, SpecificationLocator specificationLocator) throws UnableToBuildConcordionException { - ConcordionBuilder concordionBuilder = new ConcordionBuilder().withFixture(fixture).withSpecificationLocator(specificationLocator); + ConcordionBuilder concordionBuilder = new ConcordionBuilder().withFixture(fixture, fixture.getFixtureType()).withSpecificationLocator(specificationLocator); new FixtureExtensionLoader().addExtensions(fixture, concordionBuilder); - new FixtureOptionsLoader().addOptions(fixture, concordionBuilder); + new FixtureOptionsLoader().addOptions(fixture.getFixtureType(), concordionBuilder); concordion = concordionBuilder.build(); } public ResultSummary run(String example, Fixture fixture) throws IOException { - RunOutput runOutput = runResultsCache.startRun(fixture, example); + RunOutput runOutput = runResultsCache.startRun(fixture.getFixtureType(), example); ResultSummary actualResultSummary = runOutput==null? null: runOutput.getActualResultSummary(); @@ -37,26 +37,24 @@ public ResultSummary run(String example, Fixture fixture) throws IOException { try { actualResultSummary = concordion.processExample(fixture, example); statusChecker = ImplementationStatusChecker.getImplementationStatusChecker( - fixture, - actualResultSummary.getImplementationStatus()); + fixture.getFixtureType(), actualResultSummary.getImplementationStatus()); } finally { fixture.afterProcessExample(example); } } else { actualResultSummary = concordion.process(fixture); statusChecker = ImplementationStatusChecker.getImplementationStatusChecker( - fixture, - null); + fixture.getFixtureType(), null); } - runResultsCache.finishRun(fixture, - example, + runResultsCache.finishRun( + fixture.getFixtureType(), example, actualResultSummary, statusChecker); } catch (RuntimeException e) { // the run failed miserably. Tell the cache that the run failed - runResultsCache.failRun(fixture, example); + runResultsCache.failRun(fixture.getFixtureType(), example); throw e; } @@ -65,7 +63,7 @@ public ResultSummary run(String example, Fixture fixture) throws IOException { } if (actualResultSummary.isForExample()) { - printResultSummary(new FixtureType(fixture.getFixtureClass()), example, actualResultSummary, additionalInformation); + printResultSummary(fixture.getFixtureType(), example, actualResultSummary, additionalInformation); } return actualResultSummary; @@ -95,7 +93,7 @@ public synchronized Concordion getConcordion() { */ @Deprecated public ResultSummary run(Fixture fixture) throws IOException { - RunOutput results = RunResultsCache.SINGLETON.getFromCache(fixture.getFixtureClass(), null); + RunOutput results = RunResultsCache.SINGLETON.getFromCache(fixture.getFixtureType(), null); ResultSummary resultSummary = run(null, fixture); @@ -103,7 +101,7 @@ public ResultSummary run(Fixture fixture) throws IOException { if (results == null) { concordion.finish(); } - resultSummary.print(System.out, new FixtureType(fixture.getFixtureClass())); + resultSummary.print(System.out, fixture.getFixtureType()); return resultSummary; } } diff --git a/src/main/java/org/concordion/internal/FixtureSpecificationMapper.java b/src/main/java/org/concordion/internal/FixtureSpecificationMapper.java index e14f4fbdc..d67d19ff1 100644 --- a/src/main/java/org/concordion/internal/FixtureSpecificationMapper.java +++ b/src/main/java/org/concordion/internal/FixtureSpecificationMapper.java @@ -25,8 +25,8 @@ protected ServiceLoader initialValue() { } }; - public static Resource toSpecificationResource(Object fixture, String specificationSuffix) { - String slashedClassName = fixture.getClass().getName().replaceAll("\\.", "/"); + public static Resource toSpecificationResource(FixtureType fixtureType, String specificationSuffix) { + String slashedClassName = fixtureType.getFixtureClass().getName().replaceAll("\\.", "/"); String fixturePath = removeSuffixFromFixtureName(slashedClassName); String resourcePath = "/" + fixturePath + "." + specificationSuffix; diff --git a/src/main/java/org/concordion/internal/FixtureType.java b/src/main/java/org/concordion/internal/FixtureType.java index 4996a97bf..1c39f65dc 100644 --- a/src/main/java/org/concordion/internal/FixtureType.java +++ b/src/main/java/org/concordion/internal/FixtureType.java @@ -1,17 +1,23 @@ package org.concordion.internal; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; import java.util.Collections; +import java.util.Enumeration; import java.util.List; import org.concordion.api.*; import org.concordion.api.option.ConcordionOptions; +import org.concordion.internal.util.SimpleFormatter; public class FixtureType implements FixtureDeclarations { - protected Class fixtureClass; + private Class fixtureClass; private ArrayList> classHierarchyParentFirst; - + public FixtureType(Class fixtureClass) { this.fixtureClass = fixtureClass; } @@ -57,7 +63,7 @@ public ImplementationStatus getDeclaredImplementationStatus() { * @return the fixture class and all of its superclasses, excluding java.lang.Object, * ordered from the most super class to the fixture class. */ - protected List> getClassHierarchyParentFirst() { + public List> getClassHierarchyParentFirst() { if (classHierarchyParentFirst != null) { return classHierarchyParentFirst; } @@ -84,4 +90,41 @@ public List getDeclaredConcordionOptionsParentFirst() { } return annotations; } + + public Class getFixtureClass() { + return fixtureClass; + } + + public List getClassPathRoots() { + List rootPaths = new ArrayList(); + + Enumeration resources; + try { + resources = getFixtureClass().getClassLoader().getResources(""); + + while (resources.hasMoreElements()) { + rootPaths.add(new File(resources.nextElement().toURI())); + } + } catch (IOException e) { + throw new RuntimeException("Unable to get root path", e); + } catch (URISyntaxException e) { + throw new RuntimeException("Unable to get root path", e); + } + + return rootPaths; + } + + public String getSpecificationDescription() { + String name = removeSuffix(fixtureClass.getSimpleName()); + return SimpleFormatter.format("[Concordion Specification for '%s']", name); // Based on suggestion by Danny Guerrier + } + + public String getFixturePathWithoutSuffix() { + String slashedClassName = fixtureClass.getName().replaceAll("\\.", "/"); + return removeSuffix(slashedClassName); + } + + private String removeSuffix(String fixtureName) { + return FixtureSpecificationMapper.removeSuffixFromFixtureName(fixtureName); + } } diff --git a/src/main/java/org/concordion/internal/ImplementationStatusChecker.java b/src/main/java/org/concordion/internal/ImplementationStatusChecker.java index 152ac7264..5be264548 100644 --- a/src/main/java/org/concordion/internal/ImplementationStatusChecker.java +++ b/src/main/java/org/concordion/internal/ImplementationStatusChecker.java @@ -149,13 +149,13 @@ public ImplementationStatus getImplementationStatus() { return implementationStatus; } - public static ImplementationStatusChecker getImplementationStatusChecker(Fixture fixture, ImplementationStatus implementationStatus) { + public static ImplementationStatusChecker getImplementationStatusChecker(FixtureType fixtureType, ImplementationStatus implementationStatus) { // examples have precedence if (implementationStatus != null) { return implementationStatusCheckerFor(implementationStatus); } - return implementationStatusCheckerFor(fixture.getDeclaredImplementationStatus()); + return implementationStatusCheckerFor(fixtureType.getDeclaredImplementationStatus()); } public static ImplementationStatusChecker implementationStatusCheckerFor(ImplementationStatus implementationStatus) { diff --git a/src/main/java/org/concordion/internal/ResourceFinder.java b/src/main/java/org/concordion/internal/ResourceFinder.java index 8f5e8aad5..7e587f883 100644 --- a/src/main/java/org/concordion/internal/ResourceFinder.java +++ b/src/main/java/org/concordion/internal/ResourceFinder.java @@ -19,22 +19,22 @@ * @author sumnera */ public class ResourceFinder { - private Fixture fixture; + private FixtureType fixtureType; private boolean includeDefaultStyling = true; public boolean includeDefaultStyling() { return this.includeDefaultStyling; } - public ResourceFinder(Fixture fixture) { - this.fixture = fixture; + public ResourceFinder(FixtureType fixtureType) { + this.fixtureType = fixtureType; } public List getResourcesToCopy() { List sourceFiles = new ArrayList(); - List rootPaths = fixture.getClassPathRoots(); - List> classes = fixture.getClassHierarchyParentFirst(); + List rootPaths = fixtureType.getClassPathRoots(); + List> classes = fixtureType.getClassHierarchyParentFirst(); for (Class class1 : classes) { if (isAnnotationDeclared(class1, ConcordionResources.class)) { diff --git a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java index e79792970..f42c49cfe 100644 --- a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java +++ b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java @@ -21,8 +21,8 @@ public void process(Evaluator evaluator, ResultRecorder resultRecorder, Fixture specification.process(evaluator, resultRecorder, fixture); } - public void setFixture(Fixture fixture) { - testDescription = fixture.getSpecificationDescription(); + public void setFixture(FixtureType fixtureType) { + testDescription = fixtureType.getSpecificationDescription(); } public void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder, Fixture fixture) { diff --git a/src/main/java/org/concordion/internal/XMLSpecification.java b/src/main/java/org/concordion/internal/XMLSpecification.java index 546058354..e56f8b4ce 100644 --- a/src/main/java/org/concordion/internal/XMLSpecification.java +++ b/src/main/java/org/concordion/internal/XMLSpecification.java @@ -65,11 +65,11 @@ public void process(Evaluator evaluator, ResultRecorder resultRecorder, Fixture processNode(rootCommandNode, evaluator, resultRecorder, fixture); } - public void setFixture(Fixture fixture) { + public void setFixture(FixtureType fixtureType) { if (hasExampleCommandNodes()) { testDescription = OUTER_EXAMPLE_NAME; } else { - testDescription = fixture.getSpecificationDescription(); + testDescription = fixtureType.getSpecificationDescription(); } } diff --git a/src/main/java/org/concordion/internal/cache/RunResultsCache.java b/src/main/java/org/concordion/internal/cache/RunResultsCache.java index a2c4a4d45..8b4a1442d 100644 --- a/src/main/java/org/concordion/internal/cache/RunResultsCache.java +++ b/src/main/java/org/concordion/internal/cache/RunResultsCache.java @@ -3,8 +3,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.concordion.api.Fixture; import org.concordion.api.ResultSummary; +import org.concordion.internal.FixtureType; import org.concordion.internal.ImplementationStatusChecker; import org.concordion.internal.RunOutput; @@ -16,17 +16,6 @@ public enum RunResultsCache { Map map = new ConcurrentHashMap(); - /** - * Provides a direct method to access the cache - * - * @param fixture fixture containing class to retrieve from the cache - * @param example the example to get from the cache - * @return can return null if not in the cache - */ - public RunOutput getFromCache(Fixture fixture, String example) { - return getFromCache(fixture.getFixtureClass(), example); - } - /** * Provides a direct method to access the cache * @@ -38,46 +27,55 @@ public synchronized RunOutput getFromCache(Class fixtureClass, String example return map.get(getID(fixtureClass, example)); } + /** + * Provides a direct method to access the cache + * + * @param fixtureType class to retrieve from the cache + * @param example the example to get from the cache + * @return can return null if not in the cache + */ + public synchronized RunOutput getFromCache(FixtureType fixtureType, String example) { + return map.get(getID(fixtureType, example)); + } + /** * Initialises an entry in the cache for a specification with the given description. * Individual examples may then be run, and their results will be added to the fixture - * total when {@link #finishRun(Fixture, String, ResultSummary, ImplementationStatusChecker)} + * total when {@link #finishRun(FixtureType, String, ResultSummary, ImplementationStatusChecker)} * is called. - * - * @param fixture the fixture that is being started + * @param fixtureType the fixture class that is being started * @param specificationDescription a description of the target specification */ - public synchronized void startFixtureRun(Fixture fixture, String specificationDescription) { + public synchronized void startFixtureRun(FixtureType fixtureType, String specificationDescription) { CompositeRunOutput fixtureRunOutput = new CompositeRunOutput(specificationDescription); - map.put(getID(fixture, null), fixtureRunOutput); + map.put(getID(fixtureType, null), fixtureRunOutput); } /** * Searches for a match in the cache. If there is no match, it marks the test as "in progress". * This is done in one method to avoid thread synchronization issues. * - * @param fixture the fixture to retrieve + * @param fixtureType the fixture class to retrieve * @param example the name of the example that is being started (null OK) - * * @return the result summary from the cache */ - public synchronized RunOutput startRun(Fixture fixture, String example) { - assert fixture.getFixtureClass() != null; + public synchronized RunOutput startRun(FixtureType fixtureType, String example) { + assert fixtureType.getFixtureClass() != null; // check to see if there is a result in the cache - RunOutput runSummary = getExampleFromCache(fixture, example); + RunOutput runSummary = getExampleFromCache(fixtureType, example); if (runSummary != null) { return runSummary; } // no cached result, so update the cache - that means we can detect circular dependencies runSummary = new ConcordionRunOutput(); - map.put(getID(fixture, example), runSummary); + map.put(getID(fixtureType, example), runSummary); return null; } - private CacheKey getID(Fixture fixture, String example) { - return getID(fixture.getFixtureClass(), example); + private CacheKey getID(FixtureType fixtureType, String example) { + return getID(fixtureType.getFixtureClass(), example); } private CacheKey getID(Class fixtureClass, String example) { @@ -86,27 +84,26 @@ private CacheKey getID(Class fixtureClass, String example) { /** * Updates the cache with the results of a run. - * @param fixture the fixture to update + * @param fixtureType the fixture class to update * @param example the name of the example that is being finished (null ok) * @param actualResultSummary the results as reported from the spec * @param statusChecker modifier that updates results dependent on ImplementationStatus (ExpectedToFail etc) */ - public synchronized void finishRun(Fixture fixture, - String example, + public synchronized void finishRun(FixtureType fixtureType, String example, ResultSummary actualResultSummary, ImplementationStatusChecker statusChecker) { - assert fixture.getFixtureClass() != null; + assert fixtureType.getFixtureClass() != null; assert actualResultSummary != null; - RunOutput exampleRunOutput = setResultsForExample(fixture, example, actualResultSummary, statusChecker); + RunOutput exampleRunOutput = setResultsForExample(fixtureType, example, actualResultSummary, statusChecker); if (example != null) { - addResultsToFixtureTotal(fixture, exampleRunOutput); + addResultsToFixtureTotal(fixtureType, exampleRunOutput); } } - private RunOutput setResultsForExample(Fixture fixture, String example, ResultSummary actualResultSummary, ImplementationStatusChecker statusChecker) { - ConcordionRunOutput exampleResults = (ConcordionRunOutput) getExampleFromCache(fixture, example); + private RunOutput setResultsForExample(FixtureType fixtureType, String example, ResultSummary actualResultSummary, ImplementationStatusChecker statusChecker) { + ConcordionRunOutput exampleResults = (ConcordionRunOutput) getExampleFromCache(fixtureType, example); if (exampleResults == null) { throw new IllegalStateException("Internal error: startRun must always be called before finishRun"); } @@ -115,31 +112,31 @@ private RunOutput setResultsForExample(Fixture fixture, String example, ResultSu return exampleResults; } - private void addResultsToFixtureTotal(Fixture fixture, RunOutput exampleRunOutput) { - CompositeRunOutput fixtureRunOutput = (CompositeRunOutput) getFromCache(fixture.getFixtureClass(), null); + private void addResultsToFixtureTotal(FixtureType fixtureType, RunOutput exampleRunOutput) { + CompositeRunOutput fixtureRunOutput = (CompositeRunOutput) getFromCache(fixtureType.getFixtureClass(), null); fixtureRunOutput.add(exampleRunOutput); } - private RunOutput getExampleFromCache(Fixture fixture, String example) { - return map.get(getID(fixture, example)); + private RunOutput getExampleFromCache(FixtureType fixtureType, String example) { + return map.get(getID(fixtureType, example)); } /** * Run failed. Remove our placeholder value. - * @param fixture the fixture to update + * @param fixtureType fixture class that failed * @param example the name of the example that failed */ - public synchronized void failRun(Fixture fixture, String example) { - map.remove(getID(fixture, example)); + public synchronized void failRun(FixtureType fixtureType, String example) { + map.remove(getID(fixtureType, example)); } /** * For test purposes only - * @param fixture fixture to remove cache results for + * @param fixtureType fixture class to remove cache results for */ - public void removeAllFromCache(Fixture fixture) { + public void removeAllFromCache(FixtureType fixtureType) { for (CacheKey key : map.keySet()) { - if (key.isForClass(fixture.getFixtureClass())) { + if (key.isForClass(fixtureType.getFixtureClass())) { map.remove(key); } } diff --git a/src/main/java/org/concordion/internal/extension/FixtureExtensionLoader.java b/src/main/java/org/concordion/internal/extension/FixtureExtensionLoader.java index a2c3866e4..296e470f5 100644 --- a/src/main/java/org/concordion/internal/extension/FixtureExtensionLoader.java +++ b/src/main/java/org/concordion/internal/extension/FixtureExtensionLoader.java @@ -25,7 +25,7 @@ public void addExtensions(Fixture fixture, ConcordionBuilder concordionBuilder) public List getExtensionsForFixture(Fixture fixture) { final List extensions = new ArrayList(); - List> classes = fixture.getClassHierarchyParentFirst(); + List> classes = fixture.getFixtureType().getClassHierarchyParentFirst(); for (Class class1 : classes) { extensions.addAll(getExtensionsFromClassAnnotation(class1)); extensions.addAll(getExtensionsFromAnnotatedFields(fixture, class1)); diff --git a/src/main/java/org/concordion/internal/scopedObjects/ScopedFieldStore.java b/src/main/java/org/concordion/internal/scopedObjects/ScopedFieldStore.java index e283349b2..60d0b2723 100644 --- a/src/main/java/org/concordion/internal/scopedObjects/ScopedFieldStore.java +++ b/src/main/java/org/concordion/internal/scopedObjects/ScopedFieldStore.java @@ -12,6 +12,7 @@ import org.concordion.api.Scope; import org.concordion.api.ScopedObjectHolder; import org.concordion.api.extension.Extension; +import org.concordion.internal.FixtureType; import org.concordion.internal.util.SimpleFormatter; public class ScopedFieldStore { @@ -35,15 +36,15 @@ public ScopedFieldStore(Fixture fixture) { } private void createScopedFields(Fixture fixture) { - for (Class clazz : fixture.getClassHierarchyParentFirst()) { + for (Class clazz : fixture.getFixtureType().getClassHierarchyParentFirst()) { Field[] fields = clazz.getDeclaredFields(); if (fields != null) { for (Field field : fields) { if (field.getAnnotation(ConcordionScoped.class) != null) { - createScopedObjectField(fixture.getFixtureClass(), field); + createScopedObjectField(fixture.getFixtureType(), field); } if (field.getAnnotation(Extension.class) != null) { - createScopedExtensionField(fixture.getFixtureClass(), field); + createScopedExtensionField(fixture.getFixtureType(), field); } } } @@ -51,6 +52,10 @@ private void createScopedFields(Fixture fixture) { } private void createScopedObjectField(Class fixtureClass, Field field) { + createScopedObjectField(fixtureClass, field); + } + + private void createScopedObjectField(FixtureType fixtureType, Field field) { if (!field.getType().equals(ScopedObjectHolder.class)) { throw new AnnotationFormatError(SimpleFormatter.format("The '%s' annotation can only be applied to fields of type '%s'", ConcordionScoped.class.getSimpleName(), ScopedObjectHolder.class.getSimpleName())); } @@ -58,15 +63,19 @@ private void createScopedObjectField(Class fixtureClass, Field field) { ConcordionScoped annotation = field.getAnnotation(ConcordionScoped.class); Scope fieldScope = annotation.value(); String name = field.getName(); - ScopedObject scopedObject = createScopedObject(fixtureClass, name, fieldScope); + ScopedObject scopedObject = createScopedObject(fixtureType, name, fieldScope); scopedFields.get(fieldScope).add(new ScopedFieldImpl(scopedObject, field)); } private void createScopedExtensionField(Class fixtureClass, Field field) { - ScopedObject scopedObject = createScopedObject(fixtureClass, field.getName(), DEFAULT_EXTENSION_SCOPE); + createScopedExtensionField(fixtureClass, field); + } + + private void createScopedExtensionField(FixtureType fixtureType, Field field) { + ScopedObject scopedObject = createScopedObject(fixtureType, field.getName(), DEFAULT_EXTENSION_SCOPE); scopedFields.get(DEFAULT_EXTENSION_SCOPE).add(new ScopedFieldImpl(scopedObject, field)); } - + /** * Creates the scoped object for use in setting and getting the data from the fields. Protected so that a subclass can * override if necessary. @@ -76,7 +85,19 @@ private void createScopedExtensionField(Class fixtureClass, Field field) { * @return scoped object */ protected ScopedObject createScopedObject(Class fixtureClass, String fieldName, Scope fieldScope) { - return ScopedObjectFactory.SINGLETON.create(fixtureClass, fieldName, fieldScope); + return createScopedObject(fixtureClass, fieldName, fieldScope); + } + + /** + * Creates the scoped object for use in setting and getting the data from the fields. Protected so that a subclass can + * override if necessary. + * @param fixtureType fixture class + * @param fieldName name of field in fixture class + * @param fieldScope scope to be applied to the field + * @return scoped object + */ + protected ScopedObject createScopedObject(FixtureType fixtureType, String fieldName, Scope fieldScope) { + return ScopedObjectFactory.SINGLETON.create(fixtureType.getFixtureClass(), fieldName, fieldScope); } diff --git a/src/test/java/org/concordion/internal/ClassNameBasedSpecificationLocatorTest.java b/src/test/java/org/concordion/internal/ClassNameBasedSpecificationLocatorTest.java index 33ffbf0ab..98a2134e6 100644 --- a/src/test/java/org/concordion/internal/ClassNameBasedSpecificationLocatorTest.java +++ b/src/test/java/org/concordion/internal/ClassNameBasedSpecificationLocatorTest.java @@ -3,22 +3,23 @@ import junit.framework.TestCase; import org.concordion.api.SpecificationLocator; +import spec.concordion.common.command.execute.ContinueAfterExceptionsFixture; public class ClassNameBasedSpecificationLocatorTest extends TestCase { public void testRemovesWordTestFromEndOfClassNameAndAppendsDotHTML() throws Exception { SpecificationLocator locator = new ClassNameBasedSpecificationLocator(); - assertEquals("/org/concordion/internal/ClassNameBasedSpecificationLocator.html", locator.locateSpecification(this, "html").getPath()); + assertEquals("/org/concordion/internal/ClassNameBasedSpecificationLocator.html", locator.locateSpecification(new FixtureType(this.getClass()), "html").getPath()); } public void testRemovesWordFixtureFromEndOfClassNameAndAppendsDotHTML() throws Exception { SpecificationLocator locator = new ClassNameBasedSpecificationLocator(); assertEquals("/spec/concordion/common/command/execute/ContinueAfterExceptions.html", - locator.locateSpecification(new spec.concordion.common.command.execute.ContinueAfterExceptionsFixture(), "html").getPath()); + locator.locateSpecification(new FixtureType(ContinueAfterExceptionsFixture.class), "html").getPath()); } public void testCanAppendDotXHTMLWhenConstructedWithXHTMLArgument() throws Exception { - SpecificationLocator locator = new ClassNameBasedSpecificationLocator("xhtml"); - assertEquals("/org/concordion/internal/ClassNameBasedSpecificationLocator.xhtml", locator.locateSpecification(this, "xhtml").getPath()); + SpecificationLocator locator = new ClassNameBasedSpecificationLocator(); + assertEquals("/org/concordion/internal/ClassNameBasedSpecificationLocator.xhtml", locator.locateSpecification(new FixtureType(this.getClass()), "xhtml").getPath()); } } diff --git a/src/test/java/org/concordion/internal/runner/CachedResultsUnitTest.java b/src/test/java/org/concordion/internal/runner/CachedResultsUnitTest.java index ed9d7fa8a..3c31ef457 100644 --- a/src/test/java/org/concordion/internal/runner/CachedResultsUnitTest.java +++ b/src/test/java/org/concordion/internal/runner/CachedResultsUnitTest.java @@ -7,6 +7,7 @@ import static org.junit.Assert.assertThat; import org.concordion.internal.FixtureInstance; +import org.concordion.internal.FixtureType; import org.concordion.internal.RunOutput; import org.concordion.internal.cache.RunResultsCache; import org.junit.Before; @@ -21,17 +22,17 @@ public class CachedResultsUnitTest { @Before public void before() { - runResults.removeAllFromCache(new FixtureInstance(this)); + runResults.removeAllFromCache(new FixtureType(this.getClass())); } @Test public void testCacheInProgress() { // basically before a run, runResults.startRun should return null - showing that nothing is in progress - assertNull(runResults.startRun(new FixtureInstance(this), null)); + assertNull(runResults.startRun(new FixtureType(this.getClass()), null)); // but if it's called again, we'll get some "in progress" results - RunOutput concordionRunOutput = runResults.startRun(new FixtureInstance(this), null); + RunOutput concordionRunOutput = runResults.startRun(new FixtureType(this.getClass()), null); assertNotNull(concordionRunOutput); assertThat(concordionRunOutput.getActualResultSummary().getExceptionCount(), is(equalTo(0L))); assertThat(concordionRunOutput.getActualResultSummary().getSuccessCount(), is(equalTo(0L))); @@ -49,10 +50,10 @@ public void testCacheInProgress() { public void testCacheInProgressWithExample() { // basically before a run, runResults.startRun should return null - showing that nothing is in progress - assertNull(runResults.startRun(new FixtureInstance(this), EXAMPLE_1_NAME)); + assertNull(runResults.startRun(new FixtureType(this.getClass()), EXAMPLE_1_NAME)); // but if it's called again, we'll get some "in progress" results - RunOutput concordionRunOutput = runResults.startRun(new FixtureInstance(this), EXAMPLE_1_NAME); + RunOutput concordionRunOutput = runResults.startRun(new FixtureType(this.getClass()), EXAMPLE_1_NAME); assertNotNull(concordionRunOutput); assertThat(concordionRunOutput.getActualResultSummary().getExceptionCount(), is(equalTo(0L))); assertThat(concordionRunOutput.getActualResultSummary().getSuccessCount(), is(equalTo(0L))); @@ -72,11 +73,11 @@ public void testNotFoundInCache() { // some tests to check that examples are independent // two examples from the same class - assertNull(runResults.startRun(new FixtureInstance(this), EXAMPLE_1_NAME)); - assertNull(runResults.startRun(new FixtureInstance(this), EXAMPLE_2_NAME)); + assertNull(runResults.startRun(new FixtureType(this.getClass()), EXAMPLE_1_NAME)); + assertNull(runResults.startRun(new FixtureType(this.getClass()), EXAMPLE_2_NAME)); // now a same named example from a different class - assertNull(runResults.startRun(new FixtureInstance(new JustAnotherClass()), EXAMPLE_2_NAME)); + assertNull(runResults.startRun(new FixtureType(JustAnotherClass.class), EXAMPLE_2_NAME)); } private static class JustAnotherClass {}; diff --git a/src/test/java/test/concordion/TestRig.java b/src/test/java/test/concordion/TestRig.java index 9f41c7909..e4ba9a174 100644 --- a/src/test/java/test/concordion/TestRig.java +++ b/src/test/java/test/concordion/TestRig.java @@ -49,7 +49,7 @@ public ProcessingResult process(Resource resource) { fixture = new FixtureInstance(new DummyFixture()); withResource(new Resource("/test/concordion/Dummy.html"), ""); } else { - withResource(new ClassNameBasedSpecificationLocator("html").locateSpecification(fixture.getFixtureObject(), "html"), ""); + withResource(new ClassNameBasedSpecificationLocator().locateSpecification(fixture.getFixtureType(), "html"), ""); } ConcordionBuilder concordionBuilder = new ConcordionBuilder() .withAssertEqualsListener(eventRecorder) @@ -57,7 +57,7 @@ public ProcessingResult process(Resource resource) { .withSource(source) .withEvaluatorFactory(evaluatorFactory) .withTarget(stubTarget) - .withFixture(fixture); + .withFixture(fixture, fixture.getFixtureType()); fixtureExtensionLoader.addExtensions(fixture, concordionBuilder); if (extension != null) { @@ -74,7 +74,7 @@ public ProcessingResult process(Resource resource) { ResultSummary resultSummary = null; concordion.override(resource); - List examples = concordion.getExampleNames(fixture); + List examples = concordion.getExampleNames(fixture.getFixtureType()); if (!examples.isEmpty()) { for (String example : examples) { resultSummary = concordion.processExample(fixture, example); From 8d487ba650bea73d17f1eedc32ddfe4ca2a853ba Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 2 Jun 2018 08:32:26 +1200 Subject: [PATCH 17/42] Changed Concordion constructor parameter to use FixtureType rather than Fixture --- src/main/java/org/concordion/Concordion.java | 10 +++++----- .../concordion/internal/ConcordionBuilder.java | 8 ++++---- .../org/concordion/internal/FixtureRunner.java | 16 +++++++++------- src/test/java/test/concordion/TestRig.java | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index 9c769a848..c4bfd7585 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -26,27 +26,27 @@ public class Concordion { * @param specificationLocator locates the specification based on the specification type * @param specificationReader specification reader * @param evaluatorFactory evaluator factory - * @param fixture fixture instance + * @param fixtureType * @throws IOException on i/o error */ - public Concordion(List specificationTypes, SpecificationLocator specificationLocator, SpecificationReader specificationReader, EvaluatorFactory evaluatorFactory, Fixture fixture) throws IOException { + public Concordion(List specificationTypes, SpecificationLocator specificationLocator, SpecificationReader specificationReader, EvaluatorFactory evaluatorFactory, FixtureType fixtureType) throws IOException { this.specificationReader = specificationReader; this.evaluatorFactory = evaluatorFactory; SpecificationType specificationType = null; for (SpecificationType currentType : specificationTypes) { - Resource currentResource = specificationLocator.locateSpecification(fixture.getFixtureType(), currentType.getTypeSuffix()); + Resource currentResource = specificationLocator.locateSpecification(fixtureType, currentType.getTypeSuffix()); if (specificationReader.canFindSpecification(currentResource)) { if (specificationType != null) { - throw new RuntimeException(createMultipleSpecsMessage(fixture.getFixtureType(), specificationType, currentType)); + throw new RuntimeException(createMultipleSpecsMessage(fixtureType, specificationType, currentType)); } specificationType = currentType; resource = currentResource; } } if (specificationType == null) { - throw new RuntimeException(createUnableToFindSpecMessage(fixture.getFixtureType(), specificationTypes)); + throw new RuntimeException(createUnableToFindSpecMessage(fixtureType, specificationTypes)); } specificationReader.setSpecificationConverter(specificationType.getConverter()); } diff --git a/src/main/java/org/concordion/internal/ConcordionBuilder.java b/src/main/java/org/concordion/internal/ConcordionBuilder.java index 4c148d324..25ae2f812 100644 --- a/src/main/java/org/concordion/internal/ConcordionBuilder.java +++ b/src/main/java/org/concordion/internal/ConcordionBuilder.java @@ -59,7 +59,7 @@ public class ConcordionBuilder implements ConcordionExtender { private List throwableCaughtListeners = new ArrayList(); private List> failFastExceptions = Collections.>emptyList(); private boolean builtAlready; - private Fixture fixture; + private FixtureType fixtureType; private MarkdownConverter markdownConverter = new MarkdownConverter(); private XhtmlConverter xhtmlConverter = new XhtmlConverter(); @@ -319,7 +319,7 @@ public Concordion build() throws UnableToBuildConcordionException { announceBuildCompleted(); try { - return new Concordion(specificationTypes, specificationLocator, specificationReader, evaluatorFactory, fixture); + return new Concordion(specificationTypes, specificationLocator, specificationReader, evaluatorFactory, fixtureType); } catch (IOException e) { throw new UnableToBuildConcordionException(e); } @@ -415,8 +415,8 @@ public ConcordionBuilder withFailFast(Class[] failFastExcep return this; } - public ConcordionBuilder withFixture(Fixture fixture, FixtureType fixtureType) { - this.fixture = fixture; + public ConcordionBuilder withFixtureType(FixtureType fixtureType) { + this.fixtureType = fixtureType; withResources(fixtureType); diff --git a/src/main/java/org/concordion/internal/FixtureRunner.java b/src/main/java/org/concordion/internal/FixtureRunner.java index 30a497cd0..53e790305 100644 --- a/src/main/java/org/concordion/internal/FixtureRunner.java +++ b/src/main/java/org/concordion/internal/FixtureRunner.java @@ -14,7 +14,7 @@ public class FixtureRunner { private Concordion concordion; public FixtureRunner(Fixture fixture, SpecificationLocator specificationLocator) throws UnableToBuildConcordionException { - ConcordionBuilder concordionBuilder = new ConcordionBuilder().withFixture(fixture, fixture.getFixtureType()).withSpecificationLocator(specificationLocator); + ConcordionBuilder concordionBuilder = new ConcordionBuilder().withFixtureType(fixture.getFixtureType()).withSpecificationLocator(specificationLocator); new FixtureExtensionLoader().addExtensions(fixture, concordionBuilder); new FixtureOptionsLoader().addOptions(fixture.getFixtureType(), concordionBuilder); concordion = concordionBuilder.build(); @@ -22,7 +22,9 @@ public FixtureRunner(Fixture fixture, SpecificationLocator specificationLocator) public ResultSummary run(String example, Fixture fixture) throws IOException { - RunOutput runOutput = runResultsCache.startRun(fixture.getFixtureType(), example); + FixtureType fixtureType = fixture.getFixtureType(); + + RunOutput runOutput = runResultsCache.startRun(fixtureType, example); ResultSummary actualResultSummary = runOutput==null? null: runOutput.getActualResultSummary(); @@ -37,24 +39,24 @@ public ResultSummary run(String example, Fixture fixture) throws IOException { try { actualResultSummary = concordion.processExample(fixture, example); statusChecker = ImplementationStatusChecker.getImplementationStatusChecker( - fixture.getFixtureType(), actualResultSummary.getImplementationStatus()); + fixtureType, actualResultSummary.getImplementationStatus()); } finally { fixture.afterProcessExample(example); } } else { actualResultSummary = concordion.process(fixture); statusChecker = ImplementationStatusChecker.getImplementationStatusChecker( - fixture.getFixtureType(), null); + fixtureType, null); } runResultsCache.finishRun( - fixture.getFixtureType(), example, + fixtureType, example, actualResultSummary, statusChecker); } catch (RuntimeException e) { // the run failed miserably. Tell the cache that the run failed - runResultsCache.failRun(fixture.getFixtureType(), example); + runResultsCache.failRun(fixtureType, example); throw e; } @@ -63,7 +65,7 @@ public ResultSummary run(String example, Fixture fixture) throws IOException { } if (actualResultSummary.isForExample()) { - printResultSummary(fixture.getFixtureType(), example, actualResultSummary, additionalInformation); + printResultSummary(fixtureType, example, actualResultSummary, additionalInformation); } return actualResultSummary; diff --git a/src/test/java/test/concordion/TestRig.java b/src/test/java/test/concordion/TestRig.java index e4ba9a174..d36281683 100644 --- a/src/test/java/test/concordion/TestRig.java +++ b/src/test/java/test/concordion/TestRig.java @@ -57,7 +57,7 @@ public ProcessingResult process(Resource resource) { .withSource(source) .withEvaluatorFactory(evaluatorFactory) .withTarget(stubTarget) - .withFixture(fixture, fixture.getFixtureType()); + .withFixtureType(fixture.getFixtureType()); fixtureExtensionLoader.addExtensions(fixture, concordionBuilder); if (extension != null) { From b533fc7183833249eea200e10865ca8e3236e405 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 2 Jun 2018 12:05:54 +1200 Subject: [PATCH 18/42] Removed dependency of loading a Specification on the FixtureType --- src/main/java/org/concordion/Concordion.java | 31 +++++++------- .../org/concordion/api/Specification.java | 7 ++++ .../api/SpecificationByExample.java | 17 -------- .../org/concordion/internal/FixtureType.java | 2 +- ...cationToSpecificationByExampleAdaptor.java | 22 +++------- .../concordion/internal/XMLSpecification.java | 40 +++++++------------ 6 files changed, 45 insertions(+), 74 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index c4bfd7585..ec1666be0 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -62,30 +62,35 @@ public void override(Resource resource) throws IOException { public ResultSummary process(Fixture fixture) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(); - resultRecorder.setSpecificationDescription(fixture.getFixtureType().getSpecificationDescription()); - getSpecification(fixture.getFixtureType()).process(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), resultRecorder, fixture); + Evaluator evaluator = evaluatorFactory.createEvaluator(fixture.getFixtureObject()); + getSpecification().process(evaluator, resultRecorder, fixture); return resultRecorder; } - private SpecificationByExample getSpecification(FixtureType fixtureType) throws IOException { + private SpecificationByExample getSpecification() throws IOException { if (specification == null) { - specification = loadSpecificationFromResource(resource, fixtureType); - specificationDescription = specification.getSpecificationDescription(); + specification = loadSpecificationFromResource(resource); + specificationDescription = specification.getDescription(); } return specification; } public List getExampleNames(FixtureType fixtureType) throws IOException { - return getSpecification(fixtureType).getExampleNames(); + List exampleNames = getSpecification().getExampleNames(); + if (exampleNames.isEmpty()) { + exampleNames.add(fixtureType.getDescription()); + } + return exampleNames; } - public boolean hasExampleCommands(FixtureType fixtureType) throws IOException { - return getSpecification(fixtureType).hasExampleCommandNodes(); + public boolean hasExampleCommands() throws IOException { + return getSpecification().hasExampleCommandNodes(); } public ResultSummary processExample(Fixture fixture, String example) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(example); - getSpecification(fixture.getFixtureType()).processExample(evaluatorFactory.createEvaluator(fixture.getFixtureObject()), example, resultRecorder, fixture); + Evaluator evaluator = evaluatorFactory.createEvaluator(fixture.getFixtureObject()); + getSpecification().processExample(evaluator, example, resultRecorder, fixture); return resultRecorder; } @@ -93,12 +98,11 @@ public ResultSummary processExample(Fixture fixture, String example) throws IOEx * Loads the specification for the specified fixture. * * @param resource the resource to load - * @param fixtureType * @return a SpecificationByExample object to use * @throws IOException if the resource cannot be loaded */ - private SpecificationByExample loadSpecificationFromResource(Resource resource, FixtureType fixtureType) throws IOException { - Specification specification= specificationReader.readSpecification(resource); + private SpecificationByExample loadSpecificationFromResource(Resource resource) throws IOException { + Specification specification = specificationReader.readSpecification(resource); SpecificationByExample specificationByExample; if (specification instanceof SpecificationByExample) { @@ -106,7 +110,6 @@ private SpecificationByExample loadSpecificationFromResource(Resource resource, } else { specificationByExample = new SpecificationToSpecificationByExampleAdaptor(specification); } - specificationByExample.setFixture(fixtureType); return specificationByExample; } @@ -115,7 +118,7 @@ public void finish() { } public void checkValidStatus(FixtureType fixtureType) throws IOException { - if (hasExampleCommands(fixtureType) && fixtureType.getDeclaredImplementationStatus() != ImplementationStatus.EXPECTED_TO_PASS) { + if (hasExampleCommands() && fixtureType.getDeclaredImplementationStatus() != ImplementationStatus.EXPECTED_TO_PASS) { throw new IllegalStateException("Error: When the specification contains examples, " + "the Implementation Status (ExpectedToFail or Unimplemented) must be set on the example command in the specification, " + "and not as an annotation on the fixture."); diff --git a/src/main/java/org/concordion/api/Specification.java b/src/main/java/org/concordion/api/Specification.java index 3106a6fdd..4bd914615 100644 --- a/src/main/java/org/concordion/api/Specification.java +++ b/src/main/java/org/concordion/api/Specification.java @@ -3,4 +3,11 @@ public interface Specification { void process(Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture); + + /** + * Gets the description of the exported specification. + * + * @return specification description + */ + String getDescription(); } diff --git a/src/main/java/org/concordion/api/SpecificationByExample.java b/src/main/java/org/concordion/api/SpecificationByExample.java index fb0f9e3e4..d4fb361b6 100644 --- a/src/main/java/org/concordion/api/SpecificationByExample.java +++ b/src/main/java/org/concordion/api/SpecificationByExample.java @@ -1,7 +1,5 @@ package org.concordion.api; -import org.concordion.internal.FixtureType; - import java.util.List; /** @@ -11,14 +9,6 @@ */ public interface SpecificationByExample extends Specification { - /** - * Sets the fixture. Will be called before the other methods are called so that - * the class can process the fixture to determine examples, etc. - * - * @param fixtureType - */ - void setFixture(FixtureType fixtureType); - /** * Returns whether the specification contains example nodes. * @@ -26,13 +16,6 @@ public interface SpecificationByExample extends Specification { */ boolean hasExampleCommandNodes(); - /** - * Gets the description of the exported specification. - * - * @return specification description - */ - String getSpecificationDescription(); - /** * Gets all the examples in the specification. * diff --git a/src/main/java/org/concordion/internal/FixtureType.java b/src/main/java/org/concordion/internal/FixtureType.java index 1c39f65dc..0265eb720 100644 --- a/src/main/java/org/concordion/internal/FixtureType.java +++ b/src/main/java/org/concordion/internal/FixtureType.java @@ -114,7 +114,7 @@ public List getClassPathRoots() { return rootPaths; } - public String getSpecificationDescription() { + public String getDescription() { String name = removeSuffix(fixtureClass.getSimpleName()); return SimpleFormatter.format("[Concordion Specification for '%s']", name); // Based on suggestion by Danny Guerrier } diff --git a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java index f42c49cfe..eb9ca9cf9 100644 --- a/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java +++ b/src/main/java/org/concordion/internal/SpecificationToSpecificationByExampleAdaptor.java @@ -1,17 +1,16 @@ package org.concordion.internal; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.concordion.api.*; public class SpecificationToSpecificationByExampleAdaptor implements SpecificationByExample { - private String testDescription; private final Specification specification; - public SpecificationToSpecificationByExampleAdaptor(Specification s) { - specification = s; + public SpecificationToSpecificationByExampleAdaptor(Specification specification) { + this.specification = specification; } public void finish() { @@ -21,20 +20,11 @@ public void process(Evaluator evaluator, ResultRecorder resultRecorder, Fixture specification.process(evaluator, resultRecorder, fixture); } - public void setFixture(FixtureType fixtureType) { - testDescription = fixtureType.getSpecificationDescription(); - } - public void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder, Fixture fixture) { - if (testDescription.equals(example)) { - specification.process(evaluator, resultRecorder, fixture); - } } public List getExampleNames() { - ArrayList list = new ArrayList(); - list.add(testDescription); - return list; + return Collections.emptyList(); } @Override @@ -43,7 +33,7 @@ public boolean hasExampleCommandNodes() { } @Override - public String getSpecificationDescription() { - return testDescription; + public String getDescription() { + return specification.getDescription(); } } diff --git a/src/main/java/org/concordion/internal/XMLSpecification.java b/src/main/java/org/concordion/internal/XMLSpecification.java index e56f8b4ce..eab82c59f 100644 --- a/src/main/java/org/concordion/internal/XMLSpecification.java +++ b/src/main/java/org/concordion/internal/XMLSpecification.java @@ -12,7 +12,6 @@ public class XMLSpecification implements SpecificationByExample { public static final String OUTER_EXAMPLE_NAME = "[Outer]"; public static final String OUTER_EXAMPLE_SUFFIX = " " + OUTER_EXAMPLE_NAME; - private String testDescription; private final CommandCall rootCommandNode; private final SpecificationCommand specificationCommand; @@ -43,12 +42,12 @@ public void processNode(CommandCall node, Evaluator evaluator, ResultRecorder re String errorText = null; if (beforeResultRecorder.hasExceptions()) { errorText = SimpleFormatter.format("Exceptions occurred in the 'before' example in '%s'. See the output specification for details.\n", - testDescription + specificationDescription ); } else if (beforeResultRecorder.getTotalCount() > 0) { errorText = SimpleFormatter.format("Assertions were made in the 'before' example in '%s'.\n" + "Assertions are not supported in the 'before' example.\n", - testDescription + specificationDescription ); } if (errorText != null) { @@ -65,16 +64,8 @@ public void process(Evaluator evaluator, ResultRecorder resultRecorder, Fixture processNode(rootCommandNode, evaluator, resultRecorder, fixture); } - public void setFixture(FixtureType fixtureType) { - if (hasExampleCommandNodes()) { - testDescription = OUTER_EXAMPLE_NAME; - } else { - testDescription = fixtureType.getSpecificationDescription(); - } - } - public void processExample(Evaluator evaluator, String example, ResultRecorder resultRecorder, Fixture fixture) { - if (testDescription.equals(example)) { + if (!hasExampleCommandNodes() || OUTER_EXAMPLE_NAME.equals(example)) { processNode(rootCommandNode, evaluator, resultRecorder, fixture); return; } @@ -93,29 +84,26 @@ public boolean hasExampleCommandNodes() { } @Override - public String getSpecificationDescription() { + public String getDescription() { return specificationDescription; } public List getExampleNames() { - List commands = new ArrayList(); - - if (!rootCommandNode.getChildren().isEmpty()) { - // Add the main spec first to increase the chance that it will be run first by jUnit. - commands.add(testDescription); - } + List examples = new ArrayList(); - for (ExampleCommandCall exampleCall: examples) { - commands.add(exampleCall.getExampleName()); - } + if (hasExampleCommandNodes()) { + if (!rootCommandNode.getChildren().isEmpty()) { + // Add the main spec first to increase the chance that it will be run first by jUnit. + examples.add(OUTER_EXAMPLE_NAME); + } - // If there are no examples and no commands, let's add the outer test so you have 1 test in the fixture - if (commands.isEmpty()) { - commands.add(testDescription); + for (ExampleCommandCall exampleCall : this.examples) { + examples.add(exampleCall.getExampleName()); + } } - return commands; + return examples; } public void finish() { From c8d3854391aada1c4ca961870881e36514c623bf Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Mon, 4 Jun 2018 22:56:42 +1200 Subject: [PATCH 19/42] [Gradle Release Plugin] - new version commit: '2.1.4'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 205c6740f..7bea84892 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ #Sat, 25 Jul 2015 22:18:16 +1200 group=org.concordion -version=2.1.3 +version=2.1.4 From e0c0d1aa1917db62b8a42932cc11a23957cb1f12 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Wed, 6 Jun 2018 22:16:54 +1200 Subject: [PATCH 20/42] Update .travis.yml Try different syntax for JDK 10 from https://github.com/sormuras/sormuras.github.io/blob/ac6d17f663e3db1c1f50c6e202593861a9f50ab6/.travis.yml --- .travis.yml | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9a3dc6482..a9f1d87fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,12 @@ -sudo: false # update to latest Travis CI build infrastructure +sudo: false +dist: trusty +language: java -# workaround for buffer overflow issue, ref https://github.com/travis-ci/travis-ci/issues/5227 -addons: - hosts: - - myshorthost - hostname: myshorthost - artifacts: # see https://docs.travis-ci.com/user/uploading-artifacts/ - paths: - - $(git ls-files -o -x build/tmp -x build/classes -x build/resources -x .gradle | tr "\n" ":") +os: +- linux -language: java jdk: - - oraclejdk10 - - oraclejdk9 - - oraclejdk8 - - openjdk7 +- openjdk10 +- oraclejdk9 +- oraclejdk8 +- openjdk7 From fb5b53523f9a0ba6d1f863fa6fe0865d3135e541 Mon Sep 17 00:00:00 2001 From: Ian Bondoc Date: Sun, 17 Jun 2018 19:45:11 +1200 Subject: [PATCH 21/42] Removed dependency to JUnit @Ignore annotation --- src/main/java/org/concordion/api/IgnoredExample.java | 11 +++++++++++ .../java/org/concordion/api/ImplementationStatus.java | 4 +--- 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/concordion/api/IgnoredExample.java diff --git a/src/main/java/org/concordion/api/IgnoredExample.java b/src/main/java/org/concordion/api/IgnoredExample.java new file mode 100644 index 000000000..d15f7199e --- /dev/null +++ b/src/main/java/org/concordion/api/IgnoredExample.java @@ -0,0 +1,11 @@ +package org.concordion.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface IgnoredExample { +} diff --git a/src/main/java/org/concordion/api/ImplementationStatus.java b/src/main/java/org/concordion/api/ImplementationStatus.java index 5045ceba8..46a149e82 100644 --- a/src/main/java/org/concordion/api/ImplementationStatus.java +++ b/src/main/java/org/concordion/api/ImplementationStatus.java @@ -1,14 +1,12 @@ package org.concordion.api; -import org.junit.Ignore; - import java.lang.annotation.Annotation; public enum ImplementationStatus { UNIMPLEMENTED("Unimplemented", Unimplemented.class), EXPECTED_TO_FAIL("ExpectedToFail", ExpectedToFail.class), EXPECTED_TO_PASS("ExpectedToPass", ExpectedToPass.class), - IGNORED("Ignored", Ignore.class); + IGNORED("Ignored", IgnoredExample.class); private final String tag; private final Class annotation; From b8bf761874755e01615f9ffd23e0e6c33f518eeb Mon Sep 17 00:00:00 2001 From: Ian Bondoc Date: Tue, 19 Jun 2018 22:33:40 +1200 Subject: [PATCH 22/42] Introduced abstraction to the underlying example element to reduce coupling with DOM API --- .../org/concordion/api/ExampleDefinition.java | 34 +++++++++++++++++++ .../api/ImplementationStatusModifier.java | 6 ++-- .../internal/command/ExampleCommand.java | 22 +++++++++++- .../ImplementationStatusModifierTest.java | 10 ++---- 4 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 src/main/java/org/concordion/api/ExampleDefinition.java diff --git a/src/main/java/org/concordion/api/ExampleDefinition.java b/src/main/java/org/concordion/api/ExampleDefinition.java new file mode 100644 index 000000000..0ef4dc89b --- /dev/null +++ b/src/main/java/org/concordion/api/ExampleDefinition.java @@ -0,0 +1,34 @@ +package org.concordion.api; + +/** + * An interface to access example element's name and attributes for use mainly in {@link ImplementationStatusModifier}. + * + * @author Ian Bondoc + */ +public interface ExampleDefinition { + + /** + * Accessor to get the example's name + * + * @return the example's name + */ + String getName(); + + /** + * Accessor to the example's attribute given the name + * + * @param name the name of the attribute + * @return the attribute value + */ + String getAttributeValue(String name); + + /** + * Accessor to the example's attribute given the name and namespace + * + * @param localName the name of the attribute + * @param namespaceURI the namespace of the attribute + * @return the attribute value + */ + String getAttributeValue(String localName, String namespaceURI); + +} diff --git a/src/main/java/org/concordion/api/ImplementationStatusModifier.java b/src/main/java/org/concordion/api/ImplementationStatusModifier.java index 1d13b9aac..c68682b66 100644 --- a/src/main/java/org/concordion/api/ImplementationStatusModifier.java +++ b/src/main/java/org/concordion/api/ImplementationStatusModifier.java @@ -12,9 +12,9 @@ public interface ImplementationStatusModifier { /** * Determine an example element's {@code ImplementationStatus} * - * @param exampleElement the element to evaluate - * @return the status based on the exampleElement + * @param exampleDefinition the definition of the example to evaluate + * @return the status based on the exampleDefinition */ - ImplementationStatus getStatusForExample(Element exampleElement); + ImplementationStatus getStatusForExample(ExampleDefinition exampleDefinition); } diff --git a/src/main/java/org/concordion/internal/command/ExampleCommand.java b/src/main/java/org/concordion/internal/command/ExampleCommand.java index 9feefeeb4..5bc261fd7 100644 --- a/src/main/java/org/concordion/internal/command/ExampleCommand.java +++ b/src/main/java/org/concordion/internal/command/ExampleCommand.java @@ -101,7 +101,7 @@ private ImplementationStatus getImplementationStatus(CommandCall node) { } // if there's a status modifier and there's a status for the example, it overrides status param if (implementationStatusModifier != null) { - ImplementationStatus runtimeImplementation = implementationStatusModifier.getStatusForExample(node.getElement()); + ImplementationStatus runtimeImplementation = implementationStatusModifier.getStatusForExample(exampleDefinition(node.getElement())); if (runtimeImplementation != null) { implementationStatus = runtimeImplementation; } @@ -139,4 +139,24 @@ private void announceAfterExample(String exampleName, Element element, ResultRec public void setImplementationStatusModifier(ImplementationStatusModifier implementationStatusModifier) { this.implementationStatusModifier = implementationStatusModifier; } + + private static ExampleDefinition exampleDefinition(Element element) { + return new ExampleDefinition() { + @Override + public String getName() { + return element.getAttributeValue("example", ConcordionBuilder.NAMESPACE_CONCORDION_2007); + } + + @Override + public String getAttributeValue(String name) { + return element.getAttributeValue(name); + } + + @Override + public String getAttributeValue(String localName, String namespaceURI) { + return element.getAttributeValue(localName, namespaceURI); + } + }; + } + } diff --git a/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java b/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java index 575409264..649cfb469 100644 --- a/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java +++ b/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java @@ -1,9 +1,6 @@ package spec.concordion.common.extension; -import org.concordion.api.Element; -import org.concordion.api.ImplementationStatus; -import org.concordion.api.ImplementationStatusModifier; -import org.concordion.api.FullOGNL; +import org.concordion.api.*; import org.concordion.api.extension.ConcordionExtender; import org.concordion.api.extension.ConcordionExtension; import org.concordion.integration.junit4.ConcordionRunner; @@ -24,9 +21,8 @@ public void addExtension() { public void addTo(ConcordionExtender concordionExtender) { concordionExtender.withImplementationStatusModifier(new ImplementationStatusModifier() { @Override - public ImplementationStatus getStatusForExample(Element exampleElement) { - String exampleName = exampleElement.getAttributeValue("example", ConcordionBuilder.NAMESPACE_CONCORDION_2007); - if (exampleName.endsWith("Ignored")) { + public ImplementationStatus getStatusForExample(ExampleDefinition exampleDefinition) { + if (exampleDefinition.getName().endsWith("Ignored")) { return ImplementationStatus.IGNORED; } else { return null; From 7354d57509a12df884d2ec5a887439030f616e27 Mon Sep 17 00:00:00 2001 From: Ian Bondoc Date: Tue, 19 Jun 2018 22:42:37 +1200 Subject: [PATCH 23/42] Fixed (jdk6 related) bug --- .../java/org/concordion/internal/command/ExampleCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/concordion/internal/command/ExampleCommand.java b/src/main/java/org/concordion/internal/command/ExampleCommand.java index 5bc261fd7..6e211d49d 100644 --- a/src/main/java/org/concordion/internal/command/ExampleCommand.java +++ b/src/main/java/org/concordion/internal/command/ExampleCommand.java @@ -140,7 +140,7 @@ public void setImplementationStatusModifier(ImplementationStatusModifier impleme this.implementationStatusModifier = implementationStatusModifier; } - private static ExampleDefinition exampleDefinition(Element element) { + private static ExampleDefinition exampleDefinition(final Element element) { return new ExampleDefinition() { @Override public String getName() { From 5a8debc022527838d93f463cb3facb0ffe3eb765 Mon Sep 17 00:00:00 2001 From: Ian Bondoc Date: Tue, 19 Jun 2018 23:38:59 +1200 Subject: [PATCH 24/42] Prevent calls to @BeforeExample and @AfterExample annotated methods for ignored examples --- .../internal/command/ExampleCommand.java | 7 ++--- .../ImplementationStatusModifierTest.java | 26 +++++++++++++++++++ .../ImplementationStatusModifier.html | 13 +++++++++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/concordion/internal/command/ExampleCommand.java b/src/main/java/org/concordion/internal/command/ExampleCommand.java index 6e211d49d..49a91f33b 100644 --- a/src/main/java/org/concordion/internal/command/ExampleCommand.java +++ b/src/main/java/org/concordion/internal/command/ExampleCommand.java @@ -35,12 +35,13 @@ public void execute(CommandCall node, Evaluator evaluator, ResultRecorder result resultRecorder.setSpecificationDescription( specificationDescriber.getDescription(node.getResource(), exampleName)); - if (!isBeforeExample) { + ImplementationStatus status = getImplementationStatus(node); + + if (!isBeforeExample && status != ImplementationStatus.IGNORED) { announceBeforeExample(exampleName, node.getElement(), resultRecorder); } try { - ImplementationStatus status = getImplementationStatus(node); resultRecorder.setImplementationStatus(status); if (status == ImplementationStatus.IGNORED) { resultRecorder.record(Result.IGNORED); @@ -52,7 +53,7 @@ public void execute(CommandCall node, Evaluator evaluator, ResultRecorder result } setupCommandForExample(node, resultRecorder, exampleName); - if (!isBeforeExample) { + if (!isBeforeExample && status != ImplementationStatus.IGNORED) { announceAfterExample(exampleName, node.getElement(), resultRecorder); } } diff --git a/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java b/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java index 649cfb469..c30a83925 100644 --- a/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java +++ b/src/test/java/spec/concordion/common/extension/ImplementationStatusModifierTest.java @@ -8,6 +8,9 @@ import org.junit.runner.RunWith; import test.concordion.ProcessingResult; +import java.util.ArrayList; +import java.util.List; + /** * Created by bondocaadmin on 10/05/2018. */ @@ -37,4 +40,27 @@ public ImplementationStatus getStatusForExample(ExampleDefinition exampleDefinit public ProcessingResult getProcessingResult() { return super.getProcessingResult(); } + + private final List beforeExampleCapturedNames = new ArrayList(); + private final List afterExampleCapturedNames = new ArrayList(); + + @BeforeExample + public void saveNameBeforeExample(@ExampleName String name) { + beforeExampleCapturedNames.add(name); + } + + @AfterExample + public void saveNameAfterExample(@ExampleName String name) { + afterExampleCapturedNames.add(name); + } + + public List getBeforeExampleCapturedNames() { + return beforeExampleCapturedNames; + } + + public List getAfterExampleCapturedNames() { + return afterExampleCapturedNames; + } + + } diff --git a/src/test/resources/spec/concordion/common/extension/ImplementationStatusModifier.html b/src/test/resources/spec/concordion/common/extension/ImplementationStatusModifier.html index 918775223..4ace814f8 100644 --- a/src/test/resources/spec/concordion/common/extension/ImplementationStatusModifier.html +++ b/src/test/resources/spec/concordion/common/extension/ImplementationStatusModifier.html @@ -15,8 +15,11 @@

    ImplementationStatusModifier

    Example

    An ImplementationStatusModifier is installed that sets the - status of an example to IGNORED if the example name ends in Ignored. + status of an example to IGNORED if the example name ends in Ignored, a @BeforeExample annotated + fixture method which saves the example names in a list, and a @AfterExample annotated fixture method which + saves the example names in a different list.

    +

    Running a specification containing:

     <div concordion:example="aPassingExample">
    @@ -39,6 +42,14 @@ 

    Example

  • Ignored: 1
  • +

    Example names which executed @BeforeExample method: + [[Outer], aPassingExample, aFailingExample, expectedToFailExample] +

    +

    Example names which executed @AfterExample method: + [aPassingExample, aFailingExample, expectedToFailExample] (Note that although the @AfterExample + annotated method was also called for [Outer] example this concordion assertion was evaluated prior to that call + that's why it is not included in the list) +

    From 747c40a6cb3b83204259f8a5dff0915ce21681b8 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 23 Jun 2018 19:38:34 +1200 Subject: [PATCH 25/42] Modified EvaluatorFactory to take Fixture rather than Object as parameter --- src/main/java/org/concordion/Concordion.java | 4 ++-- src/main/java/org/concordion/api/EvaluatorFactory.java | 2 +- src/main/java/org/concordion/internal/OgnlEvaluator.java | 5 +++-- .../java/org/concordion/internal/OgnlEvaluatorFactory.java | 3 ++- src/main/java/org/concordion/internal/SimpleEvaluator.java | 4 +++- .../java/org/concordion/internal/SimpleEvaluatorFactory.java | 3 ++- .../common/command/expressions/ComplexExpressionsTest.java | 5 +++-- src/test/java/test/concordion/StubEvaluator.java | 3 ++- 8 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index ec1666be0..9650aad82 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -62,7 +62,7 @@ public void override(Resource resource) throws IOException { public ResultSummary process(Fixture fixture) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(); - Evaluator evaluator = evaluatorFactory.createEvaluator(fixture.getFixtureObject()); + Evaluator evaluator = evaluatorFactory.createEvaluator(fixture); getSpecification().process(evaluator, resultRecorder, fixture); return resultRecorder; } @@ -89,7 +89,7 @@ public boolean hasExampleCommands() throws IOException { public ResultSummary processExample(Fixture fixture, String example) throws IOException { SummarizingResultRecorder resultRecorder = new SummarizingResultRecorder(example); - Evaluator evaluator = evaluatorFactory.createEvaluator(fixture.getFixtureObject()); + Evaluator evaluator = evaluatorFactory.createEvaluator(fixture); getSpecification().processExample(evaluator, example, resultRecorder, fixture); return resultRecorder; } diff --git a/src/main/java/org/concordion/api/EvaluatorFactory.java b/src/main/java/org/concordion/api/EvaluatorFactory.java index e2d8da8df..c1165038a 100644 --- a/src/main/java/org/concordion/api/EvaluatorFactory.java +++ b/src/main/java/org/concordion/api/EvaluatorFactory.java @@ -2,5 +2,5 @@ public interface EvaluatorFactory { - Evaluator createEvaluator(Object fixture); + Evaluator createEvaluator(Fixture fixture); } diff --git a/src/main/java/org/concordion/internal/OgnlEvaluator.java b/src/main/java/org/concordion/internal/OgnlEvaluator.java index 44ae89266..741c1cb85 100644 --- a/src/main/java/org/concordion/internal/OgnlEvaluator.java +++ b/src/main/java/org/concordion/internal/OgnlEvaluator.java @@ -6,6 +6,7 @@ import ognl.OgnlException; import org.concordion.api.Evaluator; +import org.concordion.api.Fixture; import org.concordion.internal.util.Check; public class OgnlEvaluator implements Evaluator { @@ -13,8 +14,8 @@ public class OgnlEvaluator implements Evaluator { private Object rootObject; private final OgnlContext ognlContext = new OgnlContext(); - public OgnlEvaluator(Object rootObject) { - this.rootObject = rootObject; + public OgnlEvaluator(Fixture fixture) { + this.rootObject = fixture.getFixtureObject(); } public Object evaluate(String expression) { diff --git a/src/main/java/org/concordion/internal/OgnlEvaluatorFactory.java b/src/main/java/org/concordion/internal/OgnlEvaluatorFactory.java index d5c46bba0..a82780e67 100644 --- a/src/main/java/org/concordion/internal/OgnlEvaluatorFactory.java +++ b/src/main/java/org/concordion/internal/OgnlEvaluatorFactory.java @@ -2,10 +2,11 @@ import org.concordion.api.Evaluator; import org.concordion.api.EvaluatorFactory; +import org.concordion.api.Fixture; public class OgnlEvaluatorFactory implements EvaluatorFactory { - public Evaluator createEvaluator(Object fixture) { + public Evaluator createEvaluator(Fixture fixture) { return new OgnlEvaluator(fixture); } } diff --git a/src/main/java/org/concordion/internal/SimpleEvaluator.java b/src/main/java/org/concordion/internal/SimpleEvaluator.java index d7b52c3b0..9913339b3 100644 --- a/src/main/java/org/concordion/internal/SimpleEvaluator.java +++ b/src/main/java/org/concordion/internal/SimpleEvaluator.java @@ -1,8 +1,10 @@ package org.concordion.internal; +import org.concordion.api.Fixture; + public class SimpleEvaluator extends OgnlEvaluator { - public SimpleEvaluator(Object fixture) { + public SimpleEvaluator(Fixture fixture) { super(fixture); } diff --git a/src/main/java/org/concordion/internal/SimpleEvaluatorFactory.java b/src/main/java/org/concordion/internal/SimpleEvaluatorFactory.java index 038ab3219..ff518867c 100644 --- a/src/main/java/org/concordion/internal/SimpleEvaluatorFactory.java +++ b/src/main/java/org/concordion/internal/SimpleEvaluatorFactory.java @@ -2,10 +2,11 @@ import org.concordion.api.Evaluator; import org.concordion.api.EvaluatorFactory; +import org.concordion.api.Fixture; public class SimpleEvaluatorFactory implements EvaluatorFactory { - public Evaluator createEvaluator(Object fixture) { + public Evaluator createEvaluator(Fixture fixture) { return new SimpleEvaluator(fixture); } } diff --git a/src/test/java/spec/concordion/common/command/expressions/ComplexExpressionsTest.java b/src/test/java/spec/concordion/common/command/expressions/ComplexExpressionsTest.java index 27eeb39da..50c38215a 100644 --- a/src/test/java/spec/concordion/common/command/expressions/ComplexExpressionsTest.java +++ b/src/test/java/spec/concordion/common/command/expressions/ComplexExpressionsTest.java @@ -4,6 +4,7 @@ import org.concordion.api.FullOGNL; import org.concordion.api.MultiValueResult; import org.concordion.integration.junit4.ConcordionRunner; +import org.concordion.internal.FixtureInstance; import org.concordion.internal.OgnlEvaluator; import org.concordion.internal.SimpleEvaluator; import org.junit.runner.RunWith; @@ -15,8 +16,8 @@ @RunWith(ConcordionRunner.class) public class ComplexExpressionsTest { - private final Evaluator simple = new SimpleEvaluator(new SimpleTestFixture()); - private final Evaluator ognl = new OgnlEvaluator(new OgnlTestFixture()); + private final Evaluator simple = new SimpleEvaluator(new FixtureInstance(new SimpleTestFixture())); + private final Evaluator ognl = new OgnlEvaluator(new FixtureInstance(new OgnlTestFixture())); public ComplexExpressionsTest() { initTestVariables(simple); diff --git a/src/test/java/test/concordion/StubEvaluator.java b/src/test/java/test/concordion/StubEvaluator.java index c71fa1da1..cfb79316e 100644 --- a/src/test/java/test/concordion/StubEvaluator.java +++ b/src/test/java/test/concordion/StubEvaluator.java @@ -2,12 +2,13 @@ import org.concordion.api.Evaluator; import org.concordion.api.EvaluatorFactory; +import org.concordion.api.Fixture; public class StubEvaluator implements Evaluator, EvaluatorFactory { private Object evaluationResult = null; - public Evaluator createEvaluator(Object fixture) { + public Evaluator createEvaluator(Fixture fixture) { return this; } From 9c7bcc357f7dbbcc1c6d0a5ca49c266f4063b508 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 23 Jun 2018 22:36:09 +1200 Subject: [PATCH 26/42] Use FixtureDeclarations interface rather than FixtureType where possible --- src/main/java/org/concordion/Concordion.java | 4 ++-- .../org/concordion/api/ResultSummary.java | 8 +++----- .../internal/AbstractResultSummary.java | 20 +++++++++---------- .../internal/FixtureOptionsLoader.java | 5 +++-- .../concordion/internal/FixtureRunner.java | 7 ++++--- .../internal/ImplementationStatusChecker.java | 4 ++-- .../internal/SingleResultSummary.java | 6 +++--- .../internal/SummarizingResultRecorder.java | 4 ++-- .../internal/cache/CacheResultSummary.java | 5 ++--- .../internal/cache/RunResultsCache.java | 3 ++- 10 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index 9650aad82..a90e51fc6 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -117,8 +117,8 @@ public void finish() { specification.finish(); } - public void checkValidStatus(FixtureType fixtureType) throws IOException { - if (hasExampleCommands() && fixtureType.getDeclaredImplementationStatus() != ImplementationStatus.EXPECTED_TO_PASS) { + public void checkValidStatus(FixtureDeclarations fixtureDeclarations) throws IOException { + if (hasExampleCommands() && fixtureDeclarations.getDeclaredImplementationStatus() != ImplementationStatus.EXPECTED_TO_PASS) { throw new IllegalStateException("Error: When the specification contains examples, " + "the Implementation Status (ExpectedToFail or Unimplemented) must be set on the example command in the specification, " + "and not as an annotation on the fixture."); diff --git a/src/main/java/org/concordion/api/ResultSummary.java b/src/main/java/org/concordion/api/ResultSummary.java index 4fe90d04c..df726ad9f 100644 --- a/src/main/java/org/concordion/api/ResultSummary.java +++ b/src/main/java/org/concordion/api/ResultSummary.java @@ -1,12 +1,10 @@ package org.concordion.api; -import org.concordion.internal.FixtureType; - import java.io.PrintStream; public interface ResultSummary { - void assertIsSatisfied(FixtureType fixtureType); + void assertIsSatisfied(FixtureDeclarations fixtureDeclarations); boolean hasExceptions(); @@ -18,9 +16,9 @@ public interface ResultSummary { long getIgnoredCount(); - void print(PrintStream out, FixtureType fixtureType); + void print(PrintStream out, FixtureDeclarations fixtureDeclarations); - String printCountsToString(FixtureType fixtureType); + String printCountsToString(FixtureDeclarations fixtureDeclarations); String getSpecificationDescription(); diff --git a/src/main/java/org/concordion/internal/AbstractResultSummary.java b/src/main/java/org/concordion/internal/AbstractResultSummary.java index a542e426d..01962a13d 100644 --- a/src/main/java/org/concordion/internal/AbstractResultSummary.java +++ b/src/main/java/org/concordion/internal/AbstractResultSummary.java @@ -2,7 +2,7 @@ import java.io.PrintStream; -import org.concordion.api.Fixture; +import org.concordion.api.FixtureDeclarations; import org.concordion.api.ImplementationStatus; import org.concordion.api.ResultSummary; @@ -17,16 +17,16 @@ public boolean isForExample() { } @Override - public void print(PrintStream out, FixtureType fixtureType) { - out.print(printToString(fixtureType)); + public void print(PrintStream out, FixtureDeclarations fixtureDeclarations) { + out.print(printToString(fixtureDeclarations)); } - String printToString(FixtureType fixtureType) { + String printToString(FixtureDeclarations fixtureDeclarations) { StringBuilder builder = new StringBuilder(); builder.append("\n"); builder.append(specificationDescription); builder.append("\n"); - String counts = printCountsToString(fixtureType); + String counts = printCountsToString(fixtureDeclarations); if (counts != null) { builder.append(counts).append("\n"); } @@ -35,7 +35,7 @@ String printToString(FixtureType fixtureType) { } @Override - public String printCountsToString(FixtureType fixtureType) { + public String printCountsToString(FixtureDeclarations fixtureDeclarations) { StringBuilder builder = new StringBuilder(); builder.append("Successes: "); @@ -51,7 +51,7 @@ public String printCountsToString(FixtureType fixtureType) { builder.append(getExceptionCount()); } - builder.append(getImplementationStatusChecker(fixtureType).printNoteToString()); + builder.append(getImplementationStatusChecker(fixtureDeclarations).printNoteToString()); return builder.toString(); } @@ -74,12 +74,12 @@ public void setImplementationStatus(ImplementationStatus implementationStatus) { this.implementationStatus = implementationStatus; } - public ImplementationStatusChecker getImplementationStatusChecker(FixtureType fixtureType) { + public ImplementationStatusChecker getImplementationStatusChecker(FixtureDeclarations fixtureDeclarations) { ImplementationStatus implementationStatus; - if (isForExample() || fixtureType == null) { + if (isForExample() || fixtureDeclarations == null) { implementationStatus = getImplementationStatus(); } else { - implementationStatus = fixtureType.getDeclaredImplementationStatus(); + implementationStatus = fixtureDeclarations.getDeclaredImplementationStatus(); } return ImplementationStatusChecker.implementationStatusCheckerFor(implementationStatus); } diff --git a/src/main/java/org/concordion/internal/FixtureOptionsLoader.java b/src/main/java/org/concordion/internal/FixtureOptionsLoader.java index 2211e123d..92b13ebda 100644 --- a/src/main/java/org/concordion/internal/FixtureOptionsLoader.java +++ b/src/main/java/org/concordion/internal/FixtureOptionsLoader.java @@ -2,11 +2,12 @@ import java.util.List; +import org.concordion.api.FixtureDeclarations; import org.concordion.api.option.ConcordionOptions; public class FixtureOptionsLoader { - public void addOptions(FixtureType fixtureType, ConcordionBuilder concordionBuilder) { - List classAnnotations = fixtureType.getDeclaredConcordionOptionsParentFirst(); + public void addOptions(FixtureDeclarations fixtureDeclarations, ConcordionBuilder concordionBuilder) { + List classAnnotations = fixtureDeclarations.getDeclaredConcordionOptionsParentFirst(); for (ConcordionOptions options : classAnnotations) { concordionBuilder.configureWith(options); } diff --git a/src/main/java/org/concordion/internal/FixtureRunner.java b/src/main/java/org/concordion/internal/FixtureRunner.java index 53e790305..4aca76954 100644 --- a/src/main/java/org/concordion/internal/FixtureRunner.java +++ b/src/main/java/org/concordion/internal/FixtureRunner.java @@ -2,6 +2,7 @@ import org.concordion.Concordion; import org.concordion.api.Fixture; +import org.concordion.api.FixtureDeclarations; import org.concordion.api.ResultSummary; import org.concordion.api.SpecificationLocator; import org.concordion.internal.cache.RunResultsCache; @@ -71,13 +72,13 @@ public ResultSummary run(String example, Fixture fixture) throws IOException { return actualResultSummary; } - private void printResultSummary(FixtureType fixtureType, String example, ResultSummary resultSummary, String additionalInformation) { + private void printResultSummary(FixtureDeclarations fixtureDeclarations, String example, ResultSummary resultSummary, String additionalInformation) { synchronized (System.out) { if (additionalInformation != null) { System.out.print(additionalInformation); } - resultSummary.print(System.out, fixtureType); - resultSummary.assertIsSatisfied(fixtureType); + resultSummary.print(System.out, fixtureDeclarations); + resultSummary.assertIsSatisfied(fixtureDeclarations); } } diff --git a/src/main/java/org/concordion/internal/ImplementationStatusChecker.java b/src/main/java/org/concordion/internal/ImplementationStatusChecker.java index 5be264548..019e4c894 100644 --- a/src/main/java/org/concordion/internal/ImplementationStatusChecker.java +++ b/src/main/java/org/concordion/internal/ImplementationStatusChecker.java @@ -149,13 +149,13 @@ public ImplementationStatus getImplementationStatus() { return implementationStatus; } - public static ImplementationStatusChecker getImplementationStatusChecker(FixtureType fixtureType, ImplementationStatus implementationStatus) { + public static ImplementationStatusChecker getImplementationStatusChecker(FixtureDeclarations fixtureDeclarations, ImplementationStatus implementationStatus) { // examples have precedence if (implementationStatus != null) { return implementationStatusCheckerFor(implementationStatus); } - return implementationStatusCheckerFor(fixtureType.getDeclaredImplementationStatus()); + return implementationStatusCheckerFor(fixtureDeclarations.getDeclaredImplementationStatus()); } public static ImplementationStatusChecker implementationStatusCheckerFor(ImplementationStatus implementationStatus) { diff --git a/src/main/java/org/concordion/internal/SingleResultSummary.java b/src/main/java/org/concordion/internal/SingleResultSummary.java index 8436f3536..33426203b 100644 --- a/src/main/java/org/concordion/internal/SingleResultSummary.java +++ b/src/main/java/org/concordion/internal/SingleResultSummary.java @@ -1,6 +1,6 @@ package org.concordion.internal; -import org.concordion.api.Fixture; +import org.concordion.api.FixtureDeclarations; import org.concordion.api.Result; import org.concordion.api.ResultSummary; @@ -34,8 +34,8 @@ public int hashCode() { } @Override - public void assertIsSatisfied(FixtureType fixtureType) { - getImplementationStatusChecker(fixtureType).assertIsSatisfied(this, null); + public void assertIsSatisfied(FixtureDeclarations fixtureDeclarations) { + getImplementationStatusChecker(fixtureDeclarations).assertIsSatisfied(this, null); } @Override diff --git a/src/main/java/org/concordion/internal/SummarizingResultRecorder.java b/src/main/java/org/concordion/internal/SummarizingResultRecorder.java index d7a0b86d6..eff288f55 100644 --- a/src/main/java/org/concordion/internal/SummarizingResultRecorder.java +++ b/src/main/java/org/concordion/internal/SummarizingResultRecorder.java @@ -41,8 +41,8 @@ public void record(ResultSummary result) { } @Override - public void assertIsSatisfied(FixtureType fixtureType) { - getImplementationStatusChecker(fixtureType).assertIsSatisfied(this, failFastException); + public void assertIsSatisfied(FixtureDeclarations fixtureDeclarations) { + getImplementationStatusChecker(fixtureDeclarations).assertIsSatisfied(this, failFastException); } @Override diff --git a/src/main/java/org/concordion/internal/cache/CacheResultSummary.java b/src/main/java/org/concordion/internal/cache/CacheResultSummary.java index 0958dda0d..0191027f0 100644 --- a/src/main/java/org/concordion/internal/cache/CacheResultSummary.java +++ b/src/main/java/org/concordion/internal/cache/CacheResultSummary.java @@ -1,8 +1,7 @@ package org.concordion.internal.cache; -import org.concordion.api.Fixture; +import org.concordion.api.FixtureDeclarations; import org.concordion.api.Result; -import org.concordion.internal.FixtureType; import org.concordion.internal.SingleResultSummary; class CacheResultSummary extends SingleResultSummary { @@ -12,7 +11,7 @@ public CacheResultSummary(Result result, String specificationDescription) { } @Override - public String printCountsToString(FixtureType fixtureType) { + public String printCountsToString(FixtureDeclarations fixtureDeclarations) { // no counts for cached result summary return null; } diff --git a/src/main/java/org/concordion/internal/cache/RunResultsCache.java b/src/main/java/org/concordion/internal/cache/RunResultsCache.java index 8b4a1442d..3356899db 100644 --- a/src/main/java/org/concordion/internal/cache/RunResultsCache.java +++ b/src/main/java/org/concordion/internal/cache/RunResultsCache.java @@ -3,6 +3,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.concordion.api.FixtureDeclarations; import org.concordion.api.ResultSummary; import org.concordion.internal.FixtureType; import org.concordion.internal.ImplementationStatusChecker; @@ -41,7 +42,7 @@ public synchronized RunOutput getFromCache(FixtureType fixtureType, String examp /** * Initialises an entry in the cache for a specification with the given description. * Individual examples may then be run, and their results will be added to the fixture - * total when {@link #finishRun(FixtureType, String, ResultSummary, ImplementationStatusChecker)} + * total when {@link #finishRun(FixtureDeclarations, String, ResultSummary, ImplementationStatusChecker)} * is called. * @param fixtureType the fixture class that is being started * @param specificationDescription a description of the target specification From 0ec88380ff234528d66faf775eca98a9edd313f3 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 23 Jun 2018 22:36:33 +1200 Subject: [PATCH 27/42] Use Fixture interface rather than FixtureInstance where possible --- .../concordion/common/results/runTotals/RunTotalsFixture.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/spec/concordion/common/results/runTotals/RunTotalsFixture.java b/src/test/java/spec/concordion/common/results/runTotals/RunTotalsFixture.java index ae550e1c6..b5bf0c2df 100644 --- a/src/test/java/spec/concordion/common/results/runTotals/RunTotalsFixture.java +++ b/src/test/java/spec/concordion/common/results/runTotals/RunTotalsFixture.java @@ -19,7 +19,7 @@ public RunTotalsFixture() { withFixture(new FixtureInstance(this)); } - private RunTotalsFixture withFixture(FixtureInstance fixture) { + private RunTotalsFixture withFixture(Fixture fixture) { this.fixture = fixture; return this; } From be0919fa0632599b448e4948c22c2e9b445d00c5 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 23 Jun 2018 22:36:49 +1200 Subject: [PATCH 28/42] Remove unused class --- .../ClassNameAndTypeBasedSpecificationLocator.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/java/org/concordion/internal/ClassNameAndTypeBasedSpecificationLocator.java diff --git a/src/main/java/org/concordion/internal/ClassNameAndTypeBasedSpecificationLocator.java b/src/main/java/org/concordion/internal/ClassNameAndTypeBasedSpecificationLocator.java deleted file mode 100644 index b0510b3c2..000000000 --- a/src/main/java/org/concordion/internal/ClassNameAndTypeBasedSpecificationLocator.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.concordion.internal; - -import org.concordion.api.Resource; - -public abstract class ClassNameAndTypeBasedSpecificationLocator extends ClassNameBasedSpecificationLocator { - public abstract Resource locateSpecification(FixtureType fixtureType, String typeSuffix); -} From 8bb64e06139adaa416b09fb299d4dfd5b0740f45 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 23 Jun 2018 22:43:34 +1200 Subject: [PATCH 29/42] Change field to be final --- .../org/concordion/integration/junit4/ConcordionRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java b/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java index 1261fffd5..887b2e6e2 100644 --- a/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java +++ b/src/main/java/org/concordion/integration/junit4/ConcordionRunner.java @@ -33,12 +33,12 @@ public void invoke(ConcordionFrameworkMethod concordionFrameworkMethod, Object t }; private final Class fixtureClass; + private final Fixture setupFixture; private final FixtureRunner fixtureRunner; private final Concordion concordion; private final List concordionFrameworkMethods; private FailFastException failFastException = null; - private Fixture setupFixture; private static AtomicInteger suiteDepth = new AtomicInteger(); private boolean firstTest = true; From b61ef17d40188a3d5e69ec6b187bb96fb284a6dd Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 24 Jun 2018 13:54:02 +1200 Subject: [PATCH 30/42] Reformmatted ExampleCommand --- .../internal/command/ExampleCommand.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/concordion/internal/command/ExampleCommand.java b/src/main/java/org/concordion/internal/command/ExampleCommand.java index 879cdf0a5..990fe5b93 100644 --- a/src/main/java/org/concordion/internal/command/ExampleCommand.java +++ b/src/main/java/org/concordion/internal/command/ExampleCommand.java @@ -1,17 +1,17 @@ package org.concordion.internal.command; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.concordion.api.*; import org.concordion.api.listener.ExampleEvent; import org.concordion.api.listener.ExampleListener; import org.concordion.internal.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class ExampleCommand extends AbstractCommand { - private List listeners = new ArrayList(); + private List listeners = new ArrayList(); private SpecificationDescriber specificationDescriber; private ImplementationStatusModifier implementationStatusModifier; @@ -126,16 +126,16 @@ public void setSpecificationDescriber(SpecificationDescriber specificationDescri } private void announceBeforeExample(String exampleName, Element element, ResultRecorder resultRecorder, Fixture fixture) { - for (ExampleListener listener : listeners) { - listener.beforeExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder)resultRecorder, fixture)); - } - } + for (ExampleListener listener : listeners) { + listener.beforeExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder) resultRecorder, fixture)); + } + } private void announceAfterExample(String exampleName, Element element, ResultRecorder resultRecorder, Fixture fixture) { for (int i = listeners.size() - 1; i >= 0; i--) { - listeners.get(i).afterExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder)resultRecorder, fixture)); + listeners.get(i).afterExample(new ExampleEvent(exampleName, element, (SummarizingResultRecorder) resultRecorder, fixture)); } - } + } public void setImplementationStatusModifier(ImplementationStatusModifier implementationStatusModifier) { this.implementationStatusModifier = implementationStatusModifier; From 56b26df951f47747a4f38c01efb33ae1b74ee433 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 24 Jun 2018 22:17:39 +1200 Subject: [PATCH 31/42] Fixed Javadocs --- src/main/java/org/concordion/Concordion.java | 2 +- src/main/java/org/concordion/api/Command.java | 3 +++ .../org/concordion/internal/cache/RunResultsCache.java | 10 +++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index a90e51fc6..9f5e25762 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -26,7 +26,7 @@ public class Concordion { * @param specificationLocator locates the specification based on the specification type * @param specificationReader specification reader * @param evaluatorFactory evaluator factory - * @param fixtureType + * @param fixtureType a wrapper around the fixture class * @throws IOException on i/o error */ public Concordion(List specificationTypes, SpecificationLocator specificationLocator, SpecificationReader specificationReader, EvaluatorFactory evaluatorFactory, FixtureType fixtureType) throws IOException { diff --git a/src/main/java/org/concordion/api/Command.java b/src/main/java/org/concordion/api/Command.java index a1c5ee2b4..5a932cb16 100644 --- a/src/main/java/org/concordion/api/Command.java +++ b/src/main/java/org/concordion/api/Command.java @@ -15,6 +15,9 @@ public interface Command { * * Remove the example command from the parent object and put it in the examples list (or before examples) * * Add new commands to examples or before examples * * Modify the tree to put table or list execute commands on the right children elements. + * @param element the command call element to modify + * @param examples a list of examples + * @param beforeExamples a list of "before" examples */ void modifyCommandCallTree(CommandCall element, List examples, List beforeExamples); } diff --git a/src/main/java/org/concordion/internal/cache/RunResultsCache.java b/src/main/java/org/concordion/internal/cache/RunResultsCache.java index 3356899db..c1d5c64d4 100644 --- a/src/main/java/org/concordion/internal/cache/RunResultsCache.java +++ b/src/main/java/org/concordion/internal/cache/RunResultsCache.java @@ -42,7 +42,7 @@ public synchronized RunOutput getFromCache(FixtureType fixtureType, String examp /** * Initialises an entry in the cache for a specification with the given description. * Individual examples may then be run, and their results will be added to the fixture - * total when {@link #finishRun(FixtureDeclarations, String, ResultSummary, ImplementationStatusChecker)} + * total when {@link #finishRun(FixtureType, String, ResultSummary, ImplementationStatusChecker)} * is called. * @param fixtureType the fixture class that is being started * @param specificationDescription a description of the target specification @@ -90,7 +90,8 @@ private CacheKey getID(Class fixtureClass, String example) { * @param actualResultSummary the results as reported from the spec * @param statusChecker modifier that updates results dependent on ImplementationStatus (ExpectedToFail etc) */ - public synchronized void finishRun(FixtureType fixtureType, String example, + public synchronized void finishRun(FixtureType fixtureType, + String example, ResultSummary actualResultSummary, ImplementationStatusChecker statusChecker) { assert fixtureType.getFixtureClass() != null; @@ -103,7 +104,10 @@ public synchronized void finishRun(FixtureType fixtureType, String example, } } - private RunOutput setResultsForExample(FixtureType fixtureType, String example, ResultSummary actualResultSummary, ImplementationStatusChecker statusChecker) { + private RunOutput setResultsForExample(FixtureType fixtureType, + String example, + ResultSummary actualResultSummary, + ImplementationStatusChecker statusChecker) { ConcordionRunOutput exampleResults = (ConcordionRunOutput) getExampleFromCache(fixtureType, example); if (exampleResults == null) { throw new IllegalStateException("Internal error: startRun must always be called before finishRun"); From fd0744bddea7e161992532fea4e872c7f33174aa Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 1 Jul 2018 12:01:40 +1200 Subject: [PATCH 32/42] Updated Travis to use oraclejdk10 --- .gitignore | 4 ++++ .travis.yml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 746a3a7f2..f260970be 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ .gradle build/ +# Maven +target/ + # Eclipse .classpath .project @@ -10,6 +13,7 @@ bin/ # IDEA .idea/ +out/ *.iml # VS Code diff --git a/.travis.yml b/.travis.yml index a9f1d87fc..b62b9cb6f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ os: - linux jdk: -- openjdk10 +- oraclejdk10 - oraclejdk9 - oraclejdk8 - openjdk7 From ae15dfcb088f8ba6b26b9133cadc40751407d6cf Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 1 Jul 2018 12:09:42 +1200 Subject: [PATCH 33/42] Updated website URL to use https --- publish.gradle | 2 +- .../concordion/internal/extension/ExtensionChecker.java | 2 +- .../spec/concordion/annotation/ConcordionOptions.md | 8 ++++---- .../common/command/expressions/Expressions.html | 4 ++-- .../concordion/specificationType/markdown/Markdown.md | 4 ++-- .../specificationType/markdown/MarkdownExecuteCommand.md | 2 +- .../specificationType/markdown/MarkdownGrammar.markdown | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/publish.gradle b/publish.gradle index d7d508785..bd2c8a3c4 100644 --- a/publish.gradle +++ b/publish.gradle @@ -222,7 +222,7 @@ bintray { licenses = ['Apache-2.0'] issueTrackerUrl = issuesUrl vcsUrl = vcsUrl - websiteUrl = 'http://concordion.org' + websiteUrl = 'https://concordion.org' version { name = project.version released = new Date() diff --git a/src/main/java/org/concordion/internal/extension/ExtensionChecker.java b/src/main/java/org/concordion/internal/extension/ExtensionChecker.java index bc49718af..97e7474d1 100644 --- a/src/main/java/org/concordion/internal/extension/ExtensionChecker.java +++ b/src/main/java/org/concordion/internal/extension/ExtensionChecker.java @@ -41,7 +41,7 @@ private static void checkForDeprecatedExtensions() { } catch (ClassNotFoundException expected) { return; // We don't want it to be found } - String msg = "Warning. The concordion-extensions module is now deprecated. Please replace with the individual extension modules. See http://concordion.org/Extensions.html."; + String msg = "Warning. The concordion-extensions module is now deprecated. Please replace with the individual extension modules. See https://concordion.org/Extensions.html."; System.err.println(msg); } } diff --git a/src/test/resources/spec/concordion/annotation/ConcordionOptions.md b/src/test/resources/spec/concordion/annotation/ConcordionOptions.md index 2eb723df0..82cc804e1 100644 --- a/src/test/resources/spec/concordion/annotation/ConcordionOptions.md +++ b/src/test/resources/spec/concordion/annotation/ConcordionOptions.md @@ -45,8 +45,8 @@ Without additional extensions, the following are translated as-is. [[not a wikilink]] - http://concordion.org - http://concordion.org + https://concordion.org + https://concordion.org @@ -67,8 +67,8 @@ Given the method `withPegdownExtensions(int options)` has been [called](- "withW <a href="./wikilink.html">wikilink</a> - http://concordion.org - <a href="http://concordion.org">http://concordion.org</a> + https://concordion.org + <a href="https://concordion.org">https://concordion.org</a> diff --git a/src/test/resources/spec/concordion/common/command/expressions/Expressions.html b/src/test/resources/spec/concordion/common/command/expressions/Expressions.html index b2b4dd203..4de040f2a 100644 --- a/src/test/resources/spec/concordion/common/command/expressions/Expressions.html +++ b/src/test/resources/spec/concordion/common/command/expressions/Expressions.html @@ -5,8 +5,8 @@

    Expressions

    Concordion uses expressions to reference fields and call methods of the corresponding test fixture and to set specification variables.

    -

    In order to keep your specifications simple and maintainable, Concordion deliberately restricts the expression format that is allowed when instrumenting specifications. -Complexity should be moved into the fixture code, and then evolved into a DSL, where it is easier to maintain. +

    In order to keep your specifications simple and maintainable, Concordion deliberately restricts the expression format that is allowed when instrumenting specifications. +Complexity should be moved into the fixture code, and then evolved into a DSL, where it is easier to maintain. The idea is to have the fixture do all the work of fetching and munging the data and then return exactly the data that the spec needs, which helps to decouple the spec from the implementation.

    The following expressions are available within Concordion commands:

    diff --git a/src/test/resources/spec/concordion/specificationType/markdown/Markdown.md b/src/test/resources/spec/concordion/specificationType/markdown/Markdown.md index 752fc3a6b..c2a18c521 100644 --- a/src/test/resources/spec/concordion/specificationType/markdown/Markdown.md +++ b/src/test/resources/spec/concordion/specificationType/markdown/Markdown.md @@ -5,10 +5,10 @@ _Since_: Concordion 2.0.0 [Markdown](https://daringfireball.net/projects/markdown/) provides an easy-to-read and easy-to-write syntax for converting plain text to structured XHTML. -Concordion's Markdown support allows you to write your [Concordion](http://concordion.org/) specification in the Markdown format, converting the Markdown to XHTML at runtime and running the resultant XHTML as a Concordion specification. +Concordion's Markdown support allows you to write your [Concordion](https://concordion.org/) specification in the Markdown format, converting the Markdown to XHTML at runtime and running the resultant XHTML as a Concordion specification. -The following assumes that you already understand Concordion and Markdown. If not, please visit the [Concordion tutorial](http://concordion.org/Tutorial.html) and read the Markdown [basics](https://daringfireball.net/projects/markdown/basics). +The following assumes that you already understand Concordion and Markdown. If not, please visit the [Concordion tutorial](https://concordion.org/Tutorial.html) and read the Markdown [basics](https://daringfireball.net/projects/markdown/basics). ### Use of inline links diff --git a/src/test/resources/spec/concordion/specificationType/markdown/MarkdownExecuteCommand.md b/src/test/resources/spec/concordion/specificationType/markdown/MarkdownExecuteCommand.md index ae03f2646..afe5667c2 100644 --- a/src/test/resources/spec/concordion/specificationType/markdown/MarkdownExecuteCommand.md +++ b/src/test/resources/spec/concordion/specificationType/markdown/MarkdownExecuteCommand.md @@ -55,7 +55,7 @@ If the special variable `#TEXT` is used as a parameter within the _expression_, ### Execute on a table -To run the [execute command on a table](http://concordion.org/Tutorial.html#executeTable), the execute command is specified in the first table header column, +To run the [execute command on a table](https://concordion.org/Tutorial.html#executeTable), the execute command is specified in the first table header column, followed by the command for that column (if any), with the commands for each column of the table specified in the table header.
    diff --git a/src/test/resources/spec/concordion/specificationType/markdown/MarkdownGrammar.markdown b/src/test/resources/spec/concordion/specificationType/markdown/MarkdownGrammar.markdown index 97c6e1d61..6105b6c2b 100644 --- a/src/test/resources/spec/concordion/specificationType/markdown/MarkdownGrammar.markdown +++ b/src/test/resources/spec/concordion/specificationType/markdown/MarkdownGrammar.markdown @@ -179,7 +179,7 @@ The [execute on a list](http://concordion.github.io/concordion/latest/spec/comma #### Handling unusual sentence structures -In order to [handle unusual sentence structures](http://concordion.org/Tutorial.html#executeUnusualSentences), Concordion allows you to use an `execute` command on an outer HTML element. When using Markdown, this can be implemented using the HTML structure wrapped in a `
    `. +In order to [handle unusual sentence structures](https://concordion.org/Tutorial.html#executeUnusualSentences), Concordion allows you to use an `execute` command on an outer HTML element. When using Markdown, this can be implemented using the HTML structure wrapped in a `
    `.

    From 4093b812e7ba7afafa3e8427f98f662812d0e42a Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 1 Jul 2018 17:31:46 +1200 Subject: [PATCH 34/42] Added deprecated methods for backward compatibility --- .../org/concordion/api/AbstractCommand.java | 23 ++++++++++++++++++- .../ClassNameBasedSpecificationLocator.java | 12 ++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/concordion/api/AbstractCommand.java b/src/main/java/org/concordion/api/AbstractCommand.java index 29163390f..8ecb1e537 100644 --- a/src/main/java/org/concordion/api/AbstractCommand.java +++ b/src/main/java/org/concordion/api/AbstractCommand.java @@ -6,20 +6,41 @@ public abstract class AbstractCommand implements Command { + @Deprecated public List getExamples(CommandCall command) { return Collections.emptyList(); } + @Deprecated + public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + } + + @Deprecated + public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + } + + @Deprecated + public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) { + } + + // For backwards compatibility, call the deprecated methods + // TODO - remove this in Concordion 3.0.0 + @Override public void execute(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + execute(commandCall, evaluator, resultRecorder); } + @Override public void setUp(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + setUp(commandCall, evaluator, resultRecorder); } + @Override public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder, Fixture fixture) { + verify(commandCall, evaluator, resultRecorder); } + @Override public void modifyCommandCallTree(CommandCall element, List examples, List beforeExamples) { } - } diff --git a/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java b/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java index 8ca15b383..ce3457946 100644 --- a/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java +++ b/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java @@ -5,9 +5,17 @@ import org.concordion.internal.util.Check; public class ClassNameBasedSpecificationLocator implements SpecificationLocator { + + public ClassNameBasedSpecificationLocator() { + } + + @Deprecated + public ClassNameBasedSpecificationLocator(String specificationSuffix) { + } + @Override - public Resource locateSpecification(FixtureType fixtureType, String typeSuffix) { + public Resource locateSpecification(FixtureType fixtureType, String specificationSuffix) { Check.notNull(fixtureType, "Fixture is null"); - return FixtureSpecificationMapper.toSpecificationResource(fixtureType, typeSuffix); + return FixtureSpecificationMapper.toSpecificationResource(fixtureType, specificationSuffix); } } From 0dc478448569537762a80f707de0fee70ed1e71b Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 1 Jul 2018 17:33:01 +1200 Subject: [PATCH 35/42] Updated ExtensionChecker to check for compatibility with Concordion 2.2.0 --- .../internal/extension/ExtensionChecker.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/concordion/internal/extension/ExtensionChecker.java b/src/main/java/org/concordion/internal/extension/ExtensionChecker.java index bc49718af..651777971 100644 --- a/src/main/java/org/concordion/internal/extension/ExtensionChecker.java +++ b/src/main/java/org/concordion/internal/extension/ExtensionChecker.java @@ -8,10 +8,13 @@ public class ExtensionChecker { private static final String MARKDOWN_EXTENSION_CLASS = "org.concordion.ext.MarkdownExtension"; private static final String EXTENSIONS_CLASS = "org.concordion.ext.Extensions"; private static final String EXCEL_EXTENSION_SOURCE_CLASS = "org.concordion.ext.excel.ExcelClassPathSource"; + private static final String RUN_TOTALS_EXTENSION_CLASS = "org.concordion.ext.runtotals.RunTotalsExtension"; + private static final String EXECUTE_ONLY_IF_EXTENSION_CLASS = "org.concordion.ext.ExecuteOnlyIfExtension"; public static void checkForOutdatedExtensions() { checkForExtensionsNowInCore(); checkForBreakingChanges(); + checkCompatibility(); checkForDeprecatedExtensions(); } @@ -31,10 +34,34 @@ private static void checkForBreakingChanges() { } catch (ClassNotFoundException expected) { return; // We don't want it to be found } - String msg = "The Concordion Excel Extension must be updated to the latest version to work with Concordion 2.0 or later."; + String msg = "The Concordion Excel Extension must be updated to the latest version to work with Concordion 2.0.0 or later."; throw new ConfigurationException(msg); } + private static void checkCompatibility() { + assertCompatibleVersion(RUN_TOTALS_EXTENSION_CLASS, "concordion-run-totals-extension", "1.2", "2.2.0"); + assertCompatibleVersion(EXECUTE_ONLY_IF_EXTENSION_CLASS, "execute-executeonlyif-extension", "0.3", "2.2.0"); + } + + private static void assertCompatibleVersion(String extensionClassName, String extensionName, String requiredSpecificationVersion, String breakingConcordionVersion) { + try { + Class extensionClass = Class.forName(extensionClassName); + Package extensionPackage = extensionClass.getPackage(); + String specificationVersion = extensionPackage.getSpecificationVersion(); + if (extensionPackage.getImplementationTitle() != null) { + extensionName = extensionPackage.getImplementationTitle(); + } + if (specificationVersion == null || !extensionPackage.isCompatibleWith(requiredSpecificationVersion)) { + String msg = "The " + extensionName + " must be updated to version " + requiredSpecificationVersion + + ".0 or later to work with Concordion " + breakingConcordionVersion + " or later."; + throw new ConfigurationException(msg); + } + return; // Passes the check since it's the right version + } catch (ClassNotFoundException expected) { + return; // Passes the check since it's not on classpath + } + } + private static void checkForDeprecatedExtensions() { try { Class.forName(EXTENSIONS_CLASS); From 4a55ae6acc2678d5e2952a730ce5988659b796f3 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sun, 1 Jul 2018 18:09:18 +1200 Subject: [PATCH 36/42] Added extra properties to MANIFEST.MF --- publish.gradle | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/publish.gradle b/publish.gradle index bd2c8a3c4..ae1a5fe6e 100644 --- a/publish.gradle +++ b/publish.gradle @@ -3,6 +3,7 @@ plugins { id 'org.ajoberstar.git-publish' version '1.0.0' id "com.jfrog.bintray" version "1.6" id 'org.kordamp.gradle.clirr' version '0.2.2' + id 'net.nemerosa.versioning' version '2.7.1' } apply from: 'build.gradle' @@ -47,6 +48,22 @@ distributions { } } +jar { + manifest { + attributes 'Specification-Title' : project.name, + 'Implementation-Title' : project.name, + 'Specification-Version' : version.substring(0, version.lastIndexOf(".")), + 'Implementation-Version': version, + 'Implementation-Vendor' : 'concordion.org', + 'Specification-Vendor' : 'concordion.org', + 'Created-By' : System.getProperty('java.version') + ' (' + System.getProperty('java.vendor') + ')', + 'Built-With' : "gradle-${project.getGradle().getGradleVersion()}, groovy-${GroovySystem.getVersion()}", + 'Build-Time' : String.format("%tFT% Date: Sun, 1 Jul 2018 23:02:09 +1200 Subject: [PATCH 37/42] Added warnings for extensions using deprecated APIs --- .../internal/extension/ExtensionChecker.java | 91 ++++++++++--------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/concordion/internal/extension/ExtensionChecker.java b/src/main/java/org/concordion/internal/extension/ExtensionChecker.java index 89974064d..c0816f37b 100644 --- a/src/main/java/org/concordion/internal/extension/ExtensionChecker.java +++ b/src/main/java/org/concordion/internal/extension/ExtensionChecker.java @@ -5,70 +5,75 @@ public class ExtensionChecker { - private static final String MARKDOWN_EXTENSION_CLASS = "org.concordion.ext.MarkdownExtension"; - private static final String EXTENSIONS_CLASS = "org.concordion.ext.Extensions"; - private static final String EXCEL_EXTENSION_SOURCE_CLASS = "org.concordion.ext.excel.ExcelClassPathSource"; - private static final String RUN_TOTALS_EXTENSION_CLASS = "org.concordion.ext.runtotals.RunTotalsExtension"; - private static final String EXECUTE_ONLY_IF_EXTENSION_CLASS = "org.concordion.ext.ExecuteOnlyIfExtension"; + private static final String EMBED_EXTENSION_CLASS = "org.concordion.ext.embed.EmbedCommand"; + private static final String EXCEL_EXTENSION_CLASS = "org.concordion.ext.excel.ExcelExtension"; + private static final String EXECUTE_ONLY_IF_EXTENSION_CLASS = "org.concordion.ext.executeOnlyIf.ExecuteOnlyIfCommand"; + private static final String RUN_TOTALS_EXTENSION_CLASS = "org.concordion.ext.runtotals.RunTotalsExtension"; + private static final String SCREENSHOT_EXTENSION_CLASS = "org.concordion.ext.screenshot.ScreenshotEmbedder"; + + private static final String OUTDATED_EXCEL_EXTENSION_CLASS = "org.concordion.ext.excel.ExcelClassPathSource"; + private static final String OUTDATED_EXTENSIONS_CLASS = "org.concordion.ext.Extensions"; + private static final String OUTDATED_MARKDOWN_EXTENSION_CLASS = "org.concordion.ext.MarkdownExtension"; + + private static boolean checked = false; public static void checkForOutdatedExtensions() { - checkForExtensionsNowInCore(); - checkForBreakingChanges(); - checkCompatibility(); - checkForDeprecatedExtensions(); + if (!checked) { + failIfOutdatedExtensionFound(); + checkExtensionCompatibility(); + } + checked = true; + } + + private static void failIfOutdatedExtensionFound() { + failIfPresent(OUTDATED_MARKDOWN_EXTENSION_CLASS, "The Markdown format is now supported in the main Concordion module. The concordion-markdown-extension module must be removed from the class path."); + failIfPresent(OUTDATED_EXTENSIONS_CLASS, "Warning. The concordion-extensions module is now deprecated. Please replace with the individual extension modules. See https://concordion.org/Extensions.html."); + failIfPresent(OUTDATED_EXCEL_EXTENSION_CLASS, "The Concordion Excel Extension must be updated to the latest version to work with Concordion 2.0.0 or later."); } - private static void checkForExtensionsNowInCore() { + private static void checkExtensionCompatibility() { + failIfIncompatible(EXECUTE_ONLY_IF_EXTENSION_CLASS, "concordion-executeonlyif-extension", "0.3", "2.2.0"); + failIfIncompatible(RUN_TOTALS_EXTENSION_CLASS, "concordion-run-totals-extension", "1.2", "2.2.0"); + warnIfIncompatible(EMBED_EXTENSION_CLASS, "concordion-embed-extension", "1.2"); + warnIfIncompatible(EXCEL_EXTENSION_CLASS, "concordion-excel-extension", "2.1"); + warnIfIncompatible(SCREENSHOT_EXTENSION_CLASS, "concordion-screenshot-extension", "1.3"); + } + + private static void failIfPresent(String outdatedExtensionClass, String msg) { try { - Class.forName(MARKDOWN_EXTENSION_CLASS); + Class.forName(outdatedExtensionClass); } catch (ClassNotFoundException expected) { return; // We don't want it to be found } - String msg = "The Markdown format is now supported in the main Concordion module. The concordion-markdown-extension module must be removed from the class path."; throw new ConfigurationException(msg); } - private static void checkForBreakingChanges() { - try { - Class.forName(EXCEL_EXTENSION_SOURCE_CLASS); - } catch (ClassNotFoundException expected) { - return; // We don't want it to be found + private static void warnIfIncompatible(String extensionClassName, String extensionName, String requiredSpecificationVersion) { + if (!isCompatible(extensionClassName, requiredSpecificationVersion)) { + String msg = "Warning: This version of " + extensionName + " is deprecated. " + + "Please update to version " + requiredSpecificationVersion + ".0."; + System.err.println(msg); } - String msg = "The Concordion Excel Extension must be updated to the latest version to work with Concordion 2.0.0 or later."; - throw new ConfigurationException(msg); } - private static void checkCompatibility() { - assertCompatibleVersion(RUN_TOTALS_EXTENSION_CLASS, "concordion-run-totals-extension", "1.2", "2.2.0"); - assertCompatibleVersion(EXECUTE_ONLY_IF_EXTENSION_CLASS, "execute-executeonlyif-extension", "0.3", "2.2.0"); + private static void failIfIncompatible(String extensionClassName, String extensionName, String requiredSpecificationVersion, String breakingConcordionVersion) { + if (!isCompatible(extensionClassName, requiredSpecificationVersion)) { + String msg = "The " + extensionName + " must be updated to version " + requiredSpecificationVersion + + ".0 or later to work with Concordion " + breakingConcordionVersion + " or later."; + throw new ConfigurationException(msg); + } } - private static void assertCompatibleVersion(String extensionClassName, String extensionName, String requiredSpecificationVersion, String breakingConcordionVersion) { + private static boolean isCompatible(String extensionClassName, String requiredSpecificationVersion) { + boolean compatible; try { Class extensionClass = Class.forName(extensionClassName); Package extensionPackage = extensionClass.getPackage(); String specificationVersion = extensionPackage.getSpecificationVersion(); - if (extensionPackage.getImplementationTitle() != null) { - extensionName = extensionPackage.getImplementationTitle(); - } - if (specificationVersion == null || !extensionPackage.isCompatibleWith(requiredSpecificationVersion)) { - String msg = "The " + extensionName + " must be updated to version " + requiredSpecificationVersion + - ".0 or later to work with Concordion " + breakingConcordionVersion + " or later."; - throw new ConfigurationException(msg); - } - return; // Passes the check since it's the right version + compatible = specificationVersion != null && extensionPackage.isCompatibleWith(requiredSpecificationVersion); } catch (ClassNotFoundException expected) { - return; // Passes the check since it's not on classpath - } - } - - private static void checkForDeprecatedExtensions() { - try { - Class.forName(EXTENSIONS_CLASS); - } catch (ClassNotFoundException expected) { - return; // We don't want it to be found + compatible = true; // Passes the check since it's not on classpath } - String msg = "Warning. The concordion-extensions module is now deprecated. Please replace with the individual extension modules. See https://concordion.org/Extensions.html."; - System.err.println(msg); + return compatible; } } From e066f446b89fc637970d62803fcd112260713613 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 14 Jul 2018 07:23:48 +1200 Subject: [PATCH 38/42] Replace FixtureType with FixtureDeclarations interface --- src/main/java/org/concordion/Concordion.java | 23 +++++++++---------- .../concordion/api/FixtureDeclarations.java | 9 +++++++- .../concordion/api/SpecificationLocator.java | 6 ++--- .../ClassNameBasedSpecificationLocator.java | 7 +++--- .../internal/FixtureSpecificationMapper.java | 5 ++-- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/concordion/Concordion.java b/src/main/java/org/concordion/Concordion.java index 9f5e25762..78002e1d0 100644 --- a/src/main/java/org/concordion/Concordion.java +++ b/src/main/java/org/concordion/Concordion.java @@ -4,7 +4,6 @@ import java.util.List; import org.concordion.api.*; -import org.concordion.internal.FixtureType; import org.concordion.internal.SpecificationToSpecificationByExampleAdaptor; import org.concordion.internal.SpecificationType; import org.concordion.internal.SummarizingResultRecorder; @@ -26,27 +25,27 @@ public class Concordion { * @param specificationLocator locates the specification based on the specification type * @param specificationReader specification reader * @param evaluatorFactory evaluator factory - * @param fixtureType a wrapper around the fixture class + * @param fixtureDeclarations a wrapper around the fixture class * @throws IOException on i/o error */ - public Concordion(List specificationTypes, SpecificationLocator specificationLocator, SpecificationReader specificationReader, EvaluatorFactory evaluatorFactory, FixtureType fixtureType) throws IOException { + public Concordion(List specificationTypes, SpecificationLocator specificationLocator, SpecificationReader specificationReader, EvaluatorFactory evaluatorFactory, FixtureDeclarations fixtureDeclarations) throws IOException { this.specificationReader = specificationReader; this.evaluatorFactory = evaluatorFactory; SpecificationType specificationType = null; for (SpecificationType currentType : specificationTypes) { - Resource currentResource = specificationLocator.locateSpecification(fixtureType, currentType.getTypeSuffix()); + Resource currentResource = specificationLocator.locateSpecification(fixtureDeclarations, currentType.getTypeSuffix()); if (specificationReader.canFindSpecification(currentResource)) { if (specificationType != null) { - throw new RuntimeException(createMultipleSpecsMessage(fixtureType, specificationType, currentType)); + throw new RuntimeException(createMultipleSpecsMessage(fixtureDeclarations, specificationType, currentType)); } specificationType = currentType; resource = currentResource; } } if (specificationType == null) { - throw new RuntimeException(createUnableToFindSpecMessage(fixtureType, specificationTypes)); + throw new RuntimeException(createUnableToFindSpecMessage(fixtureDeclarations, specificationTypes)); } specificationReader.setSpecificationConverter(specificationType.getConverter()); } @@ -75,10 +74,10 @@ private SpecificationByExample getSpecification() throws IOException { return specification; } - public List getExampleNames(FixtureType fixtureType) throws IOException { + public List getExampleNames(FixtureDeclarations fixtureDeclarations) throws IOException { List exampleNames = getSpecification().getExampleNames(); if (exampleNames.isEmpty()) { - exampleNames.add(fixtureType.getDescription()); + exampleNames.add(fixtureDeclarations.getDescription()); } return exampleNames; } @@ -125,13 +124,13 @@ public void checkValidStatus(FixtureDeclarations fixtureDeclarations) throws IOE } } - private String createMultipleSpecsMessage(FixtureType fixtureType, SpecificationType type1, SpecificationType type2) { - String fixturePathWithoutSuffix = fixtureType.getFixturePathWithoutSuffix(); + private String createMultipleSpecsMessage(FixtureDeclarations fixtureDeclarations, SpecificationType type1, SpecificationType type2) { + String fixturePathWithoutSuffix = fixtureDeclarations.getFixturePathWithoutSuffix(); return SimpleFormatter.format("Found multiple matching specifications: '%s.%s' and '%s.%s'", fixturePathWithoutSuffix, type1.getTypeSuffix(), fixturePathWithoutSuffix, type2.getTypeSuffix()); } - private String createUnableToFindSpecMessage(FixtureType fixtureType, List specificationTypes) { + private String createUnableToFindSpecMessage(FixtureDeclarations fixtureDeclarations, List specificationTypes) { String msg = "Unable to find specification: '"; boolean first = true; for (SpecificationType specificationType : specificationTypes) { @@ -140,7 +139,7 @@ private String createUnableToFindSpecMessage(FixtureType fixtureType, List getFixtureClass(); + boolean declaresFullOGNL(); boolean declaresFailFast(); - + Class[] getDeclaredFailFastExceptions(); boolean declaresResources(); @@ -21,4 +24,8 @@ public interface FixtureDeclarations { ImplementationStatus getDeclaredImplementationStatus(); List getDeclaredConcordionOptionsParentFirst(); + + String getFixturePathWithoutSuffix(); + + String getDescription(); } \ No newline at end of file diff --git a/src/main/java/org/concordion/api/SpecificationLocator.java b/src/main/java/org/concordion/api/SpecificationLocator.java index b3bf4a0a4..086ca53d9 100644 --- a/src/main/java/org/concordion/api/SpecificationLocator.java +++ b/src/main/java/org/concordion/api/SpecificationLocator.java @@ -1,15 +1,13 @@ package org.concordion.api; -import org.concordion.internal.FixtureType; - public interface SpecificationLocator { /** * Locates a specification, allowing the type suffix of the specification to be specified. - * @param fixtureType the fixture type to find the specification for + * @param fixtureDeclarations the fixture type to find the specification for * @param typeSuffix the suffix of the specification * @return the resource for the specification, which may or may not actually exist * * @since 2.0.0 */ - Resource locateSpecification(FixtureType fixtureType, String typeSuffix); + Resource locateSpecification(FixtureDeclarations fixtureDeclarations, String typeSuffix); } diff --git a/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java b/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java index ce3457946..bb6829f30 100644 --- a/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java +++ b/src/main/java/org/concordion/internal/ClassNameBasedSpecificationLocator.java @@ -1,5 +1,6 @@ package org.concordion.internal; +import org.concordion.api.FixtureDeclarations; import org.concordion.api.Resource; import org.concordion.api.SpecificationLocator; import org.concordion.internal.util.Check; @@ -14,8 +15,8 @@ public ClassNameBasedSpecificationLocator(String specificationSuffix) { } @Override - public Resource locateSpecification(FixtureType fixtureType, String specificationSuffix) { - Check.notNull(fixtureType, "Fixture is null"); - return FixtureSpecificationMapper.toSpecificationResource(fixtureType, specificationSuffix); + public Resource locateSpecification(FixtureDeclarations fixtureDeclarations, String specificationSuffix) { + Check.notNull(fixtureDeclarations, "Fixture is null"); + return FixtureSpecificationMapper.toSpecificationResource(fixtureDeclarations, specificationSuffix); } } diff --git a/src/main/java/org/concordion/internal/FixtureSpecificationMapper.java b/src/main/java/org/concordion/internal/FixtureSpecificationMapper.java index d67d19ff1..51ce20b05 100644 --- a/src/main/java/org/concordion/internal/FixtureSpecificationMapper.java +++ b/src/main/java/org/concordion/internal/FixtureSpecificationMapper.java @@ -1,5 +1,6 @@ package org.concordion.internal; +import org.concordion.api.FixtureDeclarations; import org.concordion.api.Resource; import org.concordion.integration.TestFrameworkProvider; @@ -25,8 +26,8 @@ protected ServiceLoader initialValue() { } }; - public static Resource toSpecificationResource(FixtureType fixtureType, String specificationSuffix) { - String slashedClassName = fixtureType.getFixtureClass().getName().replaceAll("\\.", "/"); + public static Resource toSpecificationResource(FixtureDeclarations fixtureDeclarations, String specificationSuffix) { + String slashedClassName = fixtureDeclarations.getFixtureClass().getName().replaceAll("\\.", "/"); String fixturePath = removeSuffixFromFixtureName(slashedClassName); String resourcePath = "/" + fixturePath + "." + specificationSuffix; From 1d09c1a268dae55451bd8fdd9893ec51436bc126 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 14 Jul 2018 10:03:21 +1200 Subject: [PATCH 39/42] Reverted breaking methods from ConcordionBuilder --- .../concordion/internal/ConcordionBuilder.java | 15 +++++++++------ .../org/concordion/internal/FixtureRunner.java | 2 +- src/test/java/test/concordion/TestRig.java | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/concordion/internal/ConcordionBuilder.java b/src/main/java/org/concordion/internal/ConcordionBuilder.java index 11ba5941a..5217af8d2 100644 --- a/src/main/java/org/concordion/internal/ConcordionBuilder.java +++ b/src/main/java/org/concordion/internal/ConcordionBuilder.java @@ -415,8 +415,8 @@ public ConcordionBuilder withFailFast(Class[] failFastExcep return this; } - public ConcordionBuilder withFixtureType(FixtureType fixtureType) { - this.fixtureType = fixtureType; + public ConcordionBuilder withFixture(Fixture fixture) { + this.fixtureType = fixture.getFixtureType(); withResources(fixtureType); @@ -446,7 +446,12 @@ public ConcordionExtender withOuterExampleListener(OuterExampleListener listener return this; } - public ConcordionBuilder withResources(FixtureType fixtureType) { + public ConcordionBuilder withResources(Fixture fixture) { + withResources(fixture.getFixtureType()); + return this; + } + + private void withResources(FixtureType fixtureType) { boolean includeDefaultStyling = true; Source resourceSource = sources.get(SourceType.RESOURCE); @@ -480,11 +485,9 @@ public ConcordionBuilder withResources(FixtureType fixtureType) { if (includeDefaultStyling) { addDefaultStyling(resourceSource); } - - return this; } - private void addDefaultStyling(Source resourceSource) { + private void addDefaultStyling(Source resourceSource) { String stylesheetContent = resourceSource.readResourceAsString(EMBEDDED_STYLESHEET_RESOURCE); withEmbeddedCSS(stylesheetContent); } diff --git a/src/main/java/org/concordion/internal/FixtureRunner.java b/src/main/java/org/concordion/internal/FixtureRunner.java index 4aca76954..31511e5c0 100644 --- a/src/main/java/org/concordion/internal/FixtureRunner.java +++ b/src/main/java/org/concordion/internal/FixtureRunner.java @@ -15,7 +15,7 @@ public class FixtureRunner { private Concordion concordion; public FixtureRunner(Fixture fixture, SpecificationLocator specificationLocator) throws UnableToBuildConcordionException { - ConcordionBuilder concordionBuilder = new ConcordionBuilder().withFixtureType(fixture.getFixtureType()).withSpecificationLocator(specificationLocator); + ConcordionBuilder concordionBuilder = new ConcordionBuilder().withFixture(fixture).withSpecificationLocator(specificationLocator); new FixtureExtensionLoader().addExtensions(fixture, concordionBuilder); new FixtureOptionsLoader().addOptions(fixture.getFixtureType(), concordionBuilder); concordion = concordionBuilder.build(); diff --git a/src/test/java/test/concordion/TestRig.java b/src/test/java/test/concordion/TestRig.java index 4c922c24b..023bd63f5 100644 --- a/src/test/java/test/concordion/TestRig.java +++ b/src/test/java/test/concordion/TestRig.java @@ -57,7 +57,7 @@ public ProcessingResult process(Resource resource) { .withSource(source) .withEvaluatorFactory(evaluatorFactory) .withTarget(stubTarget) - .withFixtureType(fixture.getFixtureType()); + .withFixture(fixture); fixtureExtensionLoader.addExtensions(fixture, concordionBuilder); if (extension != null) { From 62dadc240c93a6aa9b08403646bd216b59980bfd Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 14 Jul 2018 10:07:08 +1200 Subject: [PATCH 40/42] Updated version of clirr --- publish.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/publish.gradle b/publish.gradle index ae1a5fe6e..ef8b1ba17 100644 --- a/publish.gradle +++ b/publish.gradle @@ -2,7 +2,7 @@ plugins { id 'net.researchgate.release' version '2.3.0' id 'org.ajoberstar.git-publish' version '1.0.0' id "com.jfrog.bintray" version "1.6" - id 'org.kordamp.gradle.clirr' version '0.2.2' + id 'org.kordamp.gradle.clirr' version '0.2.3' id 'net.nemerosa.versioning' version '2.7.1' } From a92ac544559ecb165a6fb59abb275bf9a8843838 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 14 Jul 2018 21:20:50 +1200 Subject: [PATCH 41/42] Tidy up Travis yml --- .travis.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index b62b9cb6f..7fc62a3c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,7 @@ -sudo: false -dist: trusty language: java -os: -- linux - jdk: - oraclejdk10 - oraclejdk9 - oraclejdk8 -- openjdk7 +- openjdk7 \ No newline at end of file From 65d6855404e14d1a3de129399ea3886e4946ed72 Mon Sep 17 00:00:00 2001 From: Nigel Charman Date: Sat, 14 Jul 2018 22:01:39 +1200 Subject: [PATCH 42/42] [Gradle Release Plugin] - pre tag commit: '2.2.0'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7bea84892..15d4360f0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ #Sat, 25 Jul 2015 22:18:16 +1200 group=org.concordion -version=2.1.4 +version=2.2.0