diff --git a/CHANGELOG.md b/CHANGELOG.md index 7209382427..7eb39b6865 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO * Allow parameter-types in escaped optional groups ([#cucumber/572](https://github.com/cucumber/cucumber/pull/572), [#cucumber/561](https://github.com/cucumber/cucumber/pull/561) Luke Hill, Jayson Smith, M.P. Korstanje) * Prefer expression with the longest non-empty match ([#cucumber/580](https://github.com/cucumber/cucumber/pull/580) M.P. Korstanje) * Improve heuristics for creating Cucumber/Regular Expressions from strings ([#cucumber/518](https://github.com/cucumber/cucumber/pull/518) Aslak Hellesøy) + * [Kotlin-Java8] Upgrade Kotlin to v1.3.0 and more idiomatic Kotlin ([#1590](https://github.com/cucumber/cucumber-jvm/pull/1590) Marit van Dijk) ### Deprecated @@ -42,7 +43,7 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO ### Fixed * [Core] Disambiguate between Windows drive letter and uri scheme ([#1568](https://github.com/cucumber/cucumber-jvm/issues/1568), [#1564](https://github.com/cucumber/cucumber-jvm/issues/1564) jsa34) -## [4.2.3-SNAPSHOT](https://github.com/cucumber/cucumber-jvm/compare/v4.2.2...v4.2.3) (2019-02-08) +## [4.2.3](https://github.com/cucumber/cucumber-jvm/compare/v4.2.2...v4.2.3) (2019-02-08) ### Fixed * [Build] Fix windows build ([#1552](https://github.com/cucumber/cucumber-jvm/pull/1552), [#1551](https://github.com/cucumber/cucumber-jvm/issues/1551) Alexey Mozhenin) diff --git a/core/src/main/java/io/cucumber/core/api/event/TestCaseStarted.java b/core/src/main/java/io/cucumber/core/api/event/TestCaseStarted.java index 151df6d18c..0c2c77b2b3 100644 --- a/core/src/main/java/io/cucumber/core/api/event/TestCaseStarted.java +++ b/core/src/main/java/io/cucumber/core/api/event/TestCaseStarted.java @@ -2,10 +2,16 @@ public final class TestCaseStarted extends TestCaseEvent { public final TestCase testCase; + private final long elapsedTimiMillis; - public TestCaseStarted(Long timeStamp, TestCase testCase) { + public TestCaseStarted(Long timeStamp, Long elapsedTimiMillis, TestCase testCase) { super(timeStamp, testCase); this.testCase = testCase; + this.elapsedTimiMillis = elapsedTimiMillis; + } + + public long getElapsedTimiMillis() { + return elapsedTimiMillis; } } diff --git a/core/src/main/java/io/cucumber/core/event/EventBus.java b/core/src/main/java/io/cucumber/core/event/EventBus.java index f0ae9765c9..07cc7a6748 100644 --- a/core/src/main/java/io/cucumber/core/event/EventBus.java +++ b/core/src/main/java/io/cucumber/core/event/EventBus.java @@ -7,6 +7,8 @@ public interface EventBus extends EventPublisher { Long getTime(); + Long getElapsedTimeMillis(); + void send(Event event); void sendAll(Iterable queue); diff --git a/core/src/main/java/io/cucumber/core/plugin/JSONFormatter.java b/core/src/main/java/io/cucumber/core/plugin/JSONFormatter.java index a03dd21365..48a9889117 100644 --- a/core/src/main/java/io/cucumber/core/plugin/JSONFormatter.java +++ b/core/src/main/java/io/cucumber/core/plugin/JSONFormatter.java @@ -1,21 +1,14 @@ package io.cucumber.core.plugin; -import io.cucumber.core.api.event.HookTestStep; -import io.cucumber.core.api.event.HookType; -import io.cucumber.core.api.event.PickleStepTestStep; -import io.cucumber.core.api.event.Result; -import io.cucumber.core.api.event.TestCase; -import io.cucumber.core.api.event.TestStep; -import io.cucumber.core.api.event.EmbedEvent; -import io.cucumber.core.api.event.EventHandler; -import io.cucumber.core.api.event.EventListener; -import io.cucumber.core.api.event.EventPublisher; -import io.cucumber.core.api.event.TestCaseStarted; -import io.cucumber.core.api.event.TestRunFinished; -import io.cucumber.core.api.event.TestSourceRead; -import io.cucumber.core.api.event.TestStepFinished; -import io.cucumber.core.api.event.TestStepStarted; -import io.cucumber.core.api.event.WriteEvent; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import gherkin.ast.Background; import gherkin.ast.Feature; import gherkin.ast.ScenarioDefinition; @@ -29,11 +22,22 @@ import gherkin.pickles.PickleString; import gherkin.pickles.PickleTable; import gherkin.pickles.PickleTag; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import io.cucumber.core.api.event.EmbedEvent; +import io.cucumber.core.api.event.EventHandler; +import io.cucumber.core.api.event.EventListener; +import io.cucumber.core.api.event.EventPublisher; +import io.cucumber.core.api.event.HookTestStep; +import io.cucumber.core.api.event.HookType; +import io.cucumber.core.api.event.PickleStepTestStep; +import io.cucumber.core.api.event.Result; +import io.cucumber.core.api.event.TestCase; +import io.cucumber.core.api.event.TestCaseStarted; +import io.cucumber.core.api.event.TestRunFinished; +import io.cucumber.core.api.event.TestSourceRead; +import io.cucumber.core.api.event.TestStep; +import io.cucumber.core.api.event.TestStepFinished; +import io.cucumber.core.api.event.TestStepStarted; +import io.cucumber.core.api.event.WriteEvent; public final class JSONFormatter implements EventListener { private String currentFeatureFile; @@ -47,6 +51,7 @@ public final class JSONFormatter implements EventListener { private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); private final NiceAppendable out; private final TestSourcesModel testSources = new TestSourcesModel(); + private DateTimeFormatter dateTimeFormatter; private EventHandler testSourceReadHandler = new EventHandler() { @Override @@ -118,7 +123,7 @@ private void handleTestCaseStarted(TestCaseStarted event) { featureMaps.add(currentFeatureMap); currentElementsList = (List>) currentFeatureMap.get("elements"); } - currentTestCaseMap = createTestCase(event.testCase); + currentTestCaseMap = createTestCase(event); if (testSources.hasBackground(currentFeatureFile, event.testCase.getLine())) { currentElementMap = createBackground(event.testCase); currentElementsList.add(currentElementMap); @@ -187,8 +192,13 @@ private Map createFeatureMap(TestCase testCase) { return featureMap; } - private Map createTestCase(TestCase testCase) { + private Map createTestCase(TestCaseStarted event) { Map testCaseMap = new HashMap(); + + testCaseMap.put("start_timestamp", getDateTimeFromTimeStamp(event)); + + TestCase testCase = event.getTestCase(); + testCaseMap.put("name", testCase.getName()); testCaseMap.put("line", testCase.getLine()); testCaseMap.put("type", "scenario"); @@ -212,6 +222,11 @@ private Map createTestCase(TestCase testCase) { return testCaseMap; } + private String getDateTimeFromTimeStamp(TestCaseStarted event) { + LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(event.getElapsedTimiMillis()), ZoneId.systemDefault()); + return localDateTime.format(dateTimeFormatter == null ? DateTimeFormatter.ISO_DATE_TIME : dateTimeFormatter); + } + private Map createBackground(TestCase testCase) { TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile, testCase.getLine()); if (astNode != null) { @@ -378,4 +393,9 @@ private Map createResultMap(Result result) { } return resultMap; } + + public void setDateTimeFormatter(DateTimeFormatter dateTimeFormatter) { + this.dateTimeFormatter = dateTimeFormatter; + } + } diff --git a/core/src/main/java/io/cucumber/core/runner/TestCase.java b/core/src/main/java/io/cucumber/core/runner/TestCase.java index 4306920610..41ad5865f8 100644 --- a/core/src/main/java/io/cucumber/core/runner/TestCase.java +++ b/core/src/main/java/io/cucumber/core/runner/TestCase.java @@ -1,18 +1,18 @@ package io.cucumber.core.runner; -import io.cucumber.core.api.event.Result; -import io.cucumber.core.api.event.TestStep; -import io.cucumber.core.api.event.TestCaseFinished; -import io.cucumber.core.api.event.TestCaseStarted; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + import gherkin.events.PickleEvent; import gherkin.pickles.PickleLocation; import gherkin.pickles.PickleTag; +import io.cucumber.core.api.event.Result; +import io.cucumber.core.api.event.TestCaseFinished; +import io.cucumber.core.api.event.TestCaseStarted; +import io.cucumber.core.api.event.TestStep; import io.cucumber.core.event.EventBus; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - final class TestCase implements io.cucumber.core.api.event.TestCase { private final PickleEvent pickleEvent; private final List testSteps; @@ -35,7 +35,9 @@ public TestCase(List testSteps, void run(EventBus bus) { boolean skipNextStep = this.dryRun; Long startTime = bus.getTime(); - bus.send(new TestCaseStarted(startTime, this)); + Long startTimeMillis = bus.getElapsedTimeMillis(); + + bus.send(new TestCaseStarted(startTime, startTimeMillis, this)); Scenario scenario = new Scenario(bus, this); for (HookTestStep before : beforeHooks) { diff --git a/core/src/main/java/io/cucumber/core/runner/TimeService.java b/core/src/main/java/io/cucumber/core/runner/TimeService.java index bc81e8ef12..efd20bdc83 100644 --- a/core/src/main/java/io/cucumber/core/runner/TimeService.java +++ b/core/src/main/java/io/cucumber/core/runner/TimeService.java @@ -2,12 +2,18 @@ public interface TimeService { long time(); + long elapsedTimeMillis(); TimeService SYSTEM = new TimeService() { @Override public long time() { return System.nanoTime(); } + + @Override + public long elapsedTimeMillis() { + return System.currentTimeMillis(); + } }; } diff --git a/core/src/main/java/io/cucumber/core/runner/TimeServiceEventBus.java b/core/src/main/java/io/cucumber/core/runner/TimeServiceEventBus.java index 2ee9cc95c2..210a5282c8 100644 --- a/core/src/main/java/io/cucumber/core/runner/TimeServiceEventBus.java +++ b/core/src/main/java/io/cucumber/core/runner/TimeServiceEventBus.java @@ -8,9 +8,13 @@ public final class TimeServiceEventBus extends AbstractEventBus { public TimeServiceEventBus(TimeService stopWatch) { this.stopWatch = stopWatch; } - + @Override public Long getTime() { return stopWatch.time(); } + + public Long getElapsedTimeMillis() { + return stopWatch.elapsedTimeMillis(); + } } diff --git a/core/src/main/java/io/cucumber/core/runtime/ThreadLocalRunnerSupplier.java b/core/src/main/java/io/cucumber/core/runtime/ThreadLocalRunnerSupplier.java index a822c89a69..b1d6b5a3f9 100644 --- a/core/src/main/java/io/cucumber/core/runtime/ThreadLocalRunnerSupplier.java +++ b/core/src/main/java/io/cucumber/core/runtime/ThreadLocalRunnerSupplier.java @@ -3,7 +3,6 @@ import io.cucumber.core.api.event.Event; import io.cucumber.core.api.event.EventHandler; import io.cucumber.core.backend.BackendSupplier; -import io.cucumber.core.backend.ObjectFactory; import io.cucumber.core.backend.ObjectFactorySupplier; import io.cucumber.core.event.AbstractEventBus; import io.cucumber.core.event.EventBus; @@ -62,6 +61,12 @@ public void send(final Event event) { super.send(event); parent.send(event); } + + @Override + public Long getElapsedTimeMillis() + { + return parent.getElapsedTimeMillis(); + } } private static final class SynchronizedEventBus implements EventBus { @@ -104,5 +109,10 @@ public synchronized void registerHandlerFor(Class eventType public synchronized void removeHandlerFor(Class eventType, EventHandler handler) { delegate.removeHandlerFor(eventType, handler); } + + @Override + public Long getElapsedTimeMillis() { + return delegate.getElapsedTimeMillis(); + } } -} +} \ No newline at end of file diff --git a/core/src/test/java/io/cucumber/core/api/event/CanonicalEventOrderTest.java b/core/src/test/java/io/cucumber/core/api/event/CanonicalEventOrderTest.java index 3efe00fce2..5c9c0bc6bd 100644 --- a/core/src/test/java/io/cucumber/core/api/event/CanonicalEventOrderTest.java +++ b/core/src/test/java/io/cucumber/core/api/event/CanonicalEventOrderTest.java @@ -32,13 +32,18 @@ static long getTime() { return new Date().getTime(); } + private static long getTimeInMillis() { + return System.currentTimeMillis(); + } + static Event createTestCaseEvent(final String uri, final int line) { final TestCase testCase = mock(TestCase.class); given(testCase.getUri()).willReturn(uri); given(testCase.getLine()).willReturn(line); - return new TestCaseStarted(getTime(), testCase); + return new TestCaseStarted(getTime(), getTimeInMillis(), testCase); } + private Event runStarted = new TestRunStarted(getTime()); private Event testRead = new TestSourceRead(getTime(), "uri", "source"); private Event suggested = new SnippetsSuggestedEvent(getTime(), "uri", Collections.emptyList(), Collections.emptyList()); diff --git a/core/src/test/java/io/cucumber/core/plugin/JSONFormatterTest.java b/core/src/test/java/io/cucumber/core/plugin/JSONFormatterTest.java index 044e9379ee..ddc6444b08 100755 --- a/core/src/test/java/io/cucumber/core/plugin/JSONFormatterTest.java +++ b/core/src/test/java/io/cucumber/core/plugin/JSONFormatterTest.java @@ -92,6 +92,7 @@ public void should_format_scenario_with_an_undefined_step() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -142,6 +143,7 @@ public void should_format_scenario_with_a_passed_step() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -195,6 +197,7 @@ public void should_format_scenario_with_a_failed_step() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -252,6 +255,7 @@ public void should_format_scenario_outline_with_one_example() { " {\n" + " \"id\": \"fruit-party;monkey-eats-fruits;fruit-table;2\",\n" + " \"keyword\": \"Scenario Outline\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats fruits\",\n" + " \"line\": 7,\n" + " \"description\": \"\",\n" + @@ -336,6 +340,7 @@ public void should_format_feature_with_background() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 6,\n" + " \"description\": \"\",\n" + @@ -379,6 +384,7 @@ public void should_format_feature_with_background() { " {\n" + " \"id\": \"banana-party;monkey-eats-more-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats more bananas\",\n" + " \"line\": 9,\n" + " \"description\": \"\",\n" + @@ -432,6 +438,7 @@ public void should_format_feature_and_scenario_with_tags() { " \"id\": \"banana-party;monkey-eats-more-bananas\",\n" + " \"type\": \"scenario\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"steps\": [\n" + " {\n" + " \"result\": {\n" + @@ -518,6 +525,7 @@ public void should_format_scenario_with_hooks() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -601,6 +609,7 @@ public void should_add_step_hooks_to_step() { " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"type\": \"scenario\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"steps\": [\n" + " {\n" + " \"result\": {\n" + @@ -732,6 +741,7 @@ public void should_handle_write_from_a_hook() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -802,6 +812,7 @@ public void should_handle_embed_from_a_hook() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -875,6 +886,7 @@ public void should_format_scenario_with_a_step_with_a_doc_string() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -935,6 +947,7 @@ public void should_format_scenario_with_a_step_with_a_doc_string_and_content_typ " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -995,6 +1008,7 @@ public void should_format_scenario_with_a_step_with_a_data_table() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -1070,6 +1084,7 @@ public void should_handle_several_features() { " {\n" + " \"id\": \"banana-party;monkey-eats-bananas\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats bananas\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -1103,6 +1118,7 @@ public void should_handle_several_features() { " {\n" + " \"id\": \"orange-party;monkey-eats-oranges\",\n" + " \"keyword\": \"Scenario\",\n" + + " \"start_timestamp\": \"1970-01-01T05:30:00\",\n" + " \"name\": \"Monkey eats oranges\",\n" + " \"line\": 3,\n" + " \"description\": \"\",\n" + @@ -1195,6 +1211,7 @@ public List getSnippet(PickleStep step, String keyword, SnippetType.Func final EventBus bus = new TimeServiceEventBus(new TimeServiceStub(1234)); Appendable stringBuilder = new StringBuilder(); + Runtime.builder() .withClassLoader(classLoader) .withResourceLoader(resourceLoader) diff --git a/core/src/test/java/io/cucumber/core/plugin/JsonParallelRuntimeTest.java b/core/src/test/java/io/cucumber/core/plugin/JsonParallelRuntimeTest.java index 2c5b9f7b6e..cc4439b5fa 100644 --- a/core/src/test/java/io/cucumber/core/plugin/JsonParallelRuntimeTest.java +++ b/core/src/test/java/io/cucumber/core/plugin/JsonParallelRuntimeTest.java @@ -1,29 +1,40 @@ package io.cucumber.core.plugin; -import io.cucumber.core.runtime.Runtime; -import org.junit.Test; - import static org.junit.Assert.assertThat; import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs; +import java.time.format.DateTimeFormatter; + +import org.junit.Test; + +import io.cucumber.core.runtime.Runtime; + //TODO: Merge with the existing test public class JsonParallelRuntimeTest { @Test public void testSingleFeature() { StringBuilder parallel = new StringBuilder(); + + JSONFormatter jsonFormatterParallel = new JSONFormatter(parallel); + jsonFormatterParallel.setDateTimeFormatter(DateTimeFormatter.ISO_DATE); + Runtime.builder() .withArgs("--threads", "3", "src/test/resources/io/cucumber/core/plugin/JSONPrettyFormatterTest.feature") - .withAdditionalPlugins(new JSONFormatter(parallel)) + .withAdditionalPlugins(jsonFormatterParallel) .build() .run(); - + + StringBuilder serial = new StringBuilder(); + JSONFormatter jsonFormatterSerial = new JSONFormatter(serial); + jsonFormatterSerial.setDateTimeFormatter(DateTimeFormatter.ISO_DATE); + Runtime.builder() .withArgs("--threads", "1", "src/test/resources/io/cucumber/core/plugin/JSONPrettyFormatterTest.feature") - .withAdditionalPlugins(new JSONFormatter(serial)) + .withAdditionalPlugins(jsonFormatterSerial) .build() .run(); @@ -33,21 +44,29 @@ public void testSingleFeature() { @Test public void testMultipleFeatures() { StringBuilder parallel = new StringBuilder(); + + JSONFormatter jsonFormatterParallel = new JSONFormatter(parallel); + jsonFormatterParallel.setDateTimeFormatter(DateTimeFormatter.ISO_DATE); + Runtime.builder() .withArgs("--threads", "3", "src/test/resources/io/cucumber/core/plugin/JSONPrettyFormatterTest.feature", "src/test/resources/io/cucumber/core/plugin/FormatterInParallel.feature") - .withAdditionalPlugins(new JSONFormatter(parallel)) + .withAdditionalPlugins(jsonFormatterParallel) .build() .run(); StringBuilder serial = new StringBuilder(); + + JSONFormatter jsonFormatterSerial = new JSONFormatter(serial); + jsonFormatterSerial.setDateTimeFormatter(DateTimeFormatter.ISO_DATE); + Runtime.builder() .withArgs("--threads", "1", "src/test/resources/io/cucumber/core/plugin/JSONPrettyFormatterTest.feature", "src/test/resources/io/cucumber/core/plugin/FormatterInParallel.feature") - .withAdditionalPlugins(new JSONFormatter(serial)) + .withAdditionalPlugins(jsonFormatterSerial) .build() .run(); diff --git a/core/src/test/java/io/cucumber/core/runner/StepDurationTimeService.java b/core/src/test/java/io/cucumber/core/runner/StepDurationTimeService.java index 73a34fb0e2..22b9b3adde 100644 --- a/core/src/test/java/io/cucumber/core/runner/StepDurationTimeService.java +++ b/core/src/test/java/io/cucumber/core/runner/StepDurationTimeService.java @@ -35,4 +35,9 @@ private void handleTestStepStarted(TestStepStarted event) { long time = time(); currentTime.set(time + stepDuration); } + + @Override + public long elapsedTimeMillis() { + return 0L; + } } diff --git a/core/src/test/java/io/cucumber/core/runner/TimeServiceStub.java b/core/src/test/java/io/cucumber/core/runner/TimeServiceStub.java index a70dc5b80d..bb67468fec 100644 --- a/core/src/test/java/io/cucumber/core/runner/TimeServiceStub.java +++ b/core/src/test/java/io/cucumber/core/runner/TimeServiceStub.java @@ -15,4 +15,9 @@ public long time() { currentTime.set(result + duration); return result; } + + @Override + public long elapsedTimeMillis() { + return 0L; + } } diff --git a/core/src/test/java/io/cucumber/core/runtime/RuntimeTest.java b/core/src/test/java/io/cucumber/core/runtime/RuntimeTest.java index 365d077471..db826cb775 100644 --- a/core/src/test/java/io/cucumber/core/runtime/RuntimeTest.java +++ b/core/src/test/java/io/cucumber/core/runtime/RuntimeTest.java @@ -12,6 +12,7 @@ import static org.mockito.Mockito.when; import java.net.URI; +import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -34,7 +35,6 @@ import io.cucumber.core.api.event.Result; import io.cucumber.core.api.event.TestCase; import io.cucumber.core.api.event.TestCaseFinished; -import io.cucumber.core.api.plugin.Plugin; import io.cucumber.core.api.plugin.StepDefinitionReporter; import io.cucumber.core.backend.Backend; import io.cucumber.core.backend.BackendSupplier; @@ -48,6 +48,7 @@ import io.cucumber.core.model.CucumberFeature; import io.cucumber.core.plugin.FormatterBuilder; import io.cucumber.core.plugin.FormatterSpy; +import io.cucumber.core.plugin.JSONFormatter; import io.cucumber.core.runner.TestBackendSupplier; import io.cucumber.core.runner.TestHelper; import io.cucumber.core.runner.TimeService; @@ -73,7 +74,9 @@ public void runs_feature_with_json_formatter() { " When s\n"); StringBuilder out = new StringBuilder(); - Plugin jsonFormatter = FormatterBuilder.jsonFormatter(out); + JSONFormatter jsonFormatter = FormatterBuilder.jsonFormatter(out); + jsonFormatter.setDateTimeFormatter(DateTimeFormatter.ofPattern("")); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); BackendSupplier backendSupplier = new BackendSupplier() { @Override @@ -81,6 +84,7 @@ public Collection get() { return singletonList(mock(Backend.class)); } }; + FeatureSupplier featureSupplier = new TestFeatureSupplier(bus, feature); Runtime.builder() .withBackendSupplier(backendSupplier) @@ -114,6 +118,7 @@ public Collection get() { " ]\n" + " },\n" + " {\n" + + " \"start_timestamp\": \"\",\n" + " \"line\": 4,\n" + " \"name\": \"scenario name\",\n" + " \"description\": \"\",\n" + diff --git a/core/src/test/java/io/cucumber/core/runtime/ThreadLocalRunnerSupplierTest.java b/core/src/test/java/io/cucumber/core/runtime/ThreadLocalRunnerSupplierTest.java index 393e746973..eb65250c24 100644 --- a/core/src/test/java/io/cucumber/core/runtime/ThreadLocalRunnerSupplierTest.java +++ b/core/src/test/java/io/cucumber/core/runtime/ThreadLocalRunnerSupplierTest.java @@ -98,6 +98,6 @@ public void receive(TestCaseStarted event) { fail(); } }); - eventBus.send(new TestCaseStarted(0L, null)); + eventBus.send(new TestCaseStarted(0L, 0L, null)); } -} \ No newline at end of file +} diff --git a/core/src/test/resources/io/cucumber/core/plugin/JSONPrettyFormatterTest.json b/core/src/test/resources/io/cucumber/core/plugin/JSONPrettyFormatterTest.json index f445447d96..7e7fb9c049 100644 --- a/core/src/test/resources/io/cucumber/core/plugin/JSONPrettyFormatterTest.json +++ b/core/src/test/resources/io/cucumber/core/plugin/JSONPrettyFormatterTest.json @@ -44,6 +44,7 @@ }, { "id": "feature-3;scenario-1", + "start_timestamp": "1970-01-01T05:30:00", "before": [ { "result": { @@ -135,6 +136,7 @@ }, { "id": "feature-3;scenariooutline-1;;2", + "start_timestamp": "1970-01-01T05:30:00", "before": [ { "result": { @@ -217,6 +219,7 @@ }, { "id": "feature-3;scenariooutline-1;;3", + "start_timestamp": "1970-01-01T05:30:00", "before": [ { "result": { @@ -299,6 +302,7 @@ }, { "id": "feature-3;scenario-2", + "start_timestamp": "1970-01-01T05:30:00", "before": [ { "result": { diff --git a/junit/src/test/java/io/cucumber/junit/api/FeatureRunnerTest.java b/junit/src/test/java/io/cucumber/junit/api/FeatureRunnerTest.java index b047497650..e1768e56d4 100644 --- a/junit/src/test/java/io/cucumber/junit/api/FeatureRunnerTest.java +++ b/junit/src/test/java/io/cucumber/junit/api/FeatureRunnerTest.java @@ -1,35 +1,5 @@ package io.cucumber.junit.api; -import io.cucumber.core.backend.ObjectFactory; -import io.cucumber.core.backend.ObjectFactorySupplier; -import io.cucumber.core.backend.SingletonObjectFactorySupplier; -import io.cucumber.core.io.MultiLoader; -import io.cucumber.core.io.Resource; -import io.cucumber.core.io.ResourceLoader; -import io.cucumber.core.options.Env; -import io.cucumber.core.runner.TimeServiceEventBus; -import io.cucumber.core.event.EventBus; -import io.cucumber.core.runner.TimeService; -import io.cucumber.core.backend.Backend; -import io.cucumber.core.backend.BackendSupplier; -import io.cucumber.core.options.RuntimeOptions; -import io.cucumber.core.runtime.ThreadLocalRunnerSupplier; -import io.cucumber.core.filter.Filters; -import io.cucumber.core.model.CucumberFeature; -import io.cucumber.core.model.FeatureLoader; -import org.junit.Test; -import org.junit.runner.Description; -import org.junit.runner.notification.RunNotifier; -import org.junit.runners.model.InitializationError; -import org.mockito.InOrder; - -import java.net.URI; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import static io.cucumber.core.backend.ObjectFactoryLoader.loadObjectFactory; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static org.junit.Assert.assertEquals; @@ -39,6 +9,35 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; +import org.junit.runner.Description; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.model.InitializationError; +import org.mockito.InOrder; + +import io.cucumber.core.backend.Backend; +import io.cucumber.core.backend.BackendSupplier; +import io.cucumber.core.backend.ObjectFactorySupplier; +import io.cucumber.core.backend.SingletonObjectFactorySupplier; +import io.cucumber.core.event.EventBus; +import io.cucumber.core.filter.Filters; +import io.cucumber.core.io.MultiLoader; +import io.cucumber.core.io.Resource; +import io.cucumber.core.io.ResourceLoader; +import io.cucumber.core.model.CucumberFeature; +import io.cucumber.core.model.FeatureLoader; +import io.cucumber.core.options.Env; +import io.cucumber.core.options.RuntimeOptions; +import io.cucumber.core.runner.TimeService; +import io.cucumber.core.runner.TimeServiceEventBus; +import io.cucumber.core.runtime.ThreadLocalRunnerSupplier; + public class FeatureRunnerTest { private static void assertDescriptionIsPredictable(Description description, Set descriptions) { @@ -169,6 +168,11 @@ private FeatureRunner createFeatureRunner(CucumberFeature cucumberFeature, JUnit public long time() { return 0L; } + + @Override + public long elapsedTimeMillis() { + return 0L; + } }; BackendSupplier backendSupplier = new BackendSupplier() { @Override diff --git a/kotlin-java8/pom.xml b/kotlin-java8/pom.xml index 99e00cc890..1a0565e115 100644 --- a/kotlin-java8/pom.xml +++ b/kotlin-java8/pom.xml @@ -12,7 +12,7 @@ Cucumber-JVM: Kotlin Java8 - 1.2.51 + 1.2.41 @@ -96,4 +96,4 @@ - + \ No newline at end of file diff --git a/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/LambdaStepdefs.kt b/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/LambdaStepdefs.kt index a1bca8bc4e..3d3c856ab8 100644 --- a/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/LambdaStepdefs.kt +++ b/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/LambdaStepdefs.kt @@ -50,7 +50,7 @@ class LambdaStepdefs : En { Given("A statement with a body expression$") { assertTrue(true) } - Given("A statement with a simple match$", { -> assertTrue(true) }) + Given("A statement with a simple match$", { assertTrue(true) }) val localInt = 1 Given("A statement with a scoped argument$", { assertEquals(2, localInt + 1) }) @@ -62,9 +62,6 @@ class LambdaStepdefs : En { assertEquals(4, d) } } - - class Person { - var first: String? = null - var last: String? = null - } } + +data class Person(val first: String?, val last: String?) diff --git a/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/RunCukesTest.kt b/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/RunCukesTest.kt index 07332164b6..a8c72e1abe 100644 --- a/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/RunCukesTest.kt +++ b/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/RunCukesTest.kt @@ -4,5 +4,4 @@ import io.cucumber.junit.api.Cucumber import org.junit.runner.RunWith @RunWith(Cucumber::class) -class RunCukesTest { -} +class RunCukesTest diff --git a/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/TypeRegistryConfiguration.kt b/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/TypeRegistryConfiguration.kt index 0d9b78082e..b2c4d66e45 100644 --- a/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/TypeRegistryConfiguration.kt +++ b/kotlin-java8/src/test/kotlin/io/cucumber/kotlin/TypeRegistryConfiguration.kt @@ -16,13 +16,10 @@ class TypeRegistryConfiguration : TypeRegistryConfigurer { override fun configureTypeRegistry(typeRegistry: TypeRegistry) { typeRegistry.defineDataTableType(DataTableType( - LambdaStepdefs.Person::class.java, - TableEntryTransformer + Person::class.java, + TableEntryTransformer { map: Map -> - val person = LambdaStepdefs.Person() - person.first = map.get("first") - person.last = map.get("last") - person + Person(map["first"], map["last"]) })) } }