crab 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ tmp
6
+ .rally_credentials
7
+ tags
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create ree@rally-cucumber-bridge
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in crab.gemspec
4
+ gemspec
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require 'cucumber/rake/task'
3
+
4
+ Cucumber::Rake::Task.new(:features) do |t|
5
+ t.cucumber_opts = "features --format pretty"
6
+ end
7
+
8
+ task :default => :features
9
+
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'crab'
4
+
5
+ Crab::CLI.start
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "crab/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "crab"
7
+ s.version = Crab::VERSION
8
+ s.authors = ["Carlos Villela"]
9
+ s.email = ["cvillela@thoughtworks.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Cucumber-Rally Bridge}
12
+ s.description = %q{CRaB is a bridge between Cucumber and Rally}
13
+
14
+ s.rubyforge_project = "crab"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.executables = 'crab'
22
+
23
+ s.add_development_dependency 'aruba'
24
+
25
+ s.add_dependency 'aruba'
26
+ s.add_dependency 'cucumber'
27
+ s.add_dependency 'rally_rest_api'
28
+ s.add_dependency 'highline'
29
+ s.add_dependency 'activesupport'
30
+ s.add_dependency 'i18n'
31
+ s.add_dependency 'sanitize'
32
+ s.add_dependency 'trollop'
33
+ end
@@ -0,0 +1,31 @@
1
+ Feature: Find Text in Stories
2
+
3
+ In order to find the story ID
4
+ A lazy developer
5
+ Wants to search for arbitrary bits of text
6
+
7
+ Background:
8
+ Given I am logged in
9
+ And I have selected the project "VEJA SP - Migração para o Alexandria"
10
+
11
+ Scenario: Matching Name
12
+ When I run `crab find Sample Crab`
13
+ Then the output should contain:
14
+ """
15
+ US4988: Sample Crab Story (grooming)
16
+ US4999: Sample Crab Parent Story (grooming)
17
+ US5000: Sample Crab Parent Story (grooming)
18
+ """
19
+
20
+ @quick
21
+ Scenario: Project Must be Specified If Not Set
22
+ Given no project is selected
23
+ When I run `crab find pattern`
24
+ Then the output should contain "Error: argument --project must be specified."
25
+
26
+ Scenario: Project Must Exist
27
+ When I run `crab find --project "foo" pattern`
28
+ Then the output should contain:
29
+ """
30
+ Error: Project "foo" not found.
31
+ """
@@ -0,0 +1,27 @@
1
+ Feature: List Stories in Rally
2
+
3
+ In order to figure out which stories she needs to pull
4
+ A developer who doesn't want to open a browser or click on things
5
+ Wants to list stories in Rally
6
+
7
+ Background:
8
+ Given I am logged in
9
+ And I have selected the project "VEJA SP - Migração para o Alexandria"
10
+
11
+ @really-slow
12
+ Scenario: Basic Invocation
13
+ When I run `crab list`
14
+ Then the output should contain "US4988: Sample Crab Story (grooming)"
15
+
16
+ @quick
17
+ Scenario: Project Must be Specified When Not Selected
18
+ Given no project is selected
19
+ When I run `crab list`
20
+ Then the output should contain "Error: argument --project must be specified."
21
+
22
+ Scenario: Project Must Exist
23
+ When I run `crab list -p "foo"`
24
+ Then the output should contain:
25
+ """
26
+ Error: Project "foo" not found.
27
+ """
@@ -0,0 +1,14 @@
1
+ Feature: Log In and Out of Rally
2
+
3
+ In order to avoid typing his credentials all the time
4
+ A lazy and security-conscious developer
5
+ Wants to log in and out of Rally in order to perform operations
6
+
7
+ Scenario: Logged Out, Logging In
8
+ Given I am logged out
9
+ When I run `crab login` interactively
10
+ And I type my username
11
+ And I type my password
12
+ Then the exit status should be 0
13
+ And the user's home directory should have a file named ".rally_credentials"
14
+
@@ -0,0 +1,27 @@
1
+ Feature: Project Selection
2
+
3
+ In order to work with the find, list etc commands more effectively
4
+ A lazy developer
5
+ Wants to set the project persistently across all commands
6
+
7
+ Background:
8
+ Given I am logged in
9
+
10
+ Scenario: Selecting a Project
11
+ Given no project is selected
12
+
13
+ When I run `crab project`
14
+ Then the output should contain "No project currently selected."
15
+
16
+ When I run `crab project "VEJA SP - Migração para o Alexandria"`
17
+ Then the exit status should be 0
18
+
19
+ When I run `crab project`
20
+ Then the output should contain "VEJA SP - Migração para o Alexandria"
21
+
22
+ Scenario: Selecting an Invalid Project
23
+ When I run `crab project "invalid"`
24
+ Then the output should contain:
25
+ """
26
+ Error: "invalid" is not a valid project.
27
+ """
@@ -0,0 +1,28 @@
1
+ Feature: Pull From Rally Into Cucumber
2
+
3
+ In order to begin development of a story that was written in Rally
4
+ A developer who doesn't want to open a browser or click things
5
+ Wants the story converted into the much nicer Cucumber format
6
+
7
+ Background:
8
+ Given I am logged in
9
+
10
+ Scenario: Pulling a Single Story
11
+ Given a directory named "crab-pull"
12
+ And I cd to "crab-pull"
13
+ When I run `crab pull US4988`
14
+ Then the output should contain "US4988: features/grooming/US4988-sample-crab-story.feature"
15
+ And a directory named "features" should exist
16
+ And a file named "features/grooming/US4988-sample-crab-story.feature" should exist
17
+ And the file "features/grooming/US4988-sample-crab-story.feature" should contain exactly:
18
+ """
19
+ Feature: [US4988] Sample Crab Story
20
+
21
+ Sample Description
22
+ """
23
+
24
+ Scenario: Pulling Multiple Stories
25
+ When I run `crab pull US4988 US5000`
26
+ Then the output should contain "US4988: features/grooming/US4988-sample-crab-story.feature"
27
+ Then the output should contain "US5000: features/grooming/US5000-sample-crab-parent-story.feature"
28
+
@@ -0,0 +1,25 @@
1
+ Feature: Show Story From Rally
2
+
3
+ In order to see what's in a story
4
+ A lazy developer
5
+ Wants to be able to do it from the command line
6
+
7
+ Background:
8
+ Given I am logged in
9
+
10
+ Scenario: Show Simple Story
11
+ When I run `crab show US4988`
12
+ Then the output should contain:
13
+ """
14
+ Feature: [US4988] Sample Crab Story
15
+
16
+ Sample Description
17
+ """
18
+
19
+ Scenario: Show Story With Test Cases
20
+ When I run `crab show US5000`
21
+ Then the output should contain "Feature: [US5000] Sample Crab Parent Story"
22
+ And the output should contain "Scenario: [TC10388] Sample Testcase"
23
+ And the output should contain " Given Rally behaves"
24
+ And the output should contain " When I look at the test case steps"
25
+ And the output should contain " Then I should be able to export them into Cucumber format"
@@ -0,0 +1,94 @@
1
+ require 'rally_rest_api'
2
+
3
+ Given /^I am logged out$/ do
4
+ end
5
+
6
+ Given /^an instance of Rally$/ do
7
+ end
8
+
9
+ Given /^Rally has a story with ID "([^"]*)"$/ do |arg1|
10
+ end
11
+
12
+ Then /^the user's home directory should have a file named "([^"]*)"$/ do |file|
13
+ File.exists? File.expand_path("~/#{file}")
14
+ end
15
+
16
+ def get_rally_credentials
17
+ username, password = File.read(File.join(File.dirname(__FILE__), '..', '..', '.rally_credentials')).split(/\n/)
18
+ [ username, password ]
19
+ end
20
+
21
+ When /^I type my username$/ do
22
+ When %Q{I type "#{get_rally_credentials.first}"}
23
+ end
24
+
25
+ When /^I type my password$/ do
26
+ When %Q{I type "#{get_rally_credentials.last}"}
27
+ end
28
+
29
+ Given /^I am logged in$/ do
30
+ username, password = get_rally_credentials
31
+ steps %Q{
32
+ Given I am logged out
33
+ When I run `crab login -u #{username} -p #{password}`
34
+ Then the output should contain "Logged in as #{username}"
35
+ }
36
+ end
37
+
38
+ Then /^a file named "([^"]*)" in the user's home directory should exist$/ do |arg1|
39
+ pending # express the regexp above with the code you wish you had
40
+ end
41
+
42
+ def get_rally
43
+ username, password = get_rally_credentials
44
+ @rally = RallyRestAPI.new :username => username, :password => password
45
+ end
46
+
47
+ def get_story(story_id)
48
+ get_rally.find(:hierarchical_requirement, :fetch => true) { equal :formatted_i_d, story_id }.first
49
+ end
50
+
51
+ Then /^the story ([A-Z]{2}\d+) should be blocked$/ do |story_id|
52
+ story = get_story(story_id)
53
+ story.blocked.should == "true"
54
+ end
55
+
56
+ Then /^the story ([A-Z]{2}\d+) should be unblocked$/ do |story_id|
57
+ story = get_story(story_id)
58
+ story.blocked.should == "false"
59
+ end
60
+
61
+ Then /^the story ([A-Z]{2}\d+) should be in iteration "([^"]*)"$/ do |story_id, iteration_name|
62
+ story = get_story story_id
63
+ story.iteration.name.should == iteration_name
64
+ end
65
+
66
+ Then /^the story ([A-Z]{2}\d+) should be in release "([^"]*)"$/ do |story_id, release_name|
67
+ story = get_story story_id
68
+ story.release.name.should == release_name
69
+ end
70
+
71
+ Then /^the story ([A-Z]{2}\d+) should have ([A-Z]{2}\d+) as its parent$/ do |child, parent|
72
+ story = get_story child
73
+ story.parent.should_not be_nil
74
+ story.parent.formatted_i_d.should == parent
75
+ end
76
+
77
+ Given /^no project is selected$/ do
78
+ Given 'I run `rm -rf ".rally_project"`'
79
+ end
80
+
81
+ def get_project
82
+ if File.exists? ".rally_project"
83
+ File.read(".rally_project").strip
84
+ end
85
+ end
86
+
87
+ Given /^I have selected the project "([^"]*)"$/ do |project|
88
+ unless get_project == project
89
+ steps %Q{
90
+ When I run `crab project #{project}`
91
+ Then the exit status should be 0
92
+ }
93
+ end
94
+ end
@@ -0,0 +1,84 @@
1
+ @quick
2
+ Feature: Subcommand Help
3
+
4
+ In order to learn how to use crab
5
+ A newbie developer
6
+ Wants to see a useful help message when she runs crab with the wrong arguments
7
+
8
+ Scenario: No Arguments
9
+ When I run `crab`
10
+ Then the output should contain "Error: Unknown subcommand."
11
+
12
+ Scenario: Help
13
+ When I run `crab -h`
14
+ Then the output should contain " login Persistently authenticate user with Rally"
15
+ And the output should contain " list Lists stories"
16
+ And the output should contain " update Update a story (name, estimate, etc)"
17
+ And the output should contain " show Show a story (and its test cases) as a Cucumber feature"
18
+ And the output should contain " pull Downloads stories (and its test cases) as Cucumber feature files"
19
+
20
+ Scenario: Bogus Subcommand
21
+ When I run `crab bogus`
22
+ Then the output should contain:
23
+ """
24
+ Error: Unknown subcommand "bogus".
25
+ """
26
+
27
+ Scenario: Pull Subcommand
28
+ When I run `crab pull --help`
29
+ Then the output should contain:
30
+ """
31
+ crab pull: pulls stories from Rally and writes them out as Cucumber features
32
+
33
+ Usage: crab [options] pull story1 [story2 ...]
34
+ """
35
+
36
+ Scenario: Show Subcommand
37
+ When I run `crab show --help`
38
+ Then the output should contain:
39
+ """
40
+ crab show: displays a story in Rally as a Cucumber feature
41
+
42
+ Usage: crab [options] show story
43
+ """
44
+
45
+ Scenario: List Subcommand
46
+ When I run `crab list --help`
47
+ Then the output should contain:
48
+ """
49
+ crab list: lists stories in Rally
50
+
51
+ Usage: crab [options] list
52
+ """
53
+
54
+ Scenario: Update Subcommand
55
+ When I run `crab update --help`
56
+ Then the output should contain:
57
+ """
58
+ crab update: update a story in Rally
59
+
60
+ Usage: crab [options] update story [options]
61
+ """
62
+
63
+ Scenario: Update Needs a Story Number
64
+ When I run `crab update`
65
+ Then the output should contain "Error: No story given."
66
+
67
+ Scenario: Update Needs At Least One Switch
68
+ When I run `crab update US4988`
69
+ Then the output should contain "Error: Nothing to update. Please provide some options."
70
+
71
+ Scenario: Find Subcommand
72
+ When I run `crab find --help`
73
+ Then the output should contain:
74
+ """
75
+ crab find: find a story in Rally
76
+
77
+ Usage: crab [options] find [options] text
78
+ """
79
+
80
+ Scenario: Find Needs Text
81
+ When I run `crab find`
82
+ Then the output should contain "Error: No search pattern given."
83
+
84
+
@@ -0,0 +1,14 @@
1
+ require 'aruba'
2
+ require 'aruba/cucumber'
3
+
4
+ Before '@quick' do
5
+ @aruba_io_wait_seconds = 1
6
+ end
7
+
8
+ Before '~@quick' do
9
+ @aruba_io_wait_seconds = 5
10
+ end
11
+
12
+ Before '@really-slow' do
13
+ @aruba_io_wait_seconds = 30
14
+ end
@@ -0,0 +1,33 @@
1
+ Feature: Update Story in Rally
2
+
3
+ In order to change a story's fields in Rally
4
+ A developer who doesn't want to open a browser or click on things
5
+ Wants to update those fields from the command line
6
+
7
+ Background:
8
+ Given I am logged in
9
+
10
+ Scenario: Update Name
11
+ When I run `crab update US4988 --name "Sample Crab Story"`
12
+ Then the output should contain "US4988: Sample Crab Story (grooming)"
13
+
14
+ Scenario: Block and Unblock
15
+ When I run `crab update US4988 --blocked`
16
+ Then the output should contain "US4988: Sample Crab Story (grooming)"
17
+ And the story US4988 should be blocked
18
+
19
+ When I run `crab update US4988 --unblocked`
20
+ Then the output should contain "US4988: Sample Crab Story (grooming)"
21
+ And the story US4988 should be unblocked
22
+
23
+ Scenario: Setting Iteration
24
+ When I run `crab update US4988 --iteration "Iteration 0"`
25
+ Then the story US4988 should be in iteration "Iteration 0"
26
+
27
+ Scenario: Setting Release
28
+ When I run `crab update US4988 --release "Beta release"`
29
+ Then the story US4988 should be in release "Beta release"
30
+
31
+ Scenario: Setting Parent
32
+ When I run `crab update US4988 --parent US5000`
33
+ Then the story US4988 should have US5000 as its parent