cucumber-attic / cucumber-ruby-spike-donotuse Goto Github PK
View Code? Open in Web Editor NEWPure Ruby Cucumber (Cucumber 2.x)
License: MIT License
Pure Ruby Cucumber (Cucumber 2.x)
License: MIT License
Inspired by RSpec's subject
macro, I'd like to add dispatching to subjects to the text mapper. Here's how I imagine it working: if you extend a module with the text mapper DSL, the mappings will be executed directly in the context, with self
as the receiver, but if you extend a class, mappings defined in that class will be executed with a named attribute (usually an instance of a specific class) as the receiver.
module HelperMapper
extend Cucumber::TextMapper
map("an explosion")
def do_explode
raise "OMG YOU GUYS"
end
end
class Person
extend Cucumber::TextMapper
attr_reader :bank
def initialize
@bank = Bank.new
end
map("he pays his bills")
def pay_bills
bank.pay_bills(amount_owed)
end
def amount_owed
Money.new(1_000_000)
end
end
Now imagine we're in an IRB session inside the execution context:
> @person = Person.new # done for you--inferred from the name of the mapper, or specified with subject a la Rspec
> dispatch("an explosion").should raise_error(/OMG YOU GUYS/)
> @person.should_receive(:pay_bills)
> dispatch("he pays his bills")
I think this would be really useful.
[Edited for clarity.]
This is from one of the features:
def_map /(\d+) and (\d+) are added together/ => [:add, Integer, Integer]
def_map ["these numbers are added together:", DocString] => :add_script
Wouldn't this be more consistent?
def_map /(\d+) and (\d+) are added together/ => [:add, Integer, Integer]
def_map "these numbers are added together:" => [:add_script, DocString]
tl;dr The mapping DSL is confusing and can be improved. Here are my ideas on what should replace it. If anyone has some ideas about that, let's talk about them here.
We map from a step to code like this:
def_map "foo" => :bar
But there are many exceptions, because sometimes there's a need to match on more than one thing, or coerce the captures, or both at once, so you get something like this:
def_map ["a foo with:", DocString] => [:bar, MySpecialType]
which is confusing (see #7) and ugly. def_map
is more lispy than ruby.
Proposal 1:
map("simple").to(:simple)
map(/a complex (\w+) with:/, DocString).to(:complex, [Name, MySpecialType])
Proposal 2:
map from("simple"), to(:simple)
map from(/a complex (\w+) with:/, DocString), to(:complex, [Name, MySpecialType])
Each would also be used to annotate methods directly, i.e., without the to
part:
map("simple")
def simple; end
map from("simple")
def simple; end
The first is more concise, but the second is easier to implement.
I like the map("simple").to(:simple)
form. It is less typing, less noise and will fit in better with the other DSL methods I have in mind (on
, and transform
).
One of the first things I was looking for was an examples directory. Not having found one it was tricky to know where to start.
This should be a good way to make them bake - they'll be used by both cucumber-js and cucumber-ruby
See http://rtomayko.github.com/ronn/ for an overview. Ronn converts markdown into manual pages. I'd like to get a piece of that sweet loving. It'd be sweet if your features could, optionally, act as the help distributed with your gem.
I'm not sure if outputting markdown or reading it would be best... probably reading it.
Once the text mapper stuff is in its own project we can start renaming things to Cucumber as appropriate. I'll also take the time to clean up the README and begin an announcement document highlighting the major changes in cucumber-ruby.
One of the things we got wrong in cucumber1 was lack of embeddability. The only entry point is the CLI.
It would be nice if cucumber-ruby had a very high level API so people can use it in their own apps/libs.
A builder interface would be neat:
cucumber = Cucumber.new
cucumber.with_features(features_dir).with_mappings(mappings_dir).with_format('pretty').with_output(STDOUT).run
-But the README says it does.
Moving the text mapping stuff into its own project will help in creating a seam between the execution model and the default backend, and will allow it to be used in other projects, e.g., Cucumber 1.x.
I believe the long term goal for cucumber-ruby should be to use ZeroMQ to handle all of the communication between the executor and the backend(s), the formatters, reporters, what-have-you. It will require re-thinking the design of large-ish portions of cucumber-ruby, and will take some time to get right, so it's not the immediate priority, but it would enable all sorts of use cases we could only dream of until now.
I'd like to rename the Cucumber executable from "cucumber" to "cuke" or "cukes". Although "cucumber" is a bit long by UNIX-y convention, that in itself isn't the reason I'd like to change it. I'd like to change it because 1) it would make it possible to have both Cucumber 1.x and Cucumber-ruby installed simultaneously without executable name conflicts, and 2) I want to add sub-commands to the CLI like Git. e.g. "cuke exec" and "cuke stats", etc.
I'm about to start driving out the reporter / formatter API, and I'd like to discuss our language a bit, particularly how it relates to reporting and execution. In 1.x the unit of execution is the scenario, but that overloaded the idea of scenario (e.g. a scenario in Cucumber contains the steps from the Gherkin scenario and the Gherkin background), so in cucumber-ruby the test case is the basic unit of execution, and the Gherkin input is compiled into test cases. My question is if this aspect of Cucumber is worth exposing to our technical users. If you executed a scenario outline with 3 examples, and the results said, "3 test cases (3 passed)", would you be confused? Maybe something like "3 test cases from 1 scenario outline"? FWIW I find it very helpful to think of Cucumber as a Gherkin compiler and executor, but from my perspective I would not be surprised if I have missed the forest for the trees. WDYT?
It should be possible to use Cucumber::Ruby classes to run Cucumber tests from code. That will enable us, for example, to create a REST service within a RAILS app to run its own features without reloading the app (or using spork), much as cowboys can do by refreshing their browser.
We need a ye olde configuration API, e.g.:
Cucumber.configure do |config|
config.before do |scenario|
Logger.log("Starting scenario #{scenario.name}")
end
end
...and so on. With a bit of work we might be able to steal some code and / or ideas from from configuration.rb and runtime.rb in 1.x.
In which context should hooks be executed / evaluated? In Cucumber 1.x they share the World with the step defs, but as I implemented them they execute in their own context, because
But I'm not sure about these at all. The fact that they are tied to Gherkin's tag expressions makes me think they belong closer to the front-end and out of the backend execution context, but it is really helpful to just plop an instance variable in the context and go. I've been considering allowing two classes of hooks--global Cucumber hooks that live in cukes/cukes_helper.rb, and backend-specific hooks of whatever type the backend (textmapper, step defs, wire) provides, but I'm wary of complicating things.
Maps (and other objects created with the text mapper macros) should be considered namespaced when they are created. It should be possible to import all maps from a namespace, or just some of them. The thinking is that people might want to override a certain map from a library (think like with Aruba or the Web steps), but not all of them.
Last year at RubyConf, PragDave made an appeal in his keynote to everyone to move away from 1.8.x, because 1.9 was a great Ruby, the future, etc. For that and other reasons, I've been developing on 1.9.2 exclusively, and if I had my way, I'd drop support for Ruby < 1.9 entirely in Cucumber 2.x. I realize this might not be possible, but I think the idea is worth floating. At the very least I think we should drop support for 1.8.6 and older, and strongly encourage people to use only 1.9.2 and newer. As a point of encouragement, I have some features planned for the text-mapping code that will only work on 1.9.x (because they depend on things you can do with methods that you just can't do in earlier versions of Ruby). These features shouldn't get in the way of 1.8 users, if we choose to support them.
Whatever is decided, we need some testing tasks that run the right things against the right rubies, and if we decide to change what versions we support, we need to communicate that clearly in the README and on the wiki.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.