├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.sbt ├── example ├── .idea │ ├── .name │ ├── libraries │ │ ├── SBT__info_cukes_cucumber_html_0_2_6_jar.xml │ │ ├── SBT__io_cucumber_cucumber_core_2_0_0_jar.xml │ │ ├── SBT__io_cucumber_cucumber_junit_2_0_0_jar.xml │ │ ├── SBT__io_cucumber_cucumber_jvm_deps_1_0_6_jar.xml │ │ ├── SBT__io_cucumber_cucumber_scala_2_12_2_0_0_jar.xml │ │ ├── SBT__io_cucumber_gherkin_4_1_3_jar.xml │ │ ├── SBT__io_cucumber_tag_expressions_1_0_1_jar.xml │ │ ├── SBT__junit_junit_4_12_jar.xml │ │ ├── SBT__org_hamcrest_hamcrest_core_1_3_jar.xml │ │ ├── SBT__org_scala_lang_modules_scala_parser_combinators_2_12_1_0_4_jar.xml │ │ ├── SBT__org_scala_lang_modules_scala_xml_2_12_1_0_5_jar.xml │ │ ├── SBT__org_scala_lang_scala_library_2_12_2_jar.xml │ │ ├── SBT__org_scala_lang_scala_reflect_2_12_2_jar.xml │ │ ├── SBT__org_scalactic_scalactic_2_12_3_0_1_jar.xml │ │ └── SBT__org_scalatest_scalatest_2_12_3_0_1_jar.xml │ ├── misc.xml │ ├── modules.xml │ ├── modules │ │ ├── example-build.iml │ │ └── example.iml │ ├── sbt.xml │ ├── scala_compiler.xml │ └── workspace.xml ├── build.sbt ├── project │ ├── build.properties │ └── plugins.sbt └── src │ └── test │ ├── resources │ ├── Multiplication.feature │ └── cucumber.properties │ └── scala │ └── com │ └── waioeka │ └── sbt │ └── MultiplicationSteps.scala ├── project └── build.properties └── src └── main └── scala └── com └── waioeka └── sbt ├── CucumberParameters.scala ├── CucumberPlugin.scala └── Jvm.scala /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | push: 5 | schedule: 6 | # 2am EST every Saturday 7 | - cron: '0 7 * * 6' 8 | jobs: 9 | build_scala2_12: 10 | runs-on: ubuntu-latest 11 | env: 12 | JAVA_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v2 16 | - name: Setup Scala 17 | uses: olafurpg/setup-scala@v13 18 | with: 19 | java-version: "adopt@1.8" 20 | - name: Coursier cache 21 | uses: coursier/cache-action@v6 22 | - name: Build and test 23 | run: | 24 | sbt -v clean +test 25 | rm -rf "$HOME/.ivy2/local" || true 26 | find $HOME/Library/Caches/Coursier/v1 -name "ivydata-*.properties" -delete || true 27 | find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete || true 28 | find $HOME/.cache/coursier/v1 -name "ivydata-*.properties" -delete || true 29 | find $HOME/.sbt -name "ivydata-*.properties" -delete || true 30 | shell: bash 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### PhpStorm ### 4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 5 | 6 | .Ulysses* 7 | 8 | 9 | *.iml 10 | 11 | ## Directory-based project format: 12 | .idea/ 13 | 14 | .idea/scopes/ 15 | .idea/dictionaries/ 16 | .idea/inspectionProfiles/ 17 | .idea/libraries/ 18 | .idea/modules/ 19 | .idea/.name 20 | .idea/*.xml 21 | !.idea/vcs.xml 22 | !.idea/uiDesigner.xml 23 | /classes 24 | /dist 25 | /out 26 | /SDK/*SDK 27 | /target 28 | /*.bat 29 | *.class 30 | out 31 | build 32 | .DS_Store 33 | *~ 34 | target/ 35 | testdata/debugger 36 | 37 | # if you remove the above rule, at least ignore the following: 38 | 39 | # User-specific stuff: 40 | # .idea/workspace.xml 41 | # .idea/tasks.xml 42 | # .idea/dictionaries 43 | 44 | # Sensitive or high-churn files: 45 | # .idea/dataSources.ids 46 | # .idea/dataSources.xml 47 | # .idea/sqlDataSources.xml 48 | # .idea/dynamic.xml 49 | # .idea/uiDesigner.xml 50 | 51 | # Gradle: 52 | # .idea/gradle.xml 53 | # .idea/libraries 54 | 55 | # Mongo Explorer plugin: 56 | # .idea/mongoSettings.xml 57 | 58 | ## File-based project format: 59 | *.ipr 60 | *.iws 61 | 62 | ## Plugin-specific files: 63 | 64 | # IntelliJ 65 | out/ 66 | 67 | # mpeltonen/sbt-idea plugin 68 | .idea_modules/ 69 | 70 | # JIRA plugin 71 | atlassian-ide-plugin.xml 72 | 73 | # Crashlytics plugin (for Android Studio and IntelliJ) 74 | com_crashlytics_export_strings.xml 75 | crashlytics.properties 76 | crashlytics-build.properties 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Standard BSD license: 2 | 3 | Copyright 1994-2004 Michael Lewis lewismj@waioeka.com . All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SBT Cucumber 2 | 3 |

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 | 15 | The Cucumber plugin provides a new sbt command, allowing you to run just your Cucumber tests using `sbt cucumber`. 16 | 17 | The plugin can be used if you want a separate command to run Cucumber tests and have your normal test framework ignore Cucumber tests. 18 | 19 | If you want to run Cucumber tests within a ScalaTest unit test framework see [here](https://github.com/lewismj/cucumber). 20 | 21 | ## Dependency Information 22 | 23 | ```scala 24 | addSbtPlugin("com.waioeka.sbt" % "cucumber-plugin" % "0.3.1") 25 | ``` 26 | 27 | > **Note** The latest version of the plugin is built using SBT 1.2.8. 28 | 29 | ### Cucumber Plugin Example 30 | 31 | The project _cucumber-plugin-example_ highlights how to use the plugin. You will need to ensure that your `build.sbt` file defines both the dependencies and the 'glue' setting (i.e. where to find the step definitions). 32 | 33 | ```scala 34 | name := "cucumber-test" 35 | organization := "com.waioeka.sbt" 36 | version := "0.3.0" 37 | 38 | libraryDependencies ++= Seq ( 39 | "io.cucumber" % "cucumber-core" % "6.10.3" % "test", 40 | "io.cucumber" %% "cucumber-scala" % "6.10.3" % "test", 41 | "io.cucumber" % "cucumber-jvm" % "6.10.3" % "test", 42 | "io.cucumber" % "cucumber-junit" % "6.10.3" % "test", 43 | "org.scalatest" %% "scalatest" % "3.2.8" % "test") 44 | 45 | enablePlugins(CucumberPlugin) 46 | 47 | CucumberPlugin.glues := List("com.waioeka.sbt") 48 | 49 | // Any environment properties you want to override/set. 50 | CucumberPlugin.envProperties := Map("K"->"2049") 51 | ``` 52 | 53 | Remember to set the `CucumberPlugin.glue` parameter to the sub directory in *test* that contains your Scala step definitions. 54 | 55 | In your *resources* directory, put in your feature files. 56 | 57 | ```feature 58 | @my-tag 59 | Feature: Multiplication 60 | In order to avoid making mistakes 61 | As a dummy 62 | I want to multiply numbers 63 | 64 | Scenario: Multiply two variables 65 | Given a variable x with value 2 66 | And a variable y with value 3 67 | When I multiply x * y 68 | Then I get 6 69 | ``` 70 | 71 | If you need to generate the stubs, just run `sbt cucumber` and you will get an error complaining about missing stubs. You can copy and paste the stub functions into your step implementation. 72 | 73 | You can now put in your stub implementation: 74 | 75 | ```scala 76 | package com.waioeka.sbt 77 | 78 | import io.cucumber.scala.{EN, ScalaDsl} 79 | import org.scalatest.Matchers 80 | 81 | /** AddAndMultiplySteps*/ 82 | class MultiplicationSteps extends ScalaDsl with EN with Matchers { 83 | var x : Int = 0 84 | var y : Int = 0 85 | var z : Int = 0 86 | 87 | Given("""^a variable x with value (\d+)$""") { (arg0: Int) => x = arg0 } 88 | 89 | Given("""^a variable y with value (\d+)$""") { (arg0: Int) => y = arg0 } 90 | 91 | When("""^I multiply x \* y$""") { () => z = x * y } 92 | 93 | Then("""^I get (\d+)$""") { (arg0: Int) => z should be (arg0) } 94 | } 95 | ``` 96 | 97 | To run the tests in standalone mode: 98 | 99 | ```shell 100 | sbt compile 101 | sbt cucumber 102 | ``` 103 | 104 | You should see some output as follows: 105 | 106 | ```shell 107 | paeroa:cucumber-test lewismj$ sbt cucumber 108 | [info] Loading project definition from /Users/lewismj/waioeka/upa-plugins/cucumber-test/project 109 | [info] Set current project to cucumber-test (in build file:/Users/lewismj/waioeka/upa-plugins/cucumber-test/) 110 | [info] Feature: Multiplication 111 | [info] In order to avoid making mistakes 112 | [info] As a dummy 113 | [info] I want to multiply numbers 114 | [info] 115 | [info] Scenario: Multiply two variables # Multiplication.feature:6 116 | [info] Given a variable x with value 2 # MultiplicationSteps.scala:17 117 | [info] And a variable y with value 3 # MultiplicationSteps.scala:21 118 | [info] When I multiply x * y # MultiplicationSteps.scala:25 119 | [info] Then I get 6 # MultiplicationSteps.scala:29 120 | [info] 121 | [info] 1 Scenarios (1 passed) 122 | [info] 4 Steps (4 passed) 123 | [info] 0m0.106s 124 | [info] 125 | [success] Total time: 1 s, completed 28-Dec-2015 22:16:19 126 | ``` 127 | 128 | The results will be output in the following formats: 129 | 130 | - cucumber-html, standard Cucumber html output. 131 | - cucumber.json, standard Cucumber json output. 132 | - cucumber-junit-report.xml, a Junit style rest report. 133 | 134 | ## Cucumber Plugin Arguments 135 | 136 | Cucumber arguments may be supplied. For example, `sbt "cucumber --tags ~@my-tag"` will filter tagged feature files. 137 | 138 | ```shell 139 | [success] Total time: 1 s, completed 15-Jun-2016 09:23:22 140 | paeroa:cucumber-plugin-example lewismj$ sbt "cucumber --tags ~@my-tag" 141 | [info] Loading global plugins from /Users/lewismj/.sbt/0.13/plugins 142 | [info] Loading project definition from /Users/lewismj/github/cucumber/cucumber-plugin-example/project 143 | [info] Set current project to cucumber-test (in build file:/Users/lewismj/github/cucumber/cucumber-plugin-example/) 144 | ** hello ** 145 | [info] None of the features at [classpath:] matched the filters: [~@my-tag] 146 | [info] 147 | [info] 0 Scenarios 148 | [info] 0 Steps 149 | [info] 0m0.000s 150 | [info] 151 | ** goodbye ** 152 | [success] Total time: 1 s, completed 15-Jun-2016 09:23:41 153 | ``` 154 | 155 | ## Properties 156 | 157 | In your `build.sbt` file you can now specify environment variables as follows: 158 | 159 | ```scala 160 | CucumberPlugin.envProperties := Map("K"->"2049") 161 | ``` 162 | 163 | The setting expects a type of `Map[String,String]`. 164 | 165 | ## Changelog 166 | 167 | | Version | Summary | 168 | |---------|---------------------------------------------------------------------------------------------------------------------------------------------------| 169 | | 0.3.0 | The plugin now uses Cucumber 6.10.3 | 170 | | 0.2.0 | Please note this [change](https://github.com/sbt/sbt-cucumber/pull/4/files) was merged in, to make the glue parameter a List, rather than String. | 171 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | import sbt.{Credentials, ScmInfo} 2 | 3 | val Scala10x = "2.10.7" 4 | val Scala12x = "2.12.10" 5 | 6 | ThisBuild / version := "0.3.1" 7 | ThisBuild / scalaVersion := Scala12x 8 | ThisBuild / organization := "com.waioeka.sbt" 9 | 10 | // cucumber-scala 6.10.3 doesn't exist for Scala 2.10 11 | ThisBuild / crossScalaVersions := Seq(Scala12x) 12 | 13 | lazy val credentialSettings = Seq( 14 | credentials ++= (for { 15 | username <- Option(System.getenv().get("SONATYPE_USERNAME")) 16 | password <- Option(System.getenv().get("SONATYPE_PASSWORD")) 17 | } yield Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", username, password)).toSeq 18 | ) 19 | 20 | lazy val publishSettings = Seq( 21 | publishMavenStyle := true, 22 | publishArtifact in Test := false, 23 | pomIncludeRepository := Function.const(false), 24 | publishTo := { 25 | val nexus = "https://oss.sonatype.org/" 26 | if (isSnapshot.value) 27 | Some("Snapshots" at nexus + "content/repositories/snapshots") 28 | else 29 | Some("Releases" at nexus + "service/local/staging/deploy/maven2") 30 | }, 31 | homepage := Some(url("https://github.com/lewismj/kea")), 32 | licenses := Seq("BSD-style" -> url("http://www.opensource.org/licenses/bsd-license.php")), 33 | scmInfo := Some(ScmInfo(url("https://github.com/lewismj/kea"), "scm:git:git@github.com:lewismj/kea.git")), 34 | autoAPIMappings := true, 35 | pomExtra := ( 36 | 37 | 38 | Michael Lewis 39 | @lewismj 40 | 41 | 42 | ) 43 | ) ++ credentialSettings 44 | 45 | lazy val commonSettings = Seq( 46 | scalacOptions += "-target:jvm-1.8", 47 | libraryDependencies ++= Seq ( 48 | "io.cucumber" % "cucumber-core" % "6.10.3", 49 | "io.cucumber" %% "cucumber-scala" % "6.10.3", 50 | "io.cucumber" % "cucumber-jvm" % "6.10.3" pomOnly(), 51 | "io.cucumber" % "cucumber-junit" % "6.10.3", 52 | "org.apache.commons" % "commons-lang3" % "3.9", 53 | "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2", 54 | "org.scala-lang.modules" %% "scala-xml" % "1.2.0"), 55 | fork in test := true, 56 | // This cross builds on sbt using Scala version 57 | pluginCrossBuild / sbtVersion := { 58 | scalaBinaryVersion.value match { 59 | case "2.10" => "0.13.18" 60 | case "2.12" => "1.2.8" 61 | } 62 | }, 63 | ) 64 | 65 | lazy val pluginSettings = buildSettings ++ commonSettings 66 | 67 | lazy val plugin = project.in(file(".")) 68 | .enablePlugins(SbtPlugin) 69 | .settings( 70 | name := "cucumber-plugin", 71 | moduleName := "cucumber-plugin", 72 | ) 73 | .settings(pluginSettings:_*) 74 | .settings(publishSettings:_*) 75 | -------------------------------------------------------------------------------- /example/.idea/.name: -------------------------------------------------------------------------------- 1 | cucumber-test -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__info_cukes_cucumber_html_0_2_6_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__io_cucumber_cucumber_core_2_0_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__io_cucumber_cucumber_junit_2_0_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__io_cucumber_cucumber_jvm_deps_1_0_6_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__io_cucumber_cucumber_scala_2_12_2_0_0_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__io_cucumber_gherkin_4_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__io_cucumber_tag_expressions_1_0_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__junit_junit_4_12_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__org_hamcrest_hamcrest_core_1_3_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__org_scala_lang_modules_scala_parser_combinators_2_12_1_0_4_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__org_scala_lang_modules_scala_xml_2_12_1_0_5_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__org_scala_lang_scala_library_2_12_2_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__org_scala_lang_scala_reflect_2_12_2_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__org_scalactic_scalactic_2_12_3_0_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/libraries/SBT__org_scalatest_scalatest_2_12_3_0_1_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /example/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/.idea/modules/example-build.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /example/.idea/modules/example.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /example/.idea/sbt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /example/.idea/scala_compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /example/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 49 | true 50 | DEFINITION_ORDER 51 | 52 | 53 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |