├── .gitignore
├── LICENCE
├── README.md
├── clojure
├── .gitignore
├── pom.xml
└── src
│ ├── main
│ ├── clojure
│ │ └── cucumber
│ │ │ └── runtime
│ │ │ └── clj.clj
│ └── java
│ │ └── cucumber
│ │ └── runtime
│ │ └── clojure
│ │ └── Dummy.java
│ └── test
│ ├── java
│ └── cucumber
│ │ └── runtime
│ │ └── clojure
│ │ ├── ClojureSnippetTest.java
│ │ └── RunCukesTest.java
│ └── resources
│ └── cucumber
│ └── runtime
│ └── clojure
│ ├── belly.clj
│ ├── cukes.feature
│ ├── stepdefs.clj
│ └── tables.feature
├── examples
├── .gitignore
├── README.md
├── pom.xml
├── project.clj
├── src
│ └── clojure_cukes
│ │ └── core.clj
└── test
│ ├── clojure_cukes
│ └── test
│ │ └── core.clj
│ ├── features
│ ├── cukes.feature
│ └── step_definitions
│ │ └── cuke_steps.clj
│ └── java
│ └── features
│ └── RunCukesTest.java
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | **/*.iml
3 |
4 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | Copyright (c) The Cucumber Organisation
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cucumber-Clojure
2 |
3 | [](https://maven-badges.herokuapp.com/maven-central/io.cucumber/cucumber-clojure)
4 |
5 | Cucumber-Clojure is a Cucumber implementation for [Clojure](http://www.clojure.org/).
6 |
7 | This document is the reference for features that are specific to Cucumber-Clojure.
8 |
9 | Please see the [general reference](https://cucumber.io/docs/reference) for features that are common to all Cucumber implementations.
10 |
11 | ## Step Definitions
12 |
13 | Clojure step definitions are defined by using the provided [macros](http://clojure.org/macros). For example:
14 |
15 | ```clojure
16 | (use 'clojure-cukes.core)
17 | (use 'clojure.test)
18 |
19 | (Given #"^I have (\d+) big cukes in my belly$" [cukes]
20 | (println cukes))
21 | ```
22 |
23 | You can use a [DataTable](https://cucumber.io/docs/reference#data-table) to define a list:
24 |
25 | ```
26 | Given I have a table with its keys in a header row:
27 | | id | name | created-at |
28 | | 55 | "foo" | 1293884100000 |
29 | | 56 | "bar" | 1293884100000 |
30 | ```
31 |
32 | Simply declare the following:
33 |
34 | ```clojure
35 | (Given #"^I have a table with its keys in a header row:$" [data]
36 | (reset! most-recent (table->rows data)))
37 | ```
38 |
39 | In this case, the DataTable is flattened to a vector of hashes
40 |
41 | ```clojure
42 | [{:id 55, :name "foo", :created-at 1293884100000}
43 | {:id 56, :name "bar", :created-at 1293884100000}]
44 | ```
45 |
46 | before invoking the step definition.
47 |
48 | ## Installation
49 |
50 | ### Maven
51 | To use cucumber-jvm-clojure in your project, add the following dependency to your `pom.xml`:
52 |
53 | ```xml
54 |
55 | io.cucumber
56 | cucumber-clojure
57 | 2.0.1
58 | test
59 |
60 | ```
61 |
62 |
63 | ## Running
64 |
65 | There are several ways to run scenarios with Cucumber-Clojure:
66 | * lein-cucumber
67 | * JunitRunner
68 |
69 | ### lein-cucumber
70 |
71 | [Leiningen](http://leiningen.org/) uses [clojure.test](TODO) to run Cucumber. All you need is a single entry point:
72 |
73 | ```clojure
74 | (ns clojure-cukes.test.core
75 | (:use [clojure-cukes.core])
76 | (:use [clojure.test]))
77 |
78 | (deftest run-cukes
79 | (. cucumber.api.cli.Main (main (into-array ["--plugin" "pretty" "--glue" "test/features/step_definitions" "test/features"]))))
80 |
81 | ```
82 |
83 | You then need to add `[com.siili/lein-cucumber "1.0.7"]` to `:plugins` in your project.clj. This allows you to run all Cucumber features with `lein cucumber`
84 |
85 | ### JUnitRunner
86 |
87 | The instructions for the JUnitRunner can be found [here](https://cucumber.io/docs/reference/jvm#junit-runner)
88 |
89 | ## Miscellaneous
90 |
91 | This module needs further documentation. The following examples show supported features:
92 |
93 | * [examples](https://github.com/cucumber/cucumber-jvm-clojure/tree/master/examples/)
94 | * [clojure/src/test/resources/cucumber/runtime/clojure](https://github.com/cucumber/cucumber-jvm-clojure/tree/master/clojure/src/test/resources/cucumber/runtime/clojure).
95 |
96 | Contributions are most welcome.
97 |
--------------------------------------------------------------------------------
/clojure/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/clojure/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 |
5 | io.cucumber
6 | cucumber-jvm-clojure
7 | 2.0.2-SNAPSHOT
8 |
9 |
10 | cucumber-clojure
11 | jar
12 | Cucumber Clojure
13 |
14 |
15 |
16 | io.cucumber
17 | cucumber-core
18 |
19 |
20 | org.clojure
21 | clojure
22 | provided
23 |
24 |
25 | junit
26 | junit
27 | test
28 |
29 |
30 | io.cucumber
31 | cucumber-junit
32 | test
33 |
34 |
35 |
36 |
37 |
38 | com.theoryinpractise
39 | clojure-maven-plugin
40 |
41 |
42 | cucumber.*
43 |
44 | true
45 |
46 |
47 |
48 | compile
49 | compile
50 |
51 | compile
52 |
53 |
54 |
55 | test
56 | test
57 |
58 | test
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | coveralls.io
69 |
70 |
71 |
72 | org.codehaus.mojo
73 | cobertura-maven-plugin
74 | ${cobertura-maven-plugin.version}
75 |
76 | true
77 |
78 |
79 |
80 |
81 | maven-surefire-plugin
82 |
83 | true
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/clojure/src/main/clojure/cucumber/runtime/clj.clj:
--------------------------------------------------------------------------------
1 | (ns cucumber.runtime.clj
2 | (:require (clojure [string :as str]))
3 | (:import (cucumber.runtime CucumberException
4 | JdkPatternArgumentMatcher
5 | StepDefinition
6 | HookDefinition
7 | TagPredicate)
8 | (cucumber.runtime.snippets Snippet
9 | SnippetGenerator)
10 | (clojure.lang RT))
11 | (:gen-class :name cucumber.runtime.clj.Backend
12 | :implements [cucumber.runtime.Backend]
13 | :constructors
14 | {[cucumber.runtime.io.ResourceLoader] []}
15 | :init init
16 | :state state))
17 |
18 | (def glue (atom nil))
19 |
20 | (defn clojure-snippet []
21 | (reify
22 | Snippet
23 | (template [_]
24 | (str
25 | "({0} #\"{1}\" [{3}]\n"
26 | " (comment {4} )\n"
27 | " (throw (cucumber.api.PendingException.)))\n"))
28 | (arguments [_ argumentTypes]
29 | (str/replace (SnippetGenerator/untypedArguments argumentTypes)
30 | "," ""))
31 | (namedGroupStart [_] nil)
32 | (namedGroupEnd [_] nil)
33 | (tableHint [_] nil)
34 | (escapePattern [_ pattern]
35 | (str/replace (str pattern) "\"" "\\\""))))
36 |
37 | (def snippet-generator (SnippetGenerator. (clojure-snippet)))
38 |
39 | (defn load-script [path]
40 | (try
41 | (RT/load (str (.replaceAll path ".clj$" "")) true)
42 | (catch Throwable t
43 | (throw (CucumberException. t)))))
44 |
45 | (defn- -init [resource-loader]
46 | [[] (atom {:resource-loader resource-loader})])
47 |
48 | (defn -loadGlue [cljb a-glue glue-paths]
49 | (reset! glue a-glue)
50 | (doseq [path glue-paths
51 | resource (.resources (:resource-loader @(.state cljb)) path ".clj")]
52 | (binding [*ns* (create-ns 'cucumber.runtime.clj)]
53 | (load-script (.getPath resource)))))
54 |
55 | (defn- -buildWorld [cljb])
56 |
57 | (defn- -disposeWorld [cljb])
58 |
59 | (defn- -getSnippet [cljb step keyword _]
60 | (.getSnippet snippet-generator step keyword nil))
61 |
62 | (defn- -setUnreportedStepExecutor [cljb executor]
63 | "executor")
64 |
65 | (defn- location-str [{:keys [file line]}]
66 | (str file ":" line))
67 |
68 | (defn add-step-definition [pattern fun location]
69 | (.addStepDefinition
70 | @glue
71 | (reify
72 | StepDefinition
73 | (matchedArguments [_ step]
74 | (.argumentsFrom (JdkPatternArgumentMatcher. pattern)
75 | (.getText step)))
76 | (getLocation [_ detail]
77 | (location-str location))
78 | (getParameterCount [_]
79 | nil)
80 | (getParameterType [_ n argumentType]
81 | nil)
82 | (execute [_ locale args]
83 | (apply fun args))
84 | (isDefinedAt [_ stack-trace-element]
85 | (and (= (.getLineNumber stack-trace-element)
86 | (:line location))
87 | (= (.getFileName stack-trace-element)
88 | (:file location))))
89 | (getPattern [_]
90 | (str pattern)))))
91 |
92 | (defmulti add-hook-definition (fn [t & _] t))
93 |
94 | (defmethod add-hook-definition :before [_ tag-expression hook-fun location]
95 | (let [tp (TagPredicate. tag-expression)]
96 | (.addBeforeHook
97 | @glue
98 | (reify
99 | HookDefinition
100 | (getLocation [_ detail?]
101 | (location-str location))
102 | (execute [hd scenario-result]
103 | (hook-fun))
104 | (matches [hd tags]
105 | (.apply tp tags))
106 | (getOrder [hd] 0)
107 | (isScenarioScoped [hd] false)))))
108 |
109 | (defmethod add-hook-definition :after [_ tag-expression hook-fun location]
110 | (let [tp (TagPredicate. tag-expression)
111 | max-parameter-count (->> hook-fun class .getDeclaredMethods
112 | (filter #(= "invoke" (.getName %)))
113 | (map #(count (.getParameterTypes %)))
114 | (apply max))]
115 | (.addAfterHook
116 | @glue
117 | (reify
118 | HookDefinition
119 | (getLocation [_ detail?]
120 | (location-str location))
121 | (execute [hd scenario-result]
122 | (if (zero? max-parameter-count)
123 | (hook-fun)
124 | (hook-fun scenario-result)))
125 | (matches [hd tags]
126 | (.apply tp tags))
127 | (getOrder [hd] 0)
128 | (isScenarioScoped [hd] false)))))
129 |
130 | (defmacro step-macros [& names]
131 | (cons 'do
132 | (for [name names]
133 | `(defmacro ~name [pattern# binding-form# & body#]
134 | `(add-step-definition ~pattern#
135 | (fn ~binding-form# ~@body#)
136 | '~{:file *file*
137 | :line (:line (meta ~'&form))})))))
138 | (step-macros
139 | Given When Then And But)
140 |
141 | (defn- hook-location [file form]
142 | {:file file
143 | :line (:line (meta form))})
144 |
145 | (defmacro Before [tags & body]
146 | `(add-hook-definition :before ~tags (fn [] ~@body) ~(hook-location *file* &form)))
147 |
148 | (defmacro After [tags & body]
149 | `(add-hook-definition :after ~tags (fn [] ~@body) ~(hook-location *file* &form)))
150 |
151 | (defn ^:private update-keys [f m]
152 | (reduce-kv #(assoc %1 (f %2) %3) {} m))
153 |
154 | (defn ^:private update-values [f m]
155 | (reduce-kv #(assoc %1 %2 (f %3)) {} m))
156 |
157 | (defn read-cuke-str
158 | "Using the clojure reader is often a good way to interpret literal values
159 | in feature files. This function makes some cucumber-specific adjustments
160 | to basic reader behavior. This is particulary appropriate when reading a
161 | table, for example: reading | \"1\" | 1 | we should intepret 1 as an int
162 | and \"1\" as a string. This is used by kv-table->map and table->rows."
163 | [string]
164 | (if (re-matches #"^:.*|\d+(\.\d+)?" string)
165 | (read-string string)
166 | (str/replace string #"\"" "")))
167 |
168 | (defn kv-table->map
169 | "Reads a table of the form | key | value |
170 | For example, given:
171 | | from | 1293884100000 |
172 | | to | 1293884100000 |
173 | It evaluates to the clojure literal:
174 | {:from 1293884100000, :to 1293884100000}"
175 | [data]
176 | (->> (into {} (map vec (.raw data)))
177 | (update-values read-cuke-str)
178 | (update-keys keyword)))
179 |
180 | (defn table->rows
181 | "Reads a cucumber table of the form
182 | | key-1 | key-2 | ... | key-n |
183 | | val-1 | val-2 | ... | val-n |
184 | For example, given:
185 | | id | name | created-at |
186 | | 55 | \"foo\" | 1293884100000 |
187 | | 56 | \"bar\" | 1293884100000 |
188 | It evaluates to the clojure literal:
189 | [{:id 55, :name \"foo\", :created-at 1293884100000}
190 | {:id 56, :name \"bar\", :created-at 1293884100000}]"
191 | [data]
192 | (let [data (map seq (.raw data))
193 | header-keys (map keyword (first data))
194 | remove-blank (fn [m,k,v] (if (seq (str v)) (assoc m k v) m))
195 | row->hash (fn [row] (apply hash-map
196 | (interleave header-keys
197 | (map read-cuke-str row))))]
198 | (map (fn [row-vals] (reduce-kv remove-blank {} (row->hash row-vals)))
199 | (next data))))
200 |
--------------------------------------------------------------------------------
/clojure/src/main/java/cucumber/runtime/clojure/Dummy.java:
--------------------------------------------------------------------------------
1 | package cucumber.runtime.clojure;
2 |
3 | // Nothing to see here, just a workaround for https://github.com/cucumber/cucumber-jvm/issues/270
4 | public class Dummy {
5 | }
6 |
--------------------------------------------------------------------------------
/clojure/src/test/java/cucumber/runtime/clojure/ClojureSnippetTest.java:
--------------------------------------------------------------------------------
1 | package cucumber.runtime.clojure;
2 |
3 | import cucumber.runtime.Backend;
4 | import cucumber.runtime.io.ResourceLoader;
5 | import gherkin.pickles.Argument;
6 | import gherkin.pickles.PickleCell;
7 | import gherkin.pickles.PickleLocation;
8 | import gherkin.pickles.PickleRow;
9 | import gherkin.pickles.PickleStep;
10 | import gherkin.pickles.PickleTable;
11 | import org.junit.Test;
12 |
13 | import java.util.Collections;
14 | import java.util.List;
15 |
16 | import static java.util.Arrays.asList;
17 | import static org.junit.Assert.assertEquals;
18 |
19 | public class ClojureSnippetTest {
20 | private static final List NO_ARGUMENTS = Collections.emptyList();
21 | private static final List NO_LOCATIONS = Collections.emptyList();
22 |
23 | @Test
24 | public void generatesPlainSnippet() throws Exception {
25 | PickleStep step = new PickleStep("I have 4 cukes in my \"big\" belly", NO_ARGUMENTS, NO_LOCATIONS);
26 | String snippet = newBackend().getSnippet(step, "Given", null);
27 | String expected = "" +
28 | "(Given #\"^I have (\\d+) cukes in my \\\"([^\\\"]*)\\\" belly$\" [arg1 arg2]\n" +
29 | " (comment Write code here that turns the phrase above into concrete actions )\n" +
30 | " (throw (cucumber.api.PendingException.)))\n";
31 | assertEquals(expected, snippet);
32 | }
33 |
34 | @Test
35 | public void generatesSnippetWithDataTable() throws Exception {
36 | PickleTable dataTable = new PickleTable(asList(new PickleRow(asList(new PickleCell(null, "col1")))));
37 | PickleStep step = new PickleStep("I have:", asList((Argument)dataTable), NO_LOCATIONS);
38 | String snippet = (newBackend()).getSnippet(step, "Given", null);
39 | String expected = "" +
40 | "(Given #\"^I have:$\" [arg1]\n" +
41 | " (comment Write code here that turns the phrase above into concrete actions )\n" +
42 | " (throw (cucumber.api.PendingException.)))\n";
43 | assertEquals(expected, snippet);
44 | }
45 |
46 | private Backend newBackend() throws Exception {
47 | return (Backend) Class.forName("cucumber.runtime.clj.Backend").getConstructor(ResourceLoader.class).newInstance(new Object[]{null});
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/clojure/src/test/java/cucumber/runtime/clojure/RunCukesTest.java:
--------------------------------------------------------------------------------
1 | package cucumber.runtime.clojure;
2 |
3 | import cucumber.api.junit.Cucumber;
4 | import org.junit.runner.RunWith;
5 |
6 | @RunWith(Cucumber.class)
7 | public class RunCukesTest {
8 | }
9 |
--------------------------------------------------------------------------------
/clojure/src/test/resources/cucumber/runtime/clojure/belly.clj:
--------------------------------------------------------------------------------
1 | (ns cucumber.runtime.clojure.belly)
2 |
3 | (def cukes (ref (vector)))
4 |
5 | (defn eat [num]
6 | (dosync (alter cukes conj num)))
7 |
8 | (defn last-meal []
9 | (last @cukes))
10 |
11 |
--------------------------------------------------------------------------------
/clojure/src/test/resources/cucumber/runtime/clojure/cukes.feature:
--------------------------------------------------------------------------------
1 | Feature: Cukes
2 |
3 | Scenario: in the belly
4 | Given I have 4 cukes in my belly
5 | Then there are 4 cukes in my belly
6 |
7 | Scenario: in the belly (list)
8 | Given I have this many cukes in my belly:
9 | | 13 |
10 | Then there are 13 cukes in my belly
11 |
12 | Scenario: unimplemented steps
13 | Given 5 unimplemented step
14 |
15 | @foo
16 | Scenario:
17 | Given I have 4 cukes in my belly
18 |
--------------------------------------------------------------------------------
/clojure/src/test/resources/cucumber/runtime/clojure/stepdefs.clj:
--------------------------------------------------------------------------------
1 | (use 'cucumber.runtime.clojure.belly)
2 |
3 | (def some-state (atom "'Before' hasn't run."))
4 |
5 | (Before []
6 | (reset! some-state "'Before' has run.")
7 | (println "Executing 'Before'."))
8 |
9 | (Before ["@foo"]
10 | (println "Executing 'Tagged Before'"))
11 |
12 | (After []
13 | (println (str "Executing 'After' " @some-state)))
14 |
15 | (Given #"^I have (\d+) cukes in my belly$" [cuke-count]
16 | (eat (Float. cuke-count)))
17 |
18 | (Given #"^I have this many cukes in my belly:$" [cuke-table]
19 | (doseq [x (.raw cuke-table)] (eat (Float. (first x)))))
20 |
21 | (When #"^there are (\d+) cukes in my belly$" [expected]
22 | (assert (= (last-meal) (Float. expected))))
23 |
24 | (Then #"^the (.*) contains (.*)$" [container ingredient]
25 | (assert (= "glass" container)))
26 |
27 | (When #"^I add (.*)$" [liquid]
28 | (assert (= "milk" liquid)))
29 |
30 | (Given #"^(\d+) unimplemented step$" [arg1]
31 | (comment Express the Regexp above with the code you wish you had )
32 | (throw (cucumber.api.PendingException. "This is pending. Seeing a stacktrace here is normal.")))
33 |
34 | (def most-recent (atom nil))
35 |
36 | (Given #"^I have a kv table:$" [data]
37 | (reset! most-recent (kv-table->map data)))
38 |
39 | (Given #"^I have a table with its keys in a header row:$" [data]
40 | (reset! most-recent (table->rows data)))
41 |
42 | (Then #"^the clojure literal equivalent should be:$" [literal-as-string]
43 | (assert (= @most-recent (read-string literal-as-string))))
44 |
--------------------------------------------------------------------------------
/clojure/src/test/resources/cucumber/runtime/clojure/tables.feature:
--------------------------------------------------------------------------------
1 | Feature: tables
2 |
3 | Scenario: a key-value table
4 | Given I have a kv table:
5 | | my-first-key | 1 |
6 | | another-key | "a string" |
7 | | yak | :a-kw |
8 | Then the clojure literal equivalent should be:
9 | """
10 | {:my-first-key 1, :another-key "a string", :yak :a-kw}
11 | """
12 |
13 | Scenario: a table
14 | Given I have a table with its keys in a header row:
15 | | id | name | created-at |
16 | | 55 | "foo" | 1293884100000 |
17 | | 56 | "bar" | 1293884100000 |
18 | Then the clojure literal equivalent should be:
19 | """
20 | [{:id 55, :name "foo", :created-at 1293884100000}
21 | {:id 56, :name "bar", :created-at 1293884100000}]
22 | """
23 |
--------------------------------------------------------------------------------
/examples/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # clojure-cukes
2 |
3 | Just a little example illustrating how to use Cucumber with Clojure and Leiningen.
4 |
5 | Please note that the example uses [lein-cucumber](https://github.com/nilswloka/lein-cucumber), which requires Leiningen 2.
6 |
7 | ## Running cukes
8 |
9 | ```
10 | lein deps
11 | lein cucumber
12 | ```
--------------------------------------------------------------------------------
/examples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | io.cucumber
7 | cucumber-jvm-clojure
8 | 2.0.2-SNAPSHOT
9 |
10 |
11 | clojure-examples
12 | clojure
13 | Cucumber Clojure Examples
14 | A demo of Cucumber with Clojure
15 |
16 | test/java
17 |
18 |
19 | test/features
20 | features
21 |
22 |
23 |
24 |
25 | com.theoryinpractise
26 | clojure-maven-plugin
27 | 1.8.1
28 | true
29 |
30 |
31 | src
32 |
33 |
34 | test/java
35 |
36 |
37 |
38 |
39 | maven-deploy-plugin
40 |
41 | true
42 |
43 |
44 |
45 |
46 |
47 |
48 | org.clojure
49 | clojure
50 |
51 |
52 | io.cucumber
53 | cucumber-clojure
54 | test
55 |
56 |
57 | io.cucumber
58 | cucumber-junit
59 | test
60 |
61 |
62 | junit
63 | junit
64 | test
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/examples/project.clj:
--------------------------------------------------------------------------------
1 | (defproject clojure_cukes "1.0.X"
2 | :description "A demo of Cucumber with Clojure and Leiningen"
3 | :dependencies [[org.clojure/clojure "1.8.0"]]
4 | :plugins [[com.siili/lein-cucumber "1.0.7"]]
5 | :cucumber-feature-paths ["test/features/"]
6 | :profiles
7 | {:dev
8 | {:dependencies [[com.siili/lein-cucumber "1.0.7"]]}}
9 | )
10 |
--------------------------------------------------------------------------------
/examples/src/clojure_cukes/core.clj:
--------------------------------------------------------------------------------
1 | (ns clojure-cukes.core)
2 |
3 | (def belly (atom []))
4 |
5 | (defn mood []
6 | (let [cukes (->> @belly
7 | (filter #(= "cukes" %))
8 | count)]
9 | (cond
10 | (> cukes 3) :happy
11 | (= cukes 2) :meh
12 | (= cukes 1) :sad
13 | :else :hungry)))
14 |
15 | (defn eat [things]
16 | (swap! belly concat things))
17 |
--------------------------------------------------------------------------------
/examples/test/clojure_cukes/test/core.clj:
--------------------------------------------------------------------------------
1 | (ns clojure-cukes.test.core
2 | (:use [clojure-cukes.core])
3 | (:use [clojure.test])
4 | (:use [leiningen.cucumber])
5 | (:import [cucumber.api.cli Main]))
6 |
7 | (deftest run-cukes
8 | (. cucumber.api.cli.Main (main (into-array ["--format" "pretty" "--glue" "test" "test/features"]))))
9 |
--------------------------------------------------------------------------------
/examples/test/features/cukes.feature:
--------------------------------------------------------------------------------
1 | Feature: Cukes
2 | An example of testing Clojure with cucumber. To see a failure try changing
3 | the last 'Then' of 'eat 1 cuke' "meh" to "happy".
4 |
5 | Scenario: in the belly
6 | Given I have 4 big "cukes" in my belly
7 | Then I am "happy"
8 |
9 | Scenario: eat 1 cuke
10 | Given I have 0 big "cukes" in my belly
11 | Then I am "hungry"
12 | When I eat 1 "cukes"
13 | Then I am "sad"
14 | When I eat 1 "cukes"
15 | Then I am "meh"
16 |
--------------------------------------------------------------------------------
/examples/test/features/step_definitions/cuke_steps.clj:
--------------------------------------------------------------------------------
1 | (use 'clojure-cukes.core)
2 | (use 'clojure.test)
3 |
4 | (Given #"^I have (\d+) big \"([^\"]*)\" in my belly$" [n, thing]
5 | (reset! belly (repeat (read-string n) thing)))
6 |
7 | (When #"I eat (\d+) \"([^\"]*)\"" [n, thing]
8 | (eat (repeat (read-string n) thing)))
9 |
10 | (Then #"^I am \"([^\"]*)\"$" [mood-name]
11 | (assert (= (name (mood)) mood-name)))
12 |
--------------------------------------------------------------------------------
/examples/test/java/features/RunCukesTest.java:
--------------------------------------------------------------------------------
1 | package features;
2 |
3 | import cucumber.api.CucumberOptions;
4 | import cucumber.api.junit.Cucumber;
5 | import org.junit.runner.RunWith;
6 |
7 | @RunWith(Cucumber.class)
8 | @CucumberOptions(format = {"pretty", "html:target/cucumber", "rerun:target/rerun.txt"})
9 | public class RunCukesTest {
10 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | io.cucumber
4 | cucumber-jvm-clojure
5 | 2.0.2-SNAPSHOT
6 | pom
7 | Cucumber JVM Clojure
8 | http://cucumber.io/
9 |
10 |
11 | org.sonatype.oss
12 | oss-parent
13 | 7
14 |
15 |
16 |
17 | ${minimum.maven.version}
18 |
19 |
20 |
21 | UTF-8
22 | UTF-8
23 | 3.3
24 | ${project.build.directory}
25 |
26 |
27 | 1.8.0
28 | 2.0.1
29 | 4.12
30 |
31 |
32 |
33 |
34 | MIT License
35 | http://www.opensource.org/licenses/mit-license
36 | repo
37 |
38 |
39 |
40 | scm:git:git://github.com/cucumber/cucumber-jvm.git
41 | scm:git:git@github.com:cucumber/cucumber-jvm.git
42 | git://github.com/cucumber/cucumber-jvm.git
43 | cucumber-jvm-2.0.0
44 |
45 |
46 |
47 |
48 |
49 | org.clojure
50 | clojure
51 | ${clojure.version}
52 |
53 |
54 | io.cucumber
55 | cucumber-clojure
56 | ${project.version}
57 |
58 |
59 | io.cucumber
60 | cucumber-core
61 | ${cucumber.version}
62 |
63 |
64 | io.cucumber
65 | cucumber-junit
66 | ${cucumber.version}
67 |
68 |
69 | junit
70 | junit
71 | ${junit.version}
72 |
73 |
74 |
75 |
76 |
80 |
81 |
82 | sonatype.org
83 | https://oss.sonatype.org/content/repositories/releases
84 |
85 |
86 |
87 |
88 | clojure
89 | examples
90 |
91 |
92 |
93 |
94 | release-sign-artifacts
95 |
96 |
97 | performRelease
98 | true
99 |
100 |
101 |
102 |
103 |
104 | org.apache.maven.plugins
105 | maven-release-plugin
106 |
107 | v@{project.version}
108 |
109 |
110 |
111 |
112 | org.apache.maven.plugins
113 | maven-gpg-plugin
114 |
115 | true
116 |
117 |
118 |
119 | sign-artifacts
120 | verify
121 |
122 | sign
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | travis-disable-deploy-by-default
134 |
135 | false
136 |
137 | env.TRAVIS
138 | true
139 |
140 |
141 |
142 | true
143 |
144 |
145 |
146 | travis-enable-deploy-if-not-pull-request
147 |
148 | false
149 |
150 | env.TRAVIS_PULL_REQUEST
151 | false
152 |
153 |
154 |
155 | false
156 |
157 |
158 |
159 | coveralls.io
160 |
161 |
162 |
163 |
164 | org.codehaus.mojo
165 | cobertura-maven-plugin
166 | ${cobertura-maven-plugin.version}
167 |
168 |
169 | xml
170 |
171 |
172 | true
173 |
174 | true
175 |
176 |
177 |
178 |
179 |
180 | org.eluder.coveralls
181 | coveralls-maven-plugin
182 | 4.3.0
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 | org.apache.maven.plugins
196 | maven-clean-plugin
197 | 3.0.0
198 |
199 |
200 |
201 | .
202 |
203 | **/*.ser
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 | org.apache.maven.plugins
212 | maven-compiler-plugin
213 | 3.6.2
214 |
215 | UTF-8
216 | 1.6
217 | 1.6
218 | -Werror
219 |
220 |
221 |
222 |
223 | org.apache.maven.plugins
224 | maven-gpg-plugin
225 | 1.6
226 |
227 |
228 |
229 | org.apache.maven.plugins
230 | maven-javadoc-plugin
231 | 3.0.0-M1
232 |
233 |
234 | cucumber.runtime,cucumber.runtime.*
235 |
236 | http://docs.oracle.com/javase/7/docs/api/
237 | http://junit.sourceforge.net/javadoc/
238 |
239 |
240 |
241 | Main API Packages
242 | cucumber.api:cucumber.api.*
243 |
244 |
245 | I18n - Java
246 | cucumber.api.java.*
247 |
248 |
249 |
250 | java
251 |
252 |
253 |
254 |
255 | org.apache.maven.plugins
256 | maven-jar-plugin
257 | 3.0.2
258 |
259 |
260 |
261 | org.apache.maven.plugins
262 | maven-project-info-reports-plugin
263 | 2.9
264 |
265 |
266 |
267 | org.apache.maven.plugins
268 | maven-release-plugin
269 | 2.5.3
270 |
271 |
272 |
273 | org.apache.maven.plugins
274 | maven-site-plugin
275 | 3.6
276 |
277 |
278 |
279 | org.apache.maven.plugins
280 | maven-resources-plugin
281 | 3.0.2
282 |
283 |
284 |
285 | org.apache.maven.plugins
286 | maven-source-plugin
287 | 3.0.1
288 |
289 |
290 | bind-sources
291 |
292 | jar
293 |
294 |
295 |
296 |
297 |
298 |
299 | org.apache.maven.plugins
300 | maven-surefire-plugin
301 | 2.20
302 |
303 | -Duser.language=en
304 | -Xmx1024m
305 | -XX:MaxPermSize=256m
306 | -Dfile.encoding=UTF-8
307 | false
308 |
309 |
310 |
311 |
312 |
313 | com.theoryinpractise
314 | clojure-maven-plugin
315 | 1.8.1
316 |
317 |
318 | org.apache.maven.plugins
319 | maven-deploy-plugin
320 | 2.8.2
321 |
322 |
323 | org.apache.maven.plugins
324 | maven-install-plugin
325 | 2.5.2
326 |
327 |
328 | org.apache.maven.plugins
329 | maven-enforcer-plugin
330 | 3.0.0-M1
331 |
332 |
333 |
334 |
335 |
336 |
337 | org.apache.maven.plugins
338 | maven-enforcer-plugin
339 |
340 |
341 | enforce
342 |
343 |
344 |
345 | 1.7.0-9
346 |
347 |
348 | [${minimum.maven.version},)
349 |
350 |
351 | Best Practice is to always define plugin versions!
352 | true
353 | true
354 | true
355 | clean,deploy,site
356 | org.codehaus.mojo
357 |
358 |
359 |
360 | commons-logging
361 |
362 | log4j
363 |
364 |
365 |
366 |
367 |
368 |
369 | enforce
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 | org.apache.maven.wagon
379 | wagon-ssh
380 | 2.10
381 |
382 |
383 |
384 |
385 |
--------------------------------------------------------------------------------