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.
- data/.gitignore +7 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Rakefile +9 -0
- data/bin/crab +5 -0
- data/crab.gemspec +33 -0
- data/features/find-text-in-stories.feature +31 -0
- data/features/list-from-rally.feature +27 -0
- data/features/login-and-out-of-rally.feature +14 -0
- data/features/project-selection.feature +27 -0
- data/features/pull-from-rally-into-cucumber.feature +28 -0
- data/features/show-from-rally.feature +25 -0
- data/features/steps/rally_steps.rb +94 -0
- data/features/subcommand-help.feature +84 -0
- data/features/support/aruba.rb +14 -0
- data/features/update-story-in-rally.feature +33 -0
- data/lib/crab.rb +19 -0
- data/lib/crab/cli.rb +112 -0
- data/lib/crab/cucumber_feature.rb +17 -0
- data/lib/crab/cucumber_scenario.rb +11 -0
- data/lib/crab/find.rb +30 -0
- data/lib/crab/list.rb +29 -0
- data/lib/crab/login.rb +25 -0
- data/lib/crab/project.rb +39 -0
- data/lib/crab/pull.rb +32 -0
- data/lib/crab/rally.rb +50 -0
- data/lib/crab/scenario.rb +23 -0
- data/lib/crab/show.rb +17 -0
- data/lib/crab/story.rb +63 -0
- data/lib/crab/update.rb +68 -0
- data/lib/crab/utilities.rb +18 -0
- data/lib/crab/version.rb +3 -0
- data/old/.gitignore +1 -0
- data/old/Gemfile +14 -0
- data/old/Rakefile +277 -0
- data/old/templates/feature-pt.mustache +5 -0
- data/old/templates/feature.mustache +4 -0
- metadata +230 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create ree@rally-cucumber-bridge
|
data/Gemfile
ADDED
data/Rakefile
ADDED
data/bin/crab
ADDED
data/crab.gemspec
ADDED
@@ -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,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
|