| @@ -0,0 +1,3 @@ | |||||
| .github | |||||
| /examples | |||||
| /spec | |||||
| @@ -0,0 +1,32 @@ | |||||
| # Set the default behavior, in case people don't have core.autocrlf set. | |||||
| * text eol=lf | |||||
| # Explicitly declare text files to always be normalized and converted | |||||
| # to native line endings on checkout. | |||||
| *.css text eol=lf | |||||
| *.feature text eol=lf | |||||
| *.gemspec text eol=lf | |||||
| *.js text eol=lf | |||||
| *.md text eol=lf | |||||
| *.rake text eol=lf | |||||
| *.rb text eol=lf | |||||
| *.sass text eol=lf | |||||
| *.tcl text eol=lf | |||||
| *.textile text eol=lf | |||||
| *.txt text eol=lf | |||||
| *.xml text eol=lf | |||||
| *.yml text eol=lf | |||||
| Gemfile text eol=lf | |||||
| LICENSE text eol=lf | |||||
| Rakefile text eol=lf | |||||
| .cucumberproignore text eol=lf | |||||
| .gitignore text eol=lf | |||||
| .rspec text eol=lf | |||||
| .ruby-gemset text eol=lf | |||||
| .yardopts text eol=lf | |||||
| scripts/* text eol=lf | |||||
| # Denote all files that are truly binary and should not be modified. | |||||
| # These patterns are here as an example; we have 0 of these. | |||||
| *.png binary | |||||
| *.jpg binary | |||||
| @@ -0,0 +1,37 @@ | |||||
| .bundle | |||||
| nbproject | |||||
| coverage | |||||
| pkg | |||||
| doc | |||||
| tmp | |||||
| .yardoc | |||||
| *.log | |||||
| *.pid | |||||
| .eprj | |||||
| .tmtags | |||||
| *~ | |||||
| .DS_Store | |||||
| *.swp | |||||
| *.swo | |||||
| target | |||||
| *.tmproj | |||||
| .#* | |||||
| .idea | |||||
| .vscode | |||||
| *.pyc | |||||
| *.rbc | |||||
| rerun.txt | |||||
| ._* | |||||
| .rvmrc | |||||
| .sass-cache | |||||
| doc/ | |||||
| *.tgz | |||||
| tags | |||||
| .ruby-version | |||||
| .project | |||||
| Gemfile.local | |||||
| Gemfile.local.lock | |||||
| .envrc | |||||
| Gemfile.lock | |||||
| bin/json-formatter | |||||
| acceptance/* | |||||
| @@ -0,0 +1,2 @@ | |||||
| --color | |||||
| --tag "~cck" | |||||
| @@ -0,0 +1,158 @@ | |||||
| inherit_from: .rubocop_todo.yml | |||||
| require: | |||||
| - rubocop-packaging | |||||
| AllCops: | |||||
| NewCops: disable | |||||
| # Keep this inline with the lowest ruby-* version in circleci/config.yml and | |||||
| # the version in the gemspec | |||||
| TargetRubyVersion: 2.6 | |||||
| # Cop names are not displayed in offense messages by default. Change behavior | |||||
| # by overriding DisplayCopNames, or by giving the `-D/--display-cop-names` | |||||
| # option. | |||||
| DisplayCopNames: true | |||||
| # Style guide URLs are not displayed in offense messages by default. Change | |||||
| # behavior by overriding `DisplayStyleGuide`, or by giving the | |||||
| # `-S/--display-style-guide` option. | |||||
| DisplayStyleGuide: true | |||||
| Exclude: | |||||
| - 'bin/*' | |||||
| - 'tmp/**/*' | |||||
| - 'vendor/**/*' | |||||
| - 'temp_app/**/*' | |||||
| - 'cck/features/**/*' | |||||
| Layout/EndOfLine: | |||||
| EnforcedStyle: lf | |||||
| # Disabling this cop until the minimum Ruby version is >= 2.3 as squiggly | |||||
| # heredocs '<<~' were introduced then. The files below are the current ones | |||||
| # with offenses | |||||
| Layout/HeredocIndentation: | |||||
| Exclude: | |||||
| - 'features/lib/support/feature_factory.rb' | |||||
| - 'lib/cucumber/cli/options.rb' | |||||
| - 'lib/cucumber/cli/profile_loader.rb' | |||||
| - 'spec/cucumber/cli/configuration_spec.rb' | |||||
| - 'spec/cucumber/cli/profile_loader_spec.rb' | |||||
| - 'spec/cucumber/formatter/pretty_spec.rb' | |||||
| # Reviewed: Formatters put trailing spaces after things like 'Feature: ' | |||||
| # In pretty_spec.rb, progress_spec.rb offences look false, | |||||
| # as the trailing spaces are in multiline string literals | |||||
| Layout/TrailingWhitespace: | |||||
| Exclude: | |||||
| - 'spec/cucumber/formatter/pretty_spec.rb' | |||||
| - 'spec/cucumber/formatter/progress_spec.rb' | |||||
| # Reviewed: please see PR-1022 for details on why this cop is disabled: | |||||
| # https://github.com/cucumber/cucumber-ruby/pull/1022 | |||||
| Lint/AmbiguousOperator: | |||||
| Enabled: false | |||||
| # We exclude proto_world for documentation (rdoc) purpose | |||||
| Lint/UselessMethodDefinition: | |||||
| Enabled: true | |||||
| Exclude: | |||||
| - 'lib/cucumber/glue/proto_world.rb' | |||||
| Metrics/AbcSize: | |||||
| Max: 45 | |||||
| Metrics/BlockLength: | |||||
| CountComments: false | |||||
| Exclude: | |||||
| - './cucumber.gemspec' | |||||
| - './spec/**/*' | |||||
| - 'cck/spec/**/*' | |||||
| Metrics/ClassLength: | |||||
| Max: 375 | |||||
| Exclude: | |||||
| - 'lib/cucumber/cli/options.rb' | |||||
| Metrics/CyclomaticComplexity: | |||||
| Max: 12 | |||||
| # A line length of 200 covers most violations in the repo while still being | |||||
| # a more up to date length given today's screen sizes | |||||
| Layout/LineLength: | |||||
| Max: 200 | |||||
| Metrics/ModuleLength: | |||||
| Max: 150 | |||||
| Exclude: | |||||
| - './spec/**/*' | |||||
| - 'cck/spec/**/*' | |||||
| Metrics/MethodLength: | |||||
| Max: 30 | |||||
| Metrics/PerceivedComplexity: | |||||
| Max: 13 | |||||
| # Rubocop doesn't like method names in other languages but as Cucumber supports | |||||
| # languages, this cop needs to be disabled. | |||||
| Naming/AsciiIdentifiers: | |||||
| Enabled: false | |||||
| # For the most part, the project is solid on naming. There are though, a few | |||||
| # cases where the cop doesn't need to catch. | |||||
| Naming/MethodName: | |||||
| EnforcedStyle: snake_case | |||||
| Enabled: true | |||||
| Exclude: | |||||
| - 'examples/i18n/ar/lib/calculator.rb' | |||||
| - 'examples/i18n/he/lib/calculator.rb' | |||||
| - 'examples/i18n/he/lib/calculator.rb' | |||||
| - 'examples/i18n/tr/lib/hesap_makinesi.rb' | |||||
| - 'lib/cucumber/glue/dsl.rb' | |||||
| # In most cases, being descriptive with parameter names helps a reader understand | |||||
| # what the variable is for. In some cases, shorter names are sufficient. | |||||
| Naming/MethodParameterName: | |||||
| AllowedNames: _, e, n, v, id, io, gh, pr | |||||
| # Reviewed: these offenses look false as the variables are in cyrillic | |||||
| Naming/VariableName: | |||||
| Exclude: | |||||
| - 'examples/i18n/ru/features/step_definitions/calculator_steps.rb' | |||||
| - 'examples/i18n/uk/features/step_definitions/calculator_steps.rb' | |||||
| - 'examples/i18n/uz/features/step_definitions/calculator_steps.rb' | |||||
| # Rubocop doesn't handle some international words well for this cop | |||||
| Naming/VariableNumber: | |||||
| EnforcedStyle: normalcase | |||||
| Exclude: | |||||
| - 'examples/i18n/**/*' | |||||
| # This cop throws errors when parsing a lot of the repo's code, possibly due | |||||
| # to splat issues? | |||||
| Style/AccessModifierDeclarations: | |||||
| Enabled: false | |||||
| Style/ClassAndModuleChildren: | |||||
| Enabled: false | |||||
| Style/ClassEqualityComparison: | |||||
| Enabled: true | |||||
| Style/Documentation: | |||||
| Enabled: false | |||||
| Style/FormatStringToken: | |||||
| EnforcedStyle: annotated | |||||
| Style/FloatDivision: | |||||
| Enabled: false | |||||
| Style/StderrPuts: | |||||
| Enabled: false | |||||
| Style/RegexpLiteral: | |||||
| EnforcedStyle: slashes | |||||
| AllowInnerSlashes: true | |||||
| Style/YodaCondition: | |||||
| Enabled: true | |||||
| @@ -0,0 +1,89 @@ | |||||
| # This configuration was generated by | |||||
| # `rubocop --auto-gen-config` | |||||
| # on 2020-08-23 16:54:14 UTC using RuboCop version 0.89.1. | |||||
| # The point is for the user to remove these configuration records | |||||
| # one by one as the offenses are removed from the code base. | |||||
| # Note that changes in the inspected code, or installation of new | |||||
| # versions of RuboCop, may require this file to be generated again. | |||||
| # Offense count: 38 | |||||
| # Cop supports --auto-correct. | |||||
| # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. | |||||
| # SupportedHashRocketStyles: key, separator, table | |||||
| # SupportedColonStyles: key, separator, table | |||||
| # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit | |||||
| Layout/HashAlignment: | |||||
| Exclude: | |||||
| - 'cucumber.gemspec' | |||||
| - 'lib/cucumber/cli/options.rb' | |||||
| - 'lib/cucumber/formatter/ansicolor.rb' | |||||
| - 'lib/cucumber/gherkin/formatter/ansi_escapes.rb' | |||||
| # Offense count: 5 | |||||
| # Cop supports --auto-correct. | |||||
| Lint/RedundantCopDisableDirective: | |||||
| Exclude: | |||||
| - 'lib/cucumber/errors.rb' | |||||
| - 'lib/cucumber/glue/proto_world.rb' | |||||
| - 'lib/cucumber/glue/registry_and_more.rb' | |||||
| - 'lib/cucumber/glue/snippet.rb' | |||||
| # Offense count: 1 | |||||
| # Configuration parameters: AllowComments. | |||||
| Lint/SuppressedException: | |||||
| Exclude: | |||||
| - 'lib/cucumber/rake/task.rb' | |||||
| # Offense count: 1 | |||||
| # Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, Regex, IgnoreExecutableScripts, AllowedAcronyms. | |||||
| # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS | |||||
| Naming/FileName: | |||||
| Exclude: | |||||
| - 'features/lib/step_definitions/iso-8859-1_steps.rb' | |||||
| # Offense count: 197 | |||||
| # Cop supports --auto-correct. | |||||
| # Configuration parameters: EnforcedStyle. | |||||
| # SupportedStyles: always, always_true, never | |||||
| Style/FrozenStringLiteralComment: | |||||
| Enabled: false | |||||
| # Offense count: 5 | |||||
| # Cop supports --auto-correct. | |||||
| # Configuration parameters: EnforcedStyle. | |||||
| # SupportedStyles: literals, strict | |||||
| Style/MutableConstant: | |||||
| Exclude: | |||||
| - 'lib/cucumber/cli/options.rb' | |||||
| - 'lib/cucumber/file_specs.rb' | |||||
| - 'lib/cucumber/runtime.rb' | |||||
| - 'lib/cucumber/term/ansicolor.rb' | |||||
| # Offense count: 5 | |||||
| # Cop supports --auto-correct. | |||||
| # Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. | |||||
| # SupportedStyles: predicate, comparison | |||||
| Style/NumericPredicate: | |||||
| Exclude: | |||||
| - 'spec/**/*' | |||||
| - 'lib/cucumber/formatter/console.rb' | |||||
| - 'lib/cucumber/formatter/console_counts.rb' | |||||
| - 'lib/cucumber/glue/invoke_in_world.rb' | |||||
| - 'lib/cucumber/runtime.rb' | |||||
| # Offense count: 10 | |||||
| # Cop supports --auto-correct. | |||||
| Style/RedundantFreeze: | |||||
| Exclude: | |||||
| - 'lib/cucumber/cli/options.rb' | |||||
| - 'lib/cucumber/formatter/unicode.rb' | |||||
| - 'spec/cucumber/step_match_spec.rb' | |||||
| # Offense count: 2 | |||||
| # Cop supports --auto-correct. | |||||
| # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods. | |||||
| # AllowedMethods: present?, blank?, presence, try, try! | |||||
| Style/SafeNavigation: | |||||
| Exclude: | |||||
| - 'lib/cucumber/formatter/ansicolor.rb' | |||||
| - 'lib/cucumber/gherkin/formatter/ansi_escapes.rb' | |||||
| @@ -0,0 +1 @@ | |||||
| cucumber | |||||
| @@ -0,0 +1,246 @@ | |||||
| # Contributing to Cucumber | |||||
| Thank you for considering contributing to Cucumber! | |||||
| This document will first introduce different ways to get involved before | |||||
| focusing on how to contribute to the code. | |||||
| ## Code of Conduct | |||||
| Everyone interacting in this codebase and issue tracker is expected to follow | |||||
| the Cucumber [code of conduct](https://cucumber.io/conduct). | |||||
| ## How can I contribute? | |||||
| If you're reading this, you are certainly looking to contribute to the code. Cucumber | |||||
| is not this single repository. It is made up of several packages around several | |||||
| repositories. So before going further with the code, you may consider the | |||||
| following first, in order to get your bearings. | |||||
| If you just want to know how to contribute to the code, go to | |||||
| [Contribute to the code](#contribute-to-the-code). | |||||
| If you want to report an issue, or suggest an enhancement, go to | |||||
| [Report bugs and submit feature requests](#report-bugs-and-submit-feature-requests). | |||||
| ### Meet the community, the maintainers, and other Cucumber developers | |||||
| Smartbear hosts a [community message board]. | |||||
| This is a good place to meet users, the community, and to ask questions. | |||||
| You can also join the Cucumber Community Slack: | |||||
| [register for an account][register-slack] then head over to [#intro][slack-intro]. | |||||
| This is the place to be to meet other contributors and find a mentor to help you | |||||
| get started. | |||||
| ### Test Cucumber | |||||
| Testing Cucumber, especially new features, is a great way to contribute. We | |||||
| cannot put a price on (early) feedback. | |||||
| Keep an eye on our CHANGELOGS to discover new features. Test and experiment, and | |||||
| submit your feedback through [issues](#report-bugs-and-submit-feature-requests), | |||||
| the [community message board], or [Slack][community-slack]. | |||||
| ### Contribute to the documentation | |||||
| [The documentation][cucumber-docs] is an important part of Cucumber. It is | |||||
| essential that it remains simple and accurate. You can contribute to it via | |||||
| [github.com/cucumber/docs](https://github.com/cucumber/docs). | |||||
| ### Promote Cucumber | |||||
| You don't know how to contribute but would like to help? Telling other people | |||||
| about Cucumber on the Internet - social media, reviews, blogs - but also in real | |||||
| life is already a big help! Join us on [Slack][community-slack] to share your | |||||
| publication and to discover new ones. | |||||
| ## Report bugs and submit feature requests | |||||
| The short version is: | |||||
| - Find the appropriate repository | |||||
| - Try to check there is not already an issue or pull request that deals with | |||||
| your bug or request | |||||
| - Explain your issue and include as much details as possible to help other | |||||
| people reproduce your problem or understand your request | |||||
| - Consider submitting a pull request if you feel confident enough | |||||
| You can find more details for each of these steps in the following sections. | |||||
| ### Find the appropriate repository | |||||
| The current repository, `cucumber-ruby`, is actually the tip of the iceberg. It | |||||
| provides a user interface through a CLI, some built-in formatters, and the | |||||
| execution environment you may know as the `World` object. | |||||
| An important repository is [cucumber/common]. It is a mono-repo | |||||
| with a lot of libraries. You will find there what is related to: | |||||
| - parsing Gherkin documents - aka `.feature` files | |||||
| - parsing tag expressions - the options you use to filter an execution with tags | |||||
| - parsing Cucumber expressions - the expressions that link a Gherkin step to a | |||||
| step definition | |||||
| - everyting related to the HTML formatter | |||||
| `cucumber-ruby` is also composed of [cucumber-ruby-core]: this is the engine that | |||||
| will execute the test cases computed from a parsed Gherkin document | |||||
| Last but not least, there is also a repository for [cucumber-rails], the gem | |||||
| that brings Cucumber to Rails 5.x and 6.x. | |||||
| In any case, if your are not sure, best places to open an issue are the current | |||||
| repository - `cucumber-ruby` - and the mono-repo at [cucumber/common]. | |||||
| ### Look for existing issues and pull requests | |||||
| Search in [the current repository][cucumber-ruby-issues], in the | |||||
| [mono-repo][cucumber/common-issues], but also in the | |||||
| [whole cucumber organization][cucumber-issues] if the problem or feature has already | |||||
| been reported. If you find an issue or pull request which is still open, add | |||||
| comments to it instead of opening a new one. | |||||
| If you're not sure, don't hesitate to just open a new issue. We can always merge | |||||
| and de-duplicate later. | |||||
| ### Submitting a pull request | |||||
| When submitting a pull request: | |||||
| - create a [draft pull request][how-to-create-a-draft-pr] | |||||
| - try to follow the instructions in the [template](.github/PULL_REQUEST_TEMPLATE.md) | |||||
| - if possible, [sign your commits] | |||||
| - update CHANGELOG.md with your changes | |||||
| - once the PR is ready, request for reviews | |||||
| More info on [how to contribute to the code](#contribute-to-the-code) can be | |||||
| found below. | |||||
| ### Opening a new issue | |||||
| To open a good issue, be clear and precise. | |||||
| If you report a problem, the reader must be able to reproduce it easily. | |||||
| Please do your best to create a [minimal, reproducible example][minimal-reproducible-example]. | |||||
| Consider submitting a pull request. Even if you think you cannot fix it by | |||||
| yourself, a pull request with a failing test is always welcome. | |||||
| If you request is for an enhancement - a new feature - try to be specific and | |||||
| support your request with referenced facts and include examples to illustrate | |||||
| your proposal. | |||||
| ## Contribute to the code | |||||
| ### Development environment | |||||
| Development environment for `cucumber-ruby` is a simple Ruby environment with | |||||
| Bundler. Use a [supported Ruby version](./README.md#supported-platforms), make | |||||
| sure [Bundler] is set-up, and voilà! | |||||
| You can then [fork][how-to-fork] and clone the repository. If your environment | |||||
| is set-up properly, the following commands should install the dependencies and | |||||
| execute all the tests successfully. | |||||
| ```shell | |||||
| bundle install | |||||
| bundle exec rake | |||||
| ``` | |||||
| You can now create a branch for your changes and [submit a pull request](#submitting-a-pull-request)! | |||||
| If you want to check the code coverage during your development, execute | |||||
| `bundle exec rake cov`. | |||||
| ### Cucumber-ruby-core | |||||
| As seen here: [Find the appropriate repository](#find-the-appropriate-repository), | |||||
| you may need to work with other repositories in order to accomplish your | |||||
| development. Beside the mono-repo in [cucumber/common], [cucumber-ruby-core] is | |||||
| also a big piece of `cucumber-ruby`. | |||||
| ### Using a local Gemfile | |||||
| A local Gemfile allows you to use your prefer set of gems for your own | |||||
| development workflow, like gems dedicated to debugging. Such gems are not part | |||||
| of `cucumber-ruby` standard `Gemfile`. | |||||
| `Gemfile.local`, `Gemfile.local.lock` and `.bundle` have been added to | |||||
| `.gitignore` so local changes cannot be accidentaly commited and pushed to the | |||||
| repository. | |||||
| A `Gemfile.local` may look like this: | |||||
| ```ruby | |||||
| # Gemfile.local | |||||
| # Include the regular Gemfile | |||||
| eval File.read('Gemfile') | |||||
| # Include your favorites development gems | |||||
| group :development do | |||||
| gem 'byebug' | |||||
| gem 'pry' | |||||
| gem 'pry-byebug' | |||||
| gem 'debase', require: false | |||||
| gem 'ruby-debug-ide', require: false | |||||
| end | |||||
| ``` | |||||
| Then you can execute bundler with the `--gemfile` flag: | |||||
| `bundle install --gemfile Gemfile.local`, or with an environment variable: | |||||
| `BUNDLE_GEMFILE=Gemfile.local bundle [COMMAND]`. | |||||
| To use your local Gemfile per default, you can also execute | |||||
| `bundle config set --local gemfile Gemfile.local`. | |||||
| ### First timer? Welcome! | |||||
| Looking for something simple to begin with? Look at issues with the label | |||||
| '[good first issue](https://github.com/cucumber/cucumber-ruby/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)'. | |||||
| Remember: Cucumber is more than `cucumber-ruby`. You can look for good first | |||||
| issues in [other cucumber reporistories](#find-the-appropriate-repository). | |||||
| ### Having trouble getting started with the code? We're here to help! | |||||
| If you have trouble setting-up your development environment, or getting started | |||||
| with the code, you can join us on [Slack][community-slack]. You will find there | |||||
| a lot of contributors. | |||||
| Full-time maintainers are also available. We would be please to have 1:1 pairing | |||||
| sessions to help you getting started. Look for | |||||
| [Matt Wynne](https://cucumberbdd.slack.com/team/U590XDLF3) or | |||||
| [Aurélien Reeves](https://cucumberbdd.slack.com/team/U011BB95MC7) on | |||||
| [Slack][community-slack]. | |||||
| ### Additional documentation and notice | |||||
| You can find additional documentation in the [docs](./docs) directory such as | |||||
| (non-exhaustive list): | |||||
| - [How to release cucumber-ruby](./docs/RELEASE_PROCESS.md) (for maintainers) | |||||
| - [How to set-up a launch.json configuration for Visual Studio Code](./docs/vscode-example-launch-configuration.md) | |||||
| <!-- Links --> | |||||
| [community message board]: https://community.smartbear.com/t5/Cucumber-Open/bd-p/CucumberOS | |||||
| [register-slack]: https://cucumberbdd-slack-invite.herokuapp.com/ | |||||
| [slack-intro]: https://cucumberbdd.slack.com/messages/C5WD8SA21/ | |||||
| [community-slack]: https://cucumberbdd.slack.com/ | |||||
| [cucumber-docs]: https://cucumber.io/docs/cucumber | |||||
| [cucumber/common]: https://github.com/cucumber/common | |||||
| [cucumber-ruby-core]: https://github.com/cucumber/cucumber-ruby-core | |||||
| [cucumber-rails]: https://github.com/cucumber/cucumber-rails | |||||
| [cucumber-ruby-issues]: https://github.com/cucumber/cucumber-ruby/search?q=is%3Aissue | |||||
| [cucumber/common-issues]: https://github.com/cucumber/common/search?q=is%3Aissue | |||||
| [cucumber-issues]: https://github.com/search?q=is%3Aissue+user%3Acucumber | |||||
| [how-to-create-a-draft-pr]: https://docs.github.com/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests | |||||
| [how-to-fork]: https://docs.github.com/github/collaborating-with-pull-requests/working-with-forks/about-forks | |||||
| [sign your commits]: https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification/signing-commits | |||||
| [minimal-reproducible-example]: https://stackoverflow.com/help/minimal-reproducible-example | |||||
| [RVM]: https://rvm.io/ | |||||
| [rbenv]: https://github.com/rbenv/rbenv | |||||
| [Bundler]: https://bundler.io/ | |||||
| @@ -0,0 +1,15 @@ | |||||
| source 'https://rubygems.org' | |||||
| git_source(:github) { |repo| "https://github.com/#{repo}.git" } | |||||
| gemspec | |||||
| gem 'rubocop', '1.43.0' | |||||
| gem 'rubocop-packaging', '0.5.2' | |||||
| # To hack on Cucumber together with any of these libraries, uncomment the line below: | |||||
| # gem 'cucumber-core', path: '../cucumber-ruby-core' | |||||
| # gem 'cucumber-cucumber-expressions', path: '../cucumber-expressions/ruby' | |||||
| # gem 'cucumber-gherkin', path: '../common/gherkin/ruby' | |||||
| # gem 'cucumber-html-formatter', path: '../html-formatter/ruby' | |||||
| # gem 'cucumber-messages', path: '../common/messages/ruby' | |||||
| @@ -0,0 +1,22 @@ | |||||
| The MIT License | |||||
| Copyright (c) Aslak Hellesøy | |||||
| Permission is hereby granted, free of charge, to any person obtaining | |||||
| a copy of this software and associated documentation files (the | |||||
| "Software"), to deal in the Software without restriction, including | |||||
| without limitation the rights to use, copy, modify, merge, publish, | |||||
| distribute, sublicense, and/or sell copies of the Software, and to | |||||
| permit persons to whom the Software is furnished to do so, subject to | |||||
| the following conditions: | |||||
| The above copyright notice and this permission notice shall be | |||||
| included in all copies or substantial portions of the Software. | |||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
| @@ -0,0 +1,62 @@ | |||||
| MONOREPO_PATH ?= ../../cucumber | |||||
| # https://stackoverflow.com/questions/2483182/recursive-wildcards-in-gnu-make | |||||
| rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) | |||||
| RUBY_FILES=$(call rwildcard,../lib ../../cucumber-ruby-core/lib/,*.rb) | |||||
| FEATURES = $(sort $(wildcard features/docs/**.feature)) | |||||
| GOLDEN_JSONS = $(patsubst features/docs/%.feature,acceptance/%-golden.json,$(FEATURES)) | |||||
| GENERATED_JSONS = $(patsubst features/docs/%.feature,acceptance/%-generated.json,$(FEATURES)) | |||||
| TESTED = $(patsubst features/docs/%.feature,acceptance/%.tested,$(FEATURES)) | |||||
| OS := $(shell [[ "$$(uname)" == "Darwin" ]] && echo "darwin" || echo "linux") | |||||
| # Determine if we're on 386 or amd64 (ignoring other processors as we're not building on them) | |||||
| ARCH := $(shell [[ "$$(uname -m)" == "x86_64" ]] && echo "amd64" || echo "386") | |||||
| default: $(GOLDEN_JSONS) $(GENERATED_JSONS) $(TESTED) | |||||
| .PHONY: default | |||||
| acceptance/%.tested: acceptance/%-golden.json acceptance/%-generated.json | |||||
| mkdir -p $$(dirname $@) | |||||
| diff --unified $^ | |||||
| .PHONY: acceptance/%.tested | |||||
| acceptance/%-golden.json: features/docs/%.feature $(MONOREPO_PATH)/compatibility-kit/ruby/scripts/neutralize-json $(RUBY_FILES) | |||||
| mkdir -p $$(dirname $@) | |||||
| bundle exec cucumber --format=json $< | \ | |||||
| jq --sort-keys "." | \ | |||||
| $(MONOREPO_PATH)/compatibility-kit/ruby/scripts/neutralize-json > $@ | |||||
| acceptance/%-generated.json: features/docs/%.feature $(RUBY_FILES) bin/json-formatter $(MONOREPO_PATH)/compatibility-kit/ruby/scripts/neutralize-json | |||||
| mkdir -p $$(dirname $@) | |||||
| bundle exec cucumber --format=message $< | \ | |||||
| bin/json-formatter --format ndjson | \ | |||||
| jq --sort-keys "." | \ | |||||
| $(MONOREPO_PATH)/compatibility-kit/ruby/scripts/neutralize-json > $@ | |||||
| bin/json-formatter: $(MONOREPO_PATH)/json-formatter/go/dist/cucumber-json-formatter-$(OS)-$(ARCH) | |||||
| cp $(MONOREPO_PATH)/json-formatter/go/dist/cucumber-json-formatter-$(OS)-$(ARCH) $@ | |||||
| chmod +x $@ | |||||
| clean: | |||||
| rm -rf acceptance/*.json bin/json-formatter | |||||
| .PHONY: clean | |||||
| release: | |||||
| [ -d '../secrets' ] || git clone keybase://team/cucumberbdd/secrets ../secrets | |||||
| git -C ../secrets pull | |||||
| ../secrets/update_permissions | |||||
| docker run \ | |||||
| --volume "${shell pwd}":/app \ | |||||
| --volume "${shell pwd}/../secrets/import-gpg-key.sh":/home/cukebot/import-gpg-key.sh \ | |||||
| --volume "${shell pwd}/../secrets/codesigning.key":/home/cukebot/codesigning.key \ | |||||
| --volume "${shell pwd}/../secrets/.ssh":/home/cukebot/.ssh \ | |||||
| --volume "${shell pwd}/../secrets/.gem":/home/cukebot/.gem \ | |||||
| --volume "${HOME}/.gitconfig":/home/cukebot/.gitconfig \ | |||||
| --env CUCUMBER_USE_RELEASED_GEMS=1 \ | |||||
| --env-file ../secrets/secrets.list \ | |||||
| --user 1000 \ | |||||
| --rm \ | |||||
| -it cucumber/cucumber-build:latest \ | |||||
| bash -c "rm Gemfile.lock && bundle && bundle exec rake && bundle exec rake release" | |||||
| .PHONY: release | |||||
| @@ -0,0 +1,162 @@ | |||||
| <p align="center"> | |||||
| <img src="./.github/img/cucumber-open-logo.png" alt="Cucumber Open - Supported by Smartbear" width="428" /> | |||||
| </p> | |||||
| # Cucumber | |||||
| [](https://vshymanskyy.github.io/StandWithUkraine) | |||||
| [](https://opencollective.com/cucumber) | |||||
| [](https://opencollective.com/cucumber) | |||||
| [](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/cucumber-ruby) | |||||
| [](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/cucumber-ruby) | |||||
| [](https://github.com/cucumber/cucumber-ruby/actions/workflows/cucumber-ruby.yml) | |||||
| [](https://codeclimate.com/github/cucumber/cucumber-ruby) | |||||
| [](https://coveralls.io/r/cucumber/cucumber-ruby?branch=main) | |||||
| Cucumber is a tool for running automated tests written in plain language. Because they're | |||||
| written in plain language, they can be read by anyone on your team. Because they can be | |||||
| read by anyone, you can use them to help improve communication, collaboration and trust on | |||||
| your team. | |||||
| <p align="center"> | |||||
| <img src="./.github/img/gherkin-example.png" alt="Cucumber Gherkin Example" width="728" /> | |||||
| </p> | |||||
| This is the Ruby implementation of Cucumber. Cucumber is also available for [JavaScript](https://github.com/cucumber/cucumber-js), | |||||
| [Java](https://github.com/cucumber/cucumber-jvm), and a lot of other languages. You can find a list of implementations here: https://cucumber.io/docs/installation/. | |||||
| See [CONTRIBUTING.md](CONTRIBUTING.md) for info on contributing to Cucumber (issues, PRs, etc.). | |||||
| Everyone interacting in this codebase and issue tracker is expected to follow the | |||||
| Cucumber [code of conduct](https://cucumber.io/conduct). | |||||
| ## Installation | |||||
| Cucumber for Ruby is a Ruby gem. Install it as you would install any gem: add | |||||
| `cucumber` to your Gemfile: | |||||
| gem 'cucumber' | |||||
| then install it: | |||||
| $ bundle | |||||
| or install the gem directly: | |||||
| $ gem install cucumber | |||||
| Later in this document, bundler is considered being used so all commands are using | |||||
| `bundle exec`. If this is not the case for you, execute `cucumber` directly, without | |||||
| `bundle exec`. | |||||
| ### Supported platforms | |||||
| - Ruby 3.2 | |||||
| - Ruby 3.1 | |||||
| - Ruby 3.0 | |||||
| - Ruby 2.7 | |||||
| - Ruby 2.6 | |||||
| - TruffleRuby 22.0.0+ | |||||
| - JRuby (with [some limitations](https://github.com/cucumber/cucumber-ruby/blob/main/docs/jruby-limitations.md)) | |||||
| - 9.3 >= 9.3.1 (there is a known issue with JRuby 9.3.0. More info can | |||||
| be found in the [PR#1571](https://github.com/cucumber/cucumber-ruby/pull/1571).) | |||||
| ### Ruby on Rails | |||||
| Using Ruby on Rails? You can use [cucumber-rails](https://github.com/cucumber/cucumber-rails) | |||||
| to bring Cucumber into your Rails project. | |||||
| ## Usage | |||||
| ### Initialization | |||||
| If you need to, initialize your `features` directory with | |||||
| $ bundle exec cucumber --init | |||||
| This will create the following directories and files if they do not exist already: | |||||
| features | |||||
| ├── step_definitions | |||||
| └── support | |||||
| └── env.rb | |||||
| ### Create your specification | |||||
| Create a file named `rule.feature` in the `features` directory with: | |||||
| ```gherkin | |||||
| # features/rule.feature | |||||
| Feature: Rule Sample | |||||
| Rule: This is a rule | |||||
| Example: A passing example | |||||
| Given this will pass | |||||
| When I do an action | |||||
| Then some results should be there | |||||
| Example: A failing example | |||||
| Given this will fail | |||||
| When I do an action | |||||
| Then some results should be there | |||||
| ``` | |||||
| ### Automate your specification | |||||
| And a file named `steps.rb` in `features/step_definitions` with: | |||||
| ```ruby | |||||
| # features/step_definitions/steps.rb | |||||
| Given("this will pass") do | |||||
| @this_will_pass = true | |||||
| end | |||||
| Given("this will fail") do | |||||
| @this_will_pass = false | |||||
| end | |||||
| When("I do an action") do | |||||
| end | |||||
| Then("some results should be there") do | |||||
| expect(@this_will_pass) | |||||
| end | |||||
| ``` | |||||
| ### Run Cucumber | |||||
| $ bundle exec cucumber | |||||
| To execute a single feature file: | |||||
| $ bundle exec cucumber features/rule.feature | |||||
| To execute a single example, indicates the line of the name of the example: | |||||
| $ bundle exec cucumber features/rule.feature:7 | |||||
| To summarize the results on the standard output, and writte a HTML report on disk: | |||||
| $ bundle exec cucumber --format summary --format html --out report.html | |||||
| For more command line options | |||||
| $ bundle exec cucumber --help | |||||
| You can also find documentation on the command line possibilities in | |||||
| [features/docs/cli](features/docs/cli). | |||||
| ## Documentation and support | |||||
| - Getting started, writing features, step definitions, and more: https://cucumber.io/docs | |||||
| - Ruby API Documentation: http://www.rubydoc.info/github/cucumber/cucumber-ruby/ | |||||
| - Community support forum: https://community.smartbear.com/t5/Cucumber-Open/bd-p/CucumberOS | |||||
| - Slack: [register for an account](https://cucumberbdd-slack-invite.herokuapp.com/) then head over to [#intro](https://cucumberbdd.slack.com/messages/C5WD8SA21/) | |||||
| ## Copyright | |||||
| Copyright (c) Cucumber Ltd. and Contributors. See LICENSE for details. | |||||
| @@ -0,0 +1,34 @@ | |||||
| # Release process for cucumber-ruby | |||||
| ## Prerequisites | |||||
| To release `cucumber-ruby`, you'll need: | |||||
| - to be a member of the core-team | |||||
| - make | |||||
| - docker | |||||
| ## cucumber-ruby-core | |||||
| If internal libraries such as `cucumber-gherkin` needs to be updated, you'll | |||||
| need to update and release `cucumber-ruby-core` before releasing `cucumber-ruby`. | |||||
| ## Releasing cucumber-ruby | |||||
| - Upgrade gems with `scripts/update-gemspec` | |||||
| - Bump the version number in `lib/cucumber/version` | |||||
| - Update `CHANGELOG.md` with the upcoming version number and create a new `Unreleased` section | |||||
| - Remove empty sections from `CHANGELOG.md` | |||||
| - Commit the changes using a verified signature | |||||
| ```shell | |||||
| git commit --gpg-sign -am "Release X.Y.Z" | |||||
| git push | |||||
| ``` | |||||
| - Now release it: push to a dedicated `release/` branch: | |||||
| ```shell | |||||
| git push origin main:release/vX.Y.Z | |||||
| ``` | |||||
| - Check the release has been successfully pushed to [rubygems](https://rubygems.org/gems/cucumber) | |||||
| - Finally, update the `cucumber-ruby` version in the | |||||
| [documentation project](https://cucumber.io/docs/installation/) in | |||||
| [versions.yaml](https://github.com/cucumber/docs/blob/master/data/versions.yaml). | |||||
| @@ -0,0 +1,22 @@ | |||||
| require 'rubygems' | |||||
| require 'bundler' | |||||
| Bundler::GemHelper.install_tasks | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib") | |||||
| Dir['gem_tasks/**/*.rake'].each { |rake| load rake } | |||||
| require 'rubocop/rake_task' | |||||
| RuboCop::RakeTask.new | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new | |||||
| default_tasks = %i[spec cucumber cck] | |||||
| default_tasks << :examples if ENV['CI'] | |||||
| task default: default_tasks | |||||
| require 'rake/clean' | |||||
| CLEAN.include %w[**/*.{log,pyc,rbc,tgz} doc] | |||||
| @@ -0,0 +1,180 @@ | |||||
| # Upgrading to 8.0.0 | |||||
| ## AfterConfiguration hook | |||||
| `AfterConfiguration` hook has been removed in 8.0.0. | |||||
| Use the `InstallPlugin` hook if you need the `configuration` parameter. | |||||
| ```ruby | |||||
| InstallPlugin do |configuration, registry| | |||||
| # configuration is an instance of Cucumber::Configuration defined in | |||||
| # lib/cucumber/configuration.rb | |||||
| # | |||||
| # registry is an instance of Cucumber::Glue::RegistryWrapper defined in | |||||
| # lib/cucumber/glue/registry_wrapper.rb | |||||
| end | |||||
| ``` | |||||
| Use the `BeforeAll` hook if you don't need the `configuration` parameter. | |||||
| ```ruby | |||||
| BeforeAll do | |||||
| # snip | |||||
| end | |||||
| ``` | |||||
| More information about hooks can be found in [features/docs/writing_support_code/hooks/README.md](./features/docs/writing_support_code/hooks/README.md). | |||||
| ## The wire protocol | |||||
| The built-in wire protocol has been removed. | |||||
| The wire protocol is still available by explicitly using the `cucumber-wire` gem. | |||||
| ### Before cucumber 8.0.0 | |||||
| Before cucumber 8.0.0, the wire protocol was automatically installed with cucumber, | |||||
| and automatically activated when it had detected a `.wire` file. | |||||
| If you were using cucumber 7.1.0 and did not already migrate your code, you had a | |||||
| deprecation message. | |||||
| ### With cucumber 8.0.0 | |||||
| If you are not using the wire protocol, you have nothing to do. | |||||
| If you already have updated your code to remove the deprecation message shown when | |||||
| using cucumber 7.1.0, you are already up-to-date. Nothing more has to be done. | |||||
| If you are still using the built-in wire protocol here the step to migrate to cucumber 8.0.0: | |||||
| - add the gem `cucumber-wire` to your Gemfile alongside the `cucumber` one, and install it: | |||||
| ```ruby | |||||
| # Gemfile | |||||
| # ... | |||||
| gem "cucumber" | |||||
| gem "cucumber-wire" | |||||
| # ... | |||||
| ``` | |||||
| ```shell | |||||
| bundle install | |||||
| ``` | |||||
| - add `require 'cucumber/wire'` in your support code. If you do not have support | |||||
| code yet, create a new one. For example `features/support/wire.rb`. | |||||
| ```ruby | |||||
| # features/support/wire.rb | |||||
| require 'cucumber/wire' | |||||
| ``` | |||||
| ## `Cucumber::Cli::Main` former `stdin` argument | |||||
| The second argument of `Cucumber::Cli::Main` - which was formerly named `stdin` - | |||||
| has been removed. | |||||
| ### Before cucumber 8.0.0 | |||||
| You would have used `Cucumber::Cli::Main` with a dummy parameter: | |||||
| ```ruby | |||||
| Cucumber::Cli::Main.new( | |||||
| argument_list, | |||||
| nil, # <-- this is a former unused `stdin` parameter | |||||
| @stdout, | |||||
| @stderr, | |||||
| @kernel | |||||
| ).execute! | |||||
| ``` | |||||
| ### With cucumber 8.0.0 | |||||
| The argument has been removed from the initializer so the dummy parameter is not | |||||
| required anymore: | |||||
| ```ruby | |||||
| Cucumber::Cli::Main.new( | |||||
| argument_list, | |||||
| @stdout, | |||||
| @stderr, | |||||
| @kernel | |||||
| ).execute! | |||||
| ``` | |||||
| ## DataTable#map_column `strict` argument | |||||
| The `strict` argument for the `map_column` method has changed to a keyword argument. | |||||
| ### Before 8.0.0 | |||||
| ```ruby | |||||
| table.map_column('column', false).do |value| | |||||
| end | |||||
| ``` | |||||
| ### With cucumber 8.0.0 | |||||
| ```ruby | |||||
| table.map_column('column', strict: false).do |value| | |||||
| end | |||||
| ``` | |||||
| # Upgrading to 7.1.0 | |||||
| ## The wire protocol | |||||
| Usage of built-in wire protocol with `cucumber-ruby` will be deprecated in cucumber | |||||
| 7.1.0, and removed in cucumber 8.0.0. | |||||
| The wire protocol will still be available by explicitly using the `cucumber-wire` | |||||
| gem. | |||||
| ### Before cucumber 7.1.0 | |||||
| Before cucumber 7.1.0, the wire protocol was automatically installed with cucumber, | |||||
| and automatically activated when it had detected a `.wire` file. | |||||
| ### With cucumber 7.1.0 | |||||
| The wire protocol will work as before, but you will notice a deprecation message. | |||||
| To prevent the deprecation message to be shown, add the gem `cucumber-wire` to your | |||||
| Gemfile alongside the `cucumber` one, and install it: | |||||
| ```ruby | |||||
| # Gemfile | |||||
| # ... | |||||
| gem "cucumber" | |||||
| gem "cucumber-wire" | |||||
| # ... | |||||
| ``` | |||||
| ```shell | |||||
| bundle install | |||||
| ``` | |||||
| And add `require 'cucumber/wire'` in your support code. If you do not have support | |||||
| code yet, create a new one. For example `features/support/wire.rb`. | |||||
| ```ruby | |||||
| # features/support/wire.rb | |||||
| require 'cucumber/wire' | |||||
| ``` | |||||
| The wire protocol will be installed, and no deprecation message will be shown anymore. | |||||
| ## AfterConfiguration hook | |||||
| Usage of `AfterConfiguration` hook will be deprecated in 7.1.0. | |||||
| Use the new `InstallPlugin` hook if you need the `configuration` parameter. | |||||
| Use the new `BeforeAll` hook if you don't need the `configuration` parameter. | |||||
| More information about hooks can be found in [features/docs/writing_support_code/hooks/README.md](./features/docs/writing_support_code/hooks/README.md). | |||||
| @@ -0,0 +1 @@ | |||||
| 8.0.0 | |||||
| @@ -0,0 +1,9 @@ | |||||
| #!/usr/bin/env ruby | |||||
| file_name = File.dirname(__FILE__) + '/../lib' | |||||
| $LOAD_PATH.unshift(file_name) unless $LOAD_PATH.include?(file_name) | |||||
| require 'simplecov_setup' | |||||
| require 'cucumber/rspec/disable_option_parser' | |||||
| require 'cucumber/cli/main' | |||||
| # The dup is to keep ARGV intact, so that tools like ruby-debug can respawn. | |||||
| Cucumber::Cli::Main.new(ARGV.dup).execute! | |||||
| @@ -0,0 +1,29 @@ | |||||
| #!/usr/bin/env ruby | |||||
| # frozen_string_literal: true | |||||
| # | |||||
| # This file was generated by Bundler. | |||||
| # | |||||
| # The application 'rspec' is installed as part of a gem, and | |||||
| # this file is here to facilitate running it. | |||||
| # | |||||
| require "pathname" | |||||
| ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile.local", | |||||
| Pathname.new(__FILE__).realpath) | |||||
| bundle_binstub = File.expand_path("../bundle", __FILE__) | |||||
| if File.file?(bundle_binstub) | |||||
| if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ | |||||
| load(bundle_binstub) | |||||
| else | |||||
| abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. | |||||
| Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") | |||||
| end | |||||
| end | |||||
| require "rubygems" | |||||
| require "bundler/setup" | |||||
| load Gem.bin_path("rspec-core", "rspec") | |||||
| @@ -0,0 +1,63 @@ | |||||
| Gem::Specification.new do |s| | |||||
| s.name = 'cucumber' | |||||
| s.version = File.read(File.expand_path('VERSION', __dir__)).strip | |||||
| s.authors = ['Aslak Hellesøy', 'Matt Wynne', 'Steve Tooke'] | |||||
| s.description = 'Behaviour Driven Development with elegance and joy' | |||||
| s.summary = "cucumber-#{s.version}" | |||||
| s.email = 'cukes@googlegroups.com' | |||||
| s.license = 'MIT' | |||||
| s.homepage = 'https://cucumber.io/' | |||||
| s.platform = Gem::Platform::RUBY | |||||
| s.metadata = { | |||||
| 'bug_tracker_uri' => 'https://github.com/cucumber/cucumber-ruby/issues', | |||||
| 'changelog_uri' => 'https://github.com/cucumber/cucumber-ruby/blob/main/CHANGELOG.md', | |||||
| 'documentation_uri' => 'https://www.rubydoc.info/github/cucumber/cucumber-ruby/', | |||||
| 'mailing_list_uri' => 'https://groups.google.com/forum/#!forum/cukes', | |||||
| 'source_code_uri' => 'https://github.com/cucumber/cucumber-ruby' | |||||
| } | |||||
| # Keep in sync with .circleci/config.yml & .rubocop.yml | |||||
| s.required_ruby_version = '>= 2.6' | |||||
| s.add_dependency 'builder', '~> 3.2', '>= 3.2.4' | |||||
| s.add_dependency 'cucumber-ci-environment', '~> 9.0', '>= 9.0.4' | |||||
| s.add_dependency 'cucumber-core', '~> 11.0', '>= 11.0.0' | |||||
| s.add_dependency 'cucumber-cucumber-expressions', '>= 15.1.1', '< 17.0' | |||||
| s.add_dependency 'cucumber-gherkin', '>= 23.0.1', '< 26.0.4' | |||||
| s.add_dependency 'cucumber-html-formatter', '>= 19.1', '< 21.0' | |||||
| s.add_dependency 'cucumber-messages', '>= 18', '< 22' | |||||
| s.add_dependency 'diff-lcs', '~> 1.5', '>= 1.5.0' | |||||
| s.add_dependency 'mini_mime', '~> 1.0' | |||||
| s.add_dependency 'multi_test', '~> 1.1', '>= 1.1.0' | |||||
| s.add_dependency 'sys-uname', '~> 1.2', '>= 1.2.2' | |||||
| s.add_development_dependency 'cucumber-compatibility-kit', '~> 9.2', '>= 9.2.1' | |||||
| s.add_development_dependency 'nokogiri', '~> 1.13', '>= 1.13.6' | |||||
| s.add_development_dependency 'pry', '~> 0.14', '>= 0.14.1' | |||||
| s.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6' | |||||
| s.add_development_dependency 'rspec', '~> 3.11', '>= 3.11.0' | |||||
| s.add_development_dependency 'simplecov', '~> 0.21', '>= 0.21.2' | |||||
| s.add_development_dependency 'syntax', '~> 1.2', '>= 1.2.2' | |||||
| s.add_development_dependency 'test-unit', '~> 3.5', '>= 3.5.3' | |||||
| s.add_development_dependency 'webrick', '~> 1.7', '>= 1.7.0' | |||||
| # For maintainer scripts | |||||
| s.add_development_dependency 'octokit', '~> 4.22', '>= 4.22.0' | |||||
| # Needed for examples (rake examples) | |||||
| s.add_development_dependency 'capybara', '~> 3.36', '>= 3.36.0', '< 3.37' | |||||
| s.add_development_dependency 'rack-test', '>= 1.1.0', '~> 2.0' | |||||
| s.add_development_dependency 'sinatra', '>= 2.2.0', '~> 3.0' | |||||
| s.required_rubygems_version = '>= 1.6.1' | |||||
| s.files = Dir[ | |||||
| 'CHANGELOG.md', | |||||
| 'CONTRIBUTING.md', | |||||
| 'README.md', | |||||
| 'LICENSE', | |||||
| 'lib/**/*' | |||||
| ] | |||||
| s.executables = ['cucumber'] | |||||
| s.rdoc_options = ['--charset=UTF-8'] | |||||
| s.require_path = 'lib' | |||||
| end | |||||
| @@ -0,0 +1,18 @@ | |||||
| <% | |||||
| std_opts = "--format progress features -r features --strict --publish-quiet".dup | |||||
| std_opts << " --tags 'not @wip'" | |||||
| std_opts << " --tags 'not @wip-jruby'" if defined?(JRUBY_VERSION) | |||||
| wip_opts = "--color -r features".dup | |||||
| if defined?(JRUBY_VERSION) | |||||
| wip_opts << " --tags '@wip or @wip-jruby'" | |||||
| else | |||||
| wip_opts << " --tags @wip" | |||||
| end | |||||
| %> | |||||
| default: <%= std_opts %> --tags "not @jruby" | |||||
| jruby: <%= std_opts %> | |||||
| jruby_win: <%= std_opts %> CUCUMBER_FORWARD_SLASH_PATHS=true | |||||
| windows_mri: <%= std_opts %> --tags "not @jruby" --tags "not @needs-many-fonts" --tags "not @todo-windows" CUCUMBER_FORWARD_SLASH_PATHS=true | |||||
| wip: --wip <%= wip_opts %> features | |||||
| none: --format pretty | |||||
| @@ -0,0 +1,40 @@ | |||||
| # Cucumber and JRuby limitations | |||||
| `cucumber` can be executed on `JRuby` (tested with `9.2`), although some of the features | |||||
| are not available on this platform. | |||||
| ## Defining steps with native languages | |||||
| There are currently three languages (Russian, Ukrainian and Uzbek) for which the step definition | |||||
| can not be written in native language. | |||||
| That means, for example, that you can not write the following code: | |||||
| ```ruby | |||||
| Допустим('я ввожу число {int}') do |число| | |||||
| calc.push число | |||||
| end | |||||
| ``` | |||||
| Instead, you have to write: | |||||
| ```ruby | |||||
| Given('я ввожу число {int}') do |number| | |||||
| calc.push number | |||||
| end | |||||
| ``` | |||||
| Of course, you can still write your feature files in a native language, for example, the following | |||||
| feature file can be executed on JRuby: | |||||
| ```gherkin | |||||
| # language: ru | |||||
| Функционал: Сложение чисел | |||||
| Чтобы не складывать в уме | |||||
| Все, у кого с этим туго | |||||
| Хотят автоматическое сложение целых чисел | |||||
| Сценарий: Сложение двух целых чисел | |||||
| Допустим я ввожу число 50 | |||||
| И затем ввожу число 70 | |||||
| Если я нажимаю "+" | |||||
| То результатом должно быть число 120 | |||||
| ``` | |||||
| @@ -0,0 +1,94 @@ | |||||
| ## Pre-requisites | |||||
| ### Ruby Extension | |||||
| Install and configure the | |||||
| [ruby extension](https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby) | |||||
| ### Use `debase` and `ruby-debug-ide` gems locally | |||||
| Make sure to use a `Gemfile.local` file with `debase` and `ruby-debug-ide` gems. | |||||
| ~~~ruby | |||||
| # Include the regular Gemfile | |||||
| eval File.read('Gemfile') | |||||
| group :development do | |||||
| gem 'debase', require: false | |||||
| gem 'ruby-debug-ide', require: false | |||||
| end | |||||
| ~~~ | |||||
| Execute `bundle config set --local gemfile Gemfile.local` to use it per default, | |||||
| then `bundle install`. | |||||
| ## Sample launch.json | |||||
| The following `launch.json` - to be placed in the `.vscode` folder - allows to use | |||||
| VSCode debugging features like **breakpoints** and **watches**. | |||||
| ```json | |||||
| { | |||||
| "version": "0.2.0", | |||||
| "configurations": [ | |||||
| { | |||||
| "name": "Cucumber", | |||||
| "type": "Ruby", | |||||
| "request": "launch", | |||||
| "useBundler": true, | |||||
| "cwd": "${workspaceRoot}", | |||||
| "program": "${workspaceRoot}/bin/cucumber", | |||||
| "internalConsoleOptions": "openOnSessionStart" | |||||
| }, | |||||
| { | |||||
| "name": "Cucumber current feature file", | |||||
| "type": "Ruby", | |||||
| "request": "launch", | |||||
| "useBundler": true, | |||||
| "cwd": "${workspaceRoot}", | |||||
| "program": "${workspaceRoot}/bin/cucumber", | |||||
| "args": ["${file}"], | |||||
| "internalConsoleOptions": "openOnSessionStart" | |||||
| }, | |||||
| { | |||||
| "name": "Cucumber scenario under cursor", | |||||
| "type": "Ruby", | |||||
| "request": "launch", | |||||
| "useBundler": true, | |||||
| "cwd": "${workspaceRoot}", | |||||
| "program": "${workspaceRoot}/bin/cucumber", | |||||
| "args": ["${file}:${lineNumber}"], | |||||
| "internalConsoleOptions": "openOnSessionStart" | |||||
| }, | |||||
| { | |||||
| "name": "Rspec", | |||||
| "type": "Ruby", | |||||
| "request": "launch", | |||||
| "useBundler": true, | |||||
| "cwd": "${workspaceRoot}", | |||||
| "program": "${workspaceRoot}/bin/rspec", | |||||
| "internalConsoleOptions": "openOnSessionStart" | |||||
| }, | |||||
| { | |||||
| "name": "Rspec current file", | |||||
| "type": "Ruby", | |||||
| "request": "launch", | |||||
| "useBundler": true, | |||||
| "cwd": "${workspaceRoot}", | |||||
| "program": "${workspaceRoot}/bin/rspec", | |||||
| "args": ["${file}"], | |||||
| "internalConsoleOptions": "openOnSessionStart" | |||||
| }, | |||||
| { | |||||
| "name": "Rspec current line", | |||||
| "type": "Ruby", | |||||
| "request": "launch", | |||||
| "useBundler": true, | |||||
| "cwd": "${workspaceRoot}", | |||||
| "program": "${workspaceRoot}/bin/rspec", | |||||
| "args": ["${file}:${lineNumber}"], | |||||
| "internalConsoleOptions": "openOnSessionStart" | |||||
| } | |||||
| ] | |||||
| } | |||||
| ``` | |||||
| @@ -0,0 +1,3 @@ | |||||
| h1. Internationalisation (i18n) examples | |||||
| Visit the "wiki":https://github.com/cucumber/cucumber/wiki/Spoken-languages for instructions on how to use Cucumber on different languages. | |||||
| @@ -0,0 +1,50 @@ | |||||
| desc 'Run features for all languages' | |||||
| task :cucumber do | |||||
| dir = File.dirname(__FILE__) | |||||
| Dir["#{dir}/*"].sort.each do |f| | |||||
| next unless File.directory?(f) | |||||
| lang = f[dir.length + 1..] | |||||
| message = examples_disabled?(lang) | |||||
| unless message.nil? | |||||
| $stderr.puts(message) | |||||
| next | |||||
| end | |||||
| Dir.chdir(f) do | |||||
| puts "DIR: #{f}" | |||||
| rake('cucumber') | |||||
| end | |||||
| end | |||||
| end | |||||
| task default: :cucumber | |||||
| def examples_disabled?(lang) | |||||
| return make_warning("SKIPPING #{lang} (The examples are out of date - please help update them)") unless examples_working?(lang) | |||||
| return make_warning("SKIPPING #{lang}: examples have been disabled for JRuby.") if jruby_disabled_examples?(lang) | |||||
| end | |||||
| def jruby_disabled_examples?(lang) | |||||
| return unless RUBY_PLATFORM == 'java' | |||||
| %w[ru uk uz].include?(lang) | |||||
| end | |||||
| def examples_working?(lang) | |||||
| !%w[ar].index(lang) | |||||
| end | |||||
| def make_warning(msg) | |||||
| %( | |||||
| !!!!! | |||||
| !!!!! | |||||
| !!!!! #{msg} | |||||
| !!!!! | |||||
| !!!!! | |||||
| ) | |||||
| end | |||||
| def rake(args) | |||||
| ruby($PROGRAM_NAME, args) | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: ar | |||||
| خاصية: الجمع | |||||
| من اجل تجنب الأخطاء السخيفة | |||||
| كشخص غبي في الرياضيات | |||||
| اريد معرفة ناتج جمع عددين | |||||
| سيناريو مخطط: جمع عددين | |||||
| بفرض كتابة <input_1> في الآلة الحاسبة | |||||
| و كتابة <input_2> في الآلة الحاسبة | |||||
| متى يتم الضغط على <button> | |||||
| اذاً يظهر <output> على الشاشة | |||||
| امثلة: | |||||
| | input_1 | input_2 | button | output | | |||||
| | 20 | 30 | جمع | 50 | | |||||
| | 2 | 5 | جمع | 7 | | |||||
| | 0 | 40 | جمع | 40 | | |||||
| @@ -0,0 +1,21 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculator' | |||||
| Before do | |||||
| @calc = Calculator.new | |||||
| end | |||||
| After do | |||||
| end | |||||
| Given 'كتابة $n في الآلة الحاسبة' do |n| | |||||
| @calc.push n.to_i | |||||
| end | |||||
| When(/يتم الضغط على (.+)/) do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Then(/يظهر (.*) على الشاشة/) do |result| | |||||
| expect(@result).to eq(result) | |||||
| end | |||||
| @@ -0,0 +1,10 @@ | |||||
| class Calculator | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def جمع | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,12 @@ | |||||
| # language: bg | |||||
| Функционалност: Събиране на числа | |||||
| За да не го правят наум | |||||
| Потребителите | |||||
| Трябва да могат да събират числа с калкулатора | |||||
| Сценарий: Събиране на две цели числа | |||||
| Дадено е че съм въвел 50 | |||||
| И съм въвел 70 | |||||
| Когато натисна "+" | |||||
| То резултата трябва да е равен на 120 | |||||
| @@ -0,0 +1,19 @@ | |||||
| # language: bg | |||||
| Функционалност: Последователни изчисления | |||||
| За да не го правят наум | |||||
| Потребителите | |||||
| Трябва да могат да извършват последователни изчисления с калкулатора | |||||
| Предистория: | |||||
| Дадено е че съм събрал 3 и 5 | |||||
| Сценарий: събиране с резултата от последната операция | |||||
| Когато въведа 4 | |||||
| И натисна "+" | |||||
| То резултата трябва да е равен на 12 | |||||
| Сценарий: делене с резултата от последната операция | |||||
| Когато въведа 2 | |||||
| И натисна "/" | |||||
| То резултата трябва да е равен на 4 | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: bg | |||||
| Функционалност: Делене на числа | |||||
| За да не го правят наум | |||||
| Потребителите | |||||
| Трябва да могат да разделят числа с калкулатора | |||||
| Рамка на сценарий: Делене на цели числа | |||||
| Дадено е че съм въвел <делимо> | |||||
| И е че съм въвел <делител> | |||||
| Когато натисна "/" | |||||
| То резултата трябва да е равен на <частно> | |||||
| Примери: | |||||
| | делимо | делител | частно | | |||||
| | 100 | 2 | 50 | | |||||
| | 28 | 7 | 4 | | |||||
| | 0 | 5 | 0 | | |||||
| @@ -0,0 +1,25 @@ | |||||
| Дадено('е че съм въвел {int}') do |int| | |||||
| calc.push int | |||||
| end | |||||
| Дадено('съм въвел {int}') do |int| | |||||
| calc.push int | |||||
| end | |||||
| Дадено('е че съм събрал {int} и {int}') do |int1, int2| | |||||
| calc.push int1 | |||||
| calc.push int2 | |||||
| calc.send '+' | |||||
| end | |||||
| Когато('въведа {int}') do |int| | |||||
| calc.push int | |||||
| end | |||||
| Когато('натисна {string}') do |op| | |||||
| calc.send op | |||||
| end | |||||
| То('резултата трябва да е равен на {int}') do |int| | |||||
| expect(calc.result).to eq(int) | |||||
| end | |||||
| @@ -0,0 +1,9 @@ | |||||
| begin | |||||
| require 'rspec/expectations' | |||||
| rescue LoadError | |||||
| require 'spec/expectations' | |||||
| end | |||||
| require 'cucumber/formatter/unicode' | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculator' | |||||
| @@ -0,0 +1,7 @@ | |||||
| module LazyCalc | |||||
| def calc | |||||
| @calc ||= Calculator.new | |||||
| end | |||||
| end | |||||
| World(LazyCalc) | |||||
| @@ -0,0 +1,27 @@ | |||||
| class Calculator | |||||
| def initialize | |||||
| @stack = [] | |||||
| end | |||||
| def push(arg) | |||||
| @stack.push arg | |||||
| end | |||||
| def result | |||||
| @stack.last | |||||
| end | |||||
| def + | |||||
| number_1 = @stack.pop | |||||
| number_2 = @stack.pop | |||||
| @stack.push number_1 + number_2 | |||||
| end | |||||
| def / | |||||
| divisor = @stack.pop | |||||
| dividend = @stack.pop | |||||
| @stack.push dividend / divisor | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,18 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculadora' | |||||
| Before do | |||||
| @calc = Calculadora.new | |||||
| end | |||||
| Donat(/que he introduït (\d+) a la calculadora/) do |n| | |||||
| @calc.push n.to_i | |||||
| end | |||||
| Quan(/premo el (\w+)/) do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Aleshores(/el resultat ha de ser (\d+) a la pantalla/) do |result| | |||||
| expect(@result).to eq(result) | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: ca | |||||
| Característica: Suma | |||||
| Per evitar fer errors tontos | |||||
| Com un matemàtic idiota | |||||
| Vull saber la suma dels números | |||||
| Esquema de l'escenari: Sumar dos números | |||||
| Donat que he introduït <entrada_1> a la calculadora | |||||
| I que he introduït <entrada_2> a la calculadora | |||||
| Quan premo el <botó> | |||||
| Aleshores el resultat ha de ser <resultat> a la pantalla | |||||
| Exemples: | |||||
| | entrada_1 | entrada_2 | botó | resultat | | |||||
| | 20 | 30 | add | 50 | | |||||
| | 2 | 5 | add | 7 | | |||||
| | 0 | 40 | add | 40 | | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Calculadora | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def add | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def divide | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| features.html | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: cs | |||||
| Požadavek: Sčítání | |||||
| Jako matematický idiot | |||||
| Abych se vyhnul hloupým chybám | |||||
| Chci vědět jak sečíst dvě čísla | |||||
| Náčrt Scénáře: Sčítaní dvou čísel | |||||
| Pokud Zadám číslo <vstup_1> do kalkulačky | |||||
| A Zadám číslo <vstup_2> do kalkulačky | |||||
| Když stisknu <tlačítko> | |||||
| Pak výsledek by měl být <výstup> | |||||
| Příklady: | |||||
| | vstup_1 | vstup_2 | tlačítko | výstup | | |||||
| | 20 | 30 | add | 50 | | |||||
| | 2 | 5 | add | 7 | | |||||
| | 0 | 40 | add | 40 | | |||||
| @@ -0,0 +1,11 @@ | |||||
| # language: cs | |||||
| Požadavek: Dělení | |||||
| Jako matematický idiot | |||||
| Abych se vyhnul hloupým chybám | |||||
| Chci vědět jak vydělit dvě čísla | |||||
| Scénář: Přirozená čísla | |||||
| Pokud Zadám číslo 3 do kalkulačky | |||||
| A Zadám číslo 2 do kalkulačky | |||||
| Když stisknu divide | |||||
| Pak výsledek by měl být 1.5 | |||||
| @@ -0,0 +1,18 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculator' | |||||
| Before do | |||||
| @calc = Calculator.new | |||||
| end | |||||
| Pokud('Zadám číslo {int} do kalkulačky') do |int| | |||||
| @calc.push int | |||||
| end | |||||
| Když('stisknu {word}') do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Pak('výsledek by měl být {float}') do |float| | |||||
| expect(@result).to eq(float) | |||||
| end | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Calculator | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def add | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def divide | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,18 @@ | |||||
| # language: da | |||||
| Egenskab: Sammenlægning | |||||
| For at slippe for at lave dumme fejl | |||||
| Som bogholder | |||||
| Vil jeg kunne lægge sammen | |||||
| Scenarie: to tal | |||||
| Givet at jeg har indtastet 5 | |||||
| Og at jeg har indtastet 7 | |||||
| Når jeg lægger sammen | |||||
| Så skal resultatet være 12 | |||||
| Scenarie: tre tal | |||||
| Givet at jeg har indtastet 5 | |||||
| Og at jeg har indtastet 7 | |||||
| Og at jeg har indtastet 1 | |||||
| Når jeg lægger sammen | |||||
| Så skal resultatet være 13 | |||||
| @@ -0,0 +1,28 @@ | |||||
| begin | |||||
| require 'rspec/expectations' | |||||
| rescue LoadError | |||||
| require 'spec/expectations' | |||||
| end | |||||
| require 'cucumber/formatter/unicode' | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'lommeregner' | |||||
| Before do | |||||
| @calc = Lommeregner.new | |||||
| end | |||||
| After do | |||||
| end | |||||
| Given(/at jeg har indtastet (\d+)/) do |n| | |||||
| @calc.push n.to_i | |||||
| end | |||||
| When('jeg lægger sammen') do | |||||
| @result = @calc.add | |||||
| end | |||||
| Then(/skal resultatet være (\d*)/) do |result| | |||||
| expect(@result).to eq(result.to_f) | |||||
| end | |||||
| @@ -0,0 +1,10 @@ | |||||
| class Lommeregner | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def add | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| features.html | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: de | |||||
| Funktionalität: Addition | |||||
| Um dumme Fehler zu vermeiden | |||||
| möchte ich als Matheidiot | |||||
| die Summe zweier Zahlen gesagt bekommen | |||||
| Szenariogrundriss: Zwei Zahlen hinzufügen | |||||
| Angenommen ich habe <Eingabe_1> in den Taschenrechner eingegeben | |||||
| Und ich habe <Eingabe_2> in den Taschenrechner eingegeben | |||||
| Wenn ich <Knopf> drücke | |||||
| Dann sollte das Ergebniss auf dem Bildschirm <Ausgabe> sein | |||||
| Beispiele: | |||||
| | Eingabe_1 | Eingabe_2 | Knopf | Ausgabe | | |||||
| | 20 | 30 | add | 50 | | |||||
| | 2 | 5 | add | 7 | | |||||
| | 0 | 40 | add | 40 | | |||||
| @@ -0,0 +1,10 @@ | |||||
| # language: de | |||||
| Funktionalität: Division | |||||
| Um dumme Fehler zu vermeiden | |||||
| müssen Kassierer in der Lage sein einen Bruchteil zu berechnen | |||||
| Szenario: Normale Zahlen | |||||
| Gegeben sei ich habe 3 in den Taschenrechner eingegeben | |||||
| Und ich habe 2 in den Taschenrechner eingegeben | |||||
| Wenn ich divide drücke | |||||
| Dann sollte das Ergebniss auf dem Bildschirm 1.5 sein | |||||
| @@ -0,0 +1,28 @@ | |||||
| begin | |||||
| require 'rspec/expectations' | |||||
| rescue LoadError | |||||
| require 'spec/expectations' | |||||
| end | |||||
| require 'cucumber/formatter/unicode' | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculator' | |||||
| Before do | |||||
| @calc = Calculator.new | |||||
| end | |||||
| After do | |||||
| end | |||||
| Angenommen(/ich habe (\d+) in den Taschenrechner eingegeben/) do |n| | |||||
| @calc.push n.to_i | |||||
| end | |||||
| Wenn(/ich (\w+) drücke/) do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Dann(/sollte das Ergebniss auf dem Bildschirm (.*) sein/) do |result| | |||||
| expect(@result).to eq(result.to_f) | |||||
| end | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Calculator | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def add | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def divide | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| features.html | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: el | |||||
| Δυνατότητα: Πρόσθεση | |||||
| Για να αποφεύγω χαζά λάθη | |||||
| Ως πρωτάρης στα μαθηματικά | |||||
| Θέλω να βλέπω το άθροισμα δύο αριθμών | |||||
| Περιγραφή Σεναρίου: Πρόσθεση δύο αριθμών | |||||
| Δεδομένου ότι έχω εισάγει <τελεστής_1> στην αριθμομηχανή | |||||
| Και έχω εισάγει <τελεστής_2> στην αριθμομηχανή | |||||
| Όταν πατάω <κουμπί> | |||||
| Τότε το αποτέλεσμα στην οθόνη πρέπει να είναι <αποτέλεσμα> | |||||
| Παραδείγματα: | |||||
| | τελεστής_1 | τελεστής_2 | κουμπί | αποτέλεσμα | | |||||
| | 20 | 30 | add | 50 | | |||||
| | 2 | 5 | add | 7 | | |||||
| | 0 | 40 | add | 40 | | |||||
| @@ -0,0 +1,10 @@ | |||||
| # language: el | |||||
| Δυνατότητα: Διαίρεση | |||||
| Για να αποφευχθούν χαζά λάθη | |||||
| Οι ταμίες θα πρέπει να μπορούν να υπολογίζουν κλάσματα | |||||
| Σενάριο: Κανονικοί αριθμοί | |||||
| Δεδομένου ότι έχω εισάγει 3 στην αριθμομηχανή | |||||
| Και έχω εισάγει 2 στην αριθμομηχανή | |||||
| Όταν πατάω divide | |||||
| Τότε το αποτέλεσμα στην οθόνη πρέπει να είναι 1.5 | |||||
| @@ -0,0 +1,25 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculator' | |||||
| Before do | |||||
| @calc = Calculator.new | |||||
| end | |||||
| After do | |||||
| end | |||||
| Δεδομένου('ότι έχω εισάγει {int} στην αριθμομηχανή') do |int| | |||||
| @calc.push int | |||||
| end | |||||
| Δεδομένου('έχω εισάγει {int} στην αριθμομηχανή') do |int| | |||||
| @calc.push int | |||||
| end | |||||
| Όταν(/πατάω (\w+)/) do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Τότε(/το αποτέλεσμα στην οθόνη πρέπει να είναι (.*)/) do |result| | |||||
| expect(@result).to eq(result.to_f) | |||||
| end | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Calculator | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def add | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def divide | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,4 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new | |||||
| @@ -0,0 +1,16 @@ | |||||
| ICANHAZ(/^IN TEH BEGINNIN (\d+) CUCUMBRZ$/) do |n| | |||||
| @basket = Basket.new(n.to_i) | |||||
| end | |||||
| WEN(/^I EAT (\d+) CUCUMBRZ$/) do |n| | |||||
| @belly = Belly.new | |||||
| @belly.eat(@basket.take(n.to_i)) | |||||
| end | |||||
| DEN(/^I HAS (\d+) CUCUMBERZ IN MAH BELLY$/) do |n| | |||||
| expect(@belly.cukes).to eq(n.to_i) | |||||
| end | |||||
| DEN(/^IN TEH END (\d+) CUCUMBRZ KTHXBAI$/) do |n| | |||||
| expect(@basket.cukes).to eq(n.to_i) | |||||
| end | |||||
| @@ -0,0 +1,8 @@ | |||||
| # language: en-lol | |||||
| OH HAI: STUFFING | |||||
| MISHUN: CUCUMBR | |||||
| I CAN HAZ IN TEH BEGINNIN 3 CUCUMBRZ | |||||
| WEN I EAT 2 CUCUMBRZ | |||||
| DEN I HAS 2 CUCUMBERZ IN MAH BELLY | |||||
| AN IN TEH END 1 CUCUMBRZ KTHXBAI | |||||
| @@ -0,0 +1,10 @@ | |||||
| begin | |||||
| require 'rspec/expectations' | |||||
| rescue LoadError | |||||
| require 'spec/expectations' | |||||
| end | |||||
| require 'cucumber/formatter/unicode' | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'basket' | |||||
| require 'belly' | |||||
| @@ -0,0 +1,12 @@ | |||||
| class Basket | |||||
| attr_reader :cukes | |||||
| def initialize(cukes) | |||||
| @cukes = cukes | |||||
| end | |||||
| def take(cukes) | |||||
| @cukes -= cukes | |||||
| cukes | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,11 @@ | |||||
| class Belly | |||||
| attr_reader :cukes | |||||
| def initialize | |||||
| @cukes = 0 | |||||
| end | |||||
| def eat(cukes) | |||||
| @cukes += cukes | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| features.html | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: en | |||||
| Feature: Addition | |||||
| In order to avoid silly mistakes | |||||
| As a math idiot | |||||
| I want to be told the sum of two numbers | |||||
| Scenario Outline: Add two numbers | |||||
| Given I have entered <input_1> into the calculator | |||||
| And I have entered <input_2> into the calculator | |||||
| When I press <button> | |||||
| Then the result should be <output> on the screen | |||||
| Examples: | |||||
| | input_1 | input_2 | button | output | | |||||
| | 20 | 30 | add | 50 | | |||||
| | 2 | 5 | add | 7 | | |||||
| | 0 | 40 | add | 40 | | |||||
| @@ -0,0 +1,10 @@ | |||||
| # language: en | |||||
| Feature: Division | |||||
| In order to avoid silly mistakes | |||||
| Cashiers must be able to calculate a fraction | |||||
| Scenario: Regular numbers | |||||
| * I have entered 3 into the calculator | |||||
| * I have entered 2 into the calculator | |||||
| * I press divide | |||||
| * the result should be 1.5 on the screen | |||||
| @@ -0,0 +1,21 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculator' | |||||
| Before do | |||||
| @calc = Calculator.new | |||||
| end | |||||
| After do | |||||
| end | |||||
| Given(/I have entered (\d+) into the calculator/) do |n| | |||||
| @calc.push n.to_i | |||||
| end | |||||
| When(/I press (\w+)/) do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Then(/the result should be (.*) on the screen/) do |result| | |||||
| expect(@result).to eq(result.to_f) | |||||
| end | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Calculator | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def add | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def divide | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| features.html | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: eo | |||||
| Trajto: Adicio | |||||
| Por eviti stultajn erarojn | |||||
| Kiel stultulo pri matematiko | |||||
| Mi volas adicii du nombrojn | |||||
| Kazo-skizo: Adiciu du nombrojn | |||||
| Komence mi entajpas <nombro_1> en la kalkulilon | |||||
| Kaj mi entajpas <nombro_2> en la kalkulilon | |||||
| Se mi premas <butono> | |||||
| Do la rezulto estu <rezulto> | |||||
| Ekzemploj: | |||||
| | nombro_1 | nombro_2 | butono | rezulto | | |||||
| | 20 | 30 | add | 50 | | |||||
| | 2 | 5 | add | 7 | | |||||
| | 0 | 40 | add | 40 | | |||||
| @@ -0,0 +1,10 @@ | |||||
| # language: eo | |||||
| Trajto: Divido | |||||
| Por eviti stultajn erarojn | |||||
| Uzantoj kapablu kalkuli frakciojn | |||||
| Kazo: Simplaj nombroj | |||||
| * mi entajpas 3 en la kalkulilon | |||||
| * mi entajpas 2 en la kalkulilon | |||||
| * mi premis divide | |||||
| * la rezulto estu 1.5 | |||||
| @@ -0,0 +1,21 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculator' | |||||
| Before do | |||||
| @calc = Calculator.new | |||||
| end | |||||
| After do | |||||
| end | |||||
| Se('mi entajpas {int} en la kalkulilon') do |int| | |||||
| @calc.push int | |||||
| end | |||||
| Donitaĵo('mi premas/premis {word}') do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Do('la rezulto estu {float}') do |float| | |||||
| expect(@result).to eq(float) | |||||
| end | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Calculator | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def add | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def divide | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: es | |||||
| Característica: adición | |||||
| Para evitar hacer errores tontos | |||||
| Como un matemático idiota | |||||
| Quiero saber la suma de los números | |||||
| Esquema del escenario: Sumar dos números | |||||
| Dado que he introducido <entrada_1> en la calculadora | |||||
| Y que he introducido <entrada_2> en la calculadora | |||||
| Cuando oprimo el <botón> | |||||
| Entonces el resultado debe ser <resultado> en la pantalla | |||||
| Ejemplos: | |||||
| | entrada_1 | entrada_2 | botón | resultado | | |||||
| | 20 | 30 | add | 50 | | |||||
| | 2 | 5 | add | 7 | | |||||
| | 0 | 40 | add | 40 | | |||||
| @@ -0,0 +1,18 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'calculador' | |||||
| Before do | |||||
| @calc = Calculador.new | |||||
| end | |||||
| Dado(/que he introducido (\d+) en la calculadora/) do |n| | |||||
| @calc.push n.to_i | |||||
| end | |||||
| Cuando(/oprimo el (\w+)/) do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Entonces(/el resultado debe ser (.*) en la pantalla/) do |result| | |||||
| expect(@result).to eq(result.to_f) | |||||
| end | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Calculador | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def add | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def divide | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,10 @@ | |||||
| # language: et | |||||
| Omadus: Jagamine | |||||
| Rumalate vigade vältimiseks | |||||
| Peavad kassapidajad saama arvutada murdudes | |||||
| Stsenaarium: Tavalised numbrid | |||||
| Eeldades et olen sisestanud kalkulaatorisse numbri 3 | |||||
| Ja olen sisestanud kalkulaatorisse numbri 2 | |||||
| Kui ma vajutan jaga | |||||
| Siis vastuseks peab ekraanil kuvatama 1.5 | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: et | |||||
| Omadus: Liitmine | |||||
| Selleks et vältida rumalaid vigu | |||||
| Olles matemaatika-puupea | |||||
| Tahan et mulle öeldaks kahe numbri summa | |||||
| Raamstsenaarium: Liida kaks numbrit | |||||
| Eeldades et olen sisestanud kalkulaatorisse numbri <input_1> | |||||
| Ja olen sisestanud kalkulaatorisse numbri <input_2> | |||||
| Kui ma vajutan <button> | |||||
| Siis vastuseks peab ekraanil kuvatama <output> | |||||
| Juhtumid: | |||||
| | input_1 | input_2 | button | output | | |||||
| | 20 | 30 | liida | 50 | | |||||
| | 2 | 5 | liida | 7 | | |||||
| | 0 | 40 | liida | 40 | | |||||
| @@ -0,0 +1,21 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'kalkulaator' | |||||
| Before do | |||||
| @calc = Kalkulaator.new | |||||
| end | |||||
| After do | |||||
| end | |||||
| Given(/olen sisestanud kalkulaatorisse numbri (\d+)/) do |n| | |||||
| @calc.push n.to_i | |||||
| end | |||||
| When(/ma vajutan (\w+)/) do |op| | |||||
| @result = @calc.send op | |||||
| end | |||||
| Then(/vastuseks peab ekraanil kuvatama (.*)/) do |result| | |||||
| expect(@result).to eq(result.to_f) | |||||
| end | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Kalkulaator | |||||
| def push(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def liida | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def jaga | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| features.html | |||||
| @@ -0,0 +1,6 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| @@ -0,0 +1,10 @@ | |||||
| # language: fi | |||||
| Ominaisuus: Jakolasku | |||||
| Välttyäkseen hölmöiltä virheiltä | |||||
| Kassanhoitajan on voitava laskea osamäärä | |||||
| Tapaus: Kokonaislukujen jakolasku | |||||
| Oletetaan että olen syöttänyt laskimeen luvun 3 | |||||
| Ja että olen syöttänyt laskimeen luvun 2 | |||||
| Kun painan "jaa" | |||||
| Niin laskimen ruudulla pitäisi näkyä tulos 1.5 | |||||
| @@ -0,0 +1,28 @@ | |||||
| begin | |||||
| require 'rspec/expectations' | |||||
| rescue LoadError | |||||
| require 'spec/expectations' | |||||
| end | |||||
| require 'cucumber/formatter/unicode' | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") | |||||
| require 'laskin' | |||||
| Before do | |||||
| @laskin = Laskin.new | |||||
| end | |||||
| After do | |||||
| end | |||||
| Given(/että olen syöttänyt laskimeen luvun (\d+)/) do |n| | |||||
| @laskin.pinoa n.to_i | |||||
| end | |||||
| When(/painan "(\w+)"/) do |op| | |||||
| @tulos = @laskin.send op | |||||
| end | |||||
| Then(/laskimen ruudulla pitäisi näkyä tulos (.*)/) do |tulos| | |||||
| expect(@tulos).to eq(tulos.to_f) | |||||
| end | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: fi | |||||
| Ominaisuus: Yhteenlasku | |||||
| Välttyäkseni hölmöiltä virheiltä | |||||
| Koska olen laskutaidoton | |||||
| Haluan että yhteenlaskut lasketaan puolestani | |||||
| Tapausaihio: Kahden luvun summa | |||||
| Oletetaan että olen syöttänyt laskimeen luvun <luku_1> | |||||
| Ja että olen syöttänyt laskimeen luvun <luku_2> | |||||
| Kun painan "<nappi>" | |||||
| Niin laskimen ruudulla pitäisi näkyä tulos <tulos> | |||||
| Tapaukset: | |||||
| | luku_1 | luku_2 | nappi | tulos | | |||||
| | 20 | 30 | summaa | 50 | | |||||
| | 2 | 5 | summaa | 7 | | |||||
| | 0 | 40 | summaa | 40 | | |||||
| @@ -0,0 +1,14 @@ | |||||
| class Laskin | |||||
| def pinoa(n) | |||||
| @args ||= [] | |||||
| @args << n | |||||
| end | |||||
| def summaa | |||||
| @args.inject(0) { |n, sum| sum + n } | |||||
| end | |||||
| def jaa | |||||
| @args[0].to_f / @args[1].to_f | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,8 @@ | |||||
| $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../../lib") | |||||
| require 'cucumber/rake/task' | |||||
| Cucumber::Rake::Task.new do |t| | |||||
| t.cucumber_opts = %w[--format pretty] | |||||
| end | |||||
| task default: :cucumber | |||||
| @@ -0,0 +1,18 @@ | |||||
| # language: fr | |||||
| Fonctionnalité: Addition | |||||
| Afin de gagner du temps lors du calcul de la facture | |||||
| En tant que commerçant | |||||
| Je souhaite pouvoir faire une addition | |||||
| Plan du Scénario: Addition de deux nombres | |||||
| Soit une calculatrice | |||||
| Et que j'entre <a> pour le premier nombre | |||||
| Et que je tape sur la touche "+" | |||||
| Et que j'entre <b> pour le second nombre | |||||
| Lorsque je tape sur la touche "=" | |||||
| Alors le résultat affiché doit être <somme> | |||||
| Exemples: | |||||
| | a | b | somme | | |||||
| | 2 | 2 | 4 | | |||||
| | 2 | 3 | 5 | | |||||
| @@ -0,0 +1,17 @@ | |||||
| # language: fr | |||||
| Fonctionnalité: Addition | |||||
| Afin de financer mon bonus avec l'argent des pigeons | |||||
| En tant que trader | |||||
| Je souhaite pouvoir additionner 2 chiffres | |||||
| Plan du Scénario: Addition de produits dérivés | |||||
| Soit une calculatrice | |||||
| Etant donné qu'on tape <a> | |||||
| Et qu'on tape <b> | |||||
| Lorsqu'on tape additionner | |||||
| Alors le résultat doit être <somme> | |||||
| Exemples: | |||||
| | a | b | somme | | |||||
| | 2 | 2 | 4 | | |||||
| | 2 | 3 | 5 | | |||||
| @@ -0,0 +1,27 @@ | |||||
| Soit(/^une calculatrice$/) do | |||||
| @calc = Calculatrice.new | |||||
| end | |||||
| Etantdonnéqu('on tape {int}') do |entier| | |||||
| @calc.push entier | |||||
| end | |||||
| Soit("j'entre {int} pour le premier/second nombre") do |entier| | |||||
| @calc.push entier | |||||
| end | |||||
| Soit('je tape sur la touche {string}') do |_touche| | |||||
| @result = @calc.additionner | |||||
| end | |||||
| Lorsqu(/on tape additionner/) do | |||||
| @result = @calc.additionner | |||||
| end | |||||
| Alors('le résultat affiché doit être {float}') do |resultat_attendu| | |||||
| expect(@result).to eq(resultat_attendu) | |||||
| end | |||||
| Alors('le résultat doit être {float}') do |resultat_attendu| | |||||
| expect(@result).to eq(resultat_attendu) | |||||
| end | |||||