Rspec & large spec files organisation
Nested contexts can help you here, but keep it shallow (typically one level deep). There are two variables to consider in each example: givens (starting state) and what method is being invoked. You can group things by method or state:
# by methoddescribe Stack do describe "#push" do it "adds an element to an empty stack" it "adds an element to a non-empty stack" end describe "#pop" do it "returns nil from an empty stack" it "returns the last element of a non-empty stack" it "removes the last element from a non-empty stack" endend# by statedescribe Stack do context "when empty" do specify "push adds an element" specify "pop returns nil" end context "when not empty" do specify "push adds an element" specify "pop returns last element" specify "pop removes last element" endend
I've used both approaches and seen them both work really well and really badly. The key to either approach is that the examples tell a story as you read from top to bottom. As requirements evolve, this means you need to review this file, just as you do your implementation code.An easy way to check that the spec makes sense is to run it with the documentation formatter:
rspec stack_spec.rb --format documentation
This spits out all the names in order (provided you're not using --order rand):
Stack #push adds an element to an empty stack adds an element to a non-empty stack #pop returns nil from an empty stack returns the last element of a non-empty stack removes the last element from a non-empty stack
or
Stack when empty push adds an element pop returns nil when not empty push adds an element pop returns last element pop removes last element
Once you see this output, it'll be pretty clear to you whether the organization you're using makes sense or not.