crab 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +21 -10
- data/features/show-from-rally.feature +3 -3
- data/features/subcommand-help.feature +19 -9
- data/lib/crab.rb +9 -9
- data/lib/crab/cli.rb +14 -11
- data/lib/crab/commands/move.rb +46 -0
- data/lib/crab/commands/testcase.rb +1 -1
- data/lib/crab/commands/update.rb +2 -5
- data/lib/crab/cucumber_scenario.rb +1 -2
- data/lib/crab/rally.rb +1 -1
- data/lib/crab/story.rb +1 -1
- data/lib/crab/testcase.rb +4 -0
- data/lib/crab/utilities.rb +8 -0
- data/lib/crab/version.rb +1 -1
- metadata +5 -5
- data/lib/crab/scenario.rb +0 -30
data/README.md
CHANGED
@@ -139,25 +139,36 @@ If you have any problems, please let us know.
|
|
139
139
|
[4]: http://gembundler.com
|
140
140
|
[5]: https://github.com/cucumber/aruba
|
141
141
|
|
142
|
-
To do
|
143
|
-
|
142
|
+
To do / Roadmap
|
143
|
+
---------------
|
144
144
|
|
145
|
-
|
146
|
-
|
145
|
+
### 0.2.0
|
146
|
+
|
147
|
+
- Add a `move` subcommand which moves the story from one state to the next (potentially, `move --back`)
|
147
148
|
- `pull` is not very smart and could detect feature files being moved from one dir to another
|
148
149
|
- Recursively look for a `.crab` directory like Git does with `.git`
|
149
|
-
- Encrypt password in generated `~/.crab/credentials`
|
150
150
|
- Verbose logging (especially before any change or destructive operations in Rally)
|
151
|
-
- Dry-run mode
|
152
151
|
- Figure out how to stub or simulate Rally (tests are taking way too long already)
|
152
|
+
|
153
|
+
### 0.3.0
|
154
|
+
|
155
|
+
- Add a `push` subcommand which parses a Cucumber feature and adds or updates it in Rally
|
156
|
+
- Add a config command + .crab/config file to hold settings like project, etc
|
153
157
|
- Error messages are still more cryptic than we'd like
|
154
|
-
- Add a `move` subcommand which moves the story from one state to the next (potentially, `move --back`)
|
155
|
-
- Add a Cucumber Formatter that updates Test Runs in Rally with results from CI
|
156
|
-
- Investigate use of other fields like Priority and Risk in Rally Test Cases
|
157
158
|
- Make it possible to associate defects with Features (essentially treating defects like stories)
|
158
|
-
- Test in Ruby 1.9
|
159
159
|
- Use the Gherkin models and formatters instead of dumb string templates to generate feature files
|
160
160
|
|
161
|
+
### Later / before 1.0.0
|
162
|
+
|
163
|
+
- Dry-run mode
|
164
|
+
- Encrypt password in generated `~/.crab/credentials`
|
165
|
+
- Add a Cucumber Formatter that updates Test Runs in Rally with results from CI
|
166
|
+
- Test in Ruby 1.9
|
167
|
+
|
168
|
+
### After 1.0.0
|
169
|
+
|
170
|
+
- Bash completion scripts
|
171
|
+
|
161
172
|
Suggestions? Please get in touch!
|
162
173
|
|
163
174
|
Authors and Contributors
|
@@ -1,10 +1,10 @@
|
|
1
1
|
Feature: Show Story From Rally
|
2
|
-
|
2
|
+
|
3
3
|
In order to see what's in a story
|
4
4
|
A lazy developer
|
5
5
|
Wants to be able to do it from the command line
|
6
6
|
|
7
|
-
Background:
|
7
|
+
Background:
|
8
8
|
Given I am logged in
|
9
9
|
|
10
10
|
Scenario: Show Simple Story
|
@@ -19,7 +19,7 @@ Feature: Show Story From Rally
|
|
19
19
|
Scenario: Show Story With Test Cases
|
20
20
|
When I run `crab show US5000`
|
21
21
|
Then the output should contain "Feature: [US5000] Sample Crab Parent Story"
|
22
|
-
And the output should contain "@manual @
|
22
|
+
And the output should contain "@important @medium @manual @acceptance"
|
23
23
|
And the output should contain "Scenario: [TC10388] Sample Testcase"
|
24
24
|
And the output should contain " Given Rally behaves"
|
25
25
|
And the output should contain " When I look at the test case steps"
|
@@ -11,15 +11,16 @@ Feature: Subcommand Help
|
|
11
11
|
|
12
12
|
Scenario: Help
|
13
13
|
When I run `crab -h`
|
14
|
-
Then the output should contain "
|
15
|
-
|
16
|
-
And the output should contain "
|
17
|
-
And the output should contain "
|
18
|
-
And the output should contain "
|
19
|
-
And the output should contain "
|
20
|
-
And the output should contain "
|
21
|
-
And the output should contain "
|
22
|
-
And the output should contain "
|
14
|
+
Then the output should contain "create Create a new story in Rally"
|
15
|
+
And the output should contain "delete Delete an existing story in Rally"
|
16
|
+
And the output should contain "find Find stories by text in name, description or notes"
|
17
|
+
And the output should contain "login Persistently authenticate user with Rally"
|
18
|
+
And the output should contain "move Move a story from one status to the next (or previous)"
|
19
|
+
And the output should contain "project Persistently select project to work with in Rally"
|
20
|
+
And the output should contain "pull Downloads stories (and its test cases) as Cucumber feature files"
|
21
|
+
And the output should contain "show Show a story (and its test cases) as a Cucumber feature"
|
22
|
+
And the output should contain "testcase Manage test cases in a story (add, update, delete)"
|
23
|
+
And the output should contain "update Update a story (name, estimate, etc)"
|
23
24
|
|
24
25
|
Scenario: Bogus Subcommand
|
25
26
|
When I run `crab bogus`
|
@@ -97,3 +98,12 @@ Feature: Subcommand Help
|
|
97
98
|
Usage: crab [options] find [options] [text]
|
98
99
|
"""
|
99
100
|
|
101
|
+
Scenario: Move Subcommand
|
102
|
+
When I run `crab move --help`
|
103
|
+
Then the output should contain:
|
104
|
+
"""
|
105
|
+
crab move: move a story from one status to the next (or previous)
|
106
|
+
|
107
|
+
Usage: crab [options] move story [options]
|
108
|
+
"""
|
109
|
+
|
data/lib/crab.rb
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
require "crab/version"
|
2
2
|
|
3
3
|
# common dependencies
|
4
|
-
require '
|
4
|
+
require 'active_support/all'
|
5
5
|
require 'fileutils'
|
6
6
|
require 'gherkin/i18n'
|
7
7
|
require 'highline/import'
|
8
|
-
require 'active_support/all'
|
9
8
|
require 'rally_rest_api'
|
10
9
|
require 'sanitize'
|
10
|
+
require 'trollop'
|
11
11
|
|
12
12
|
# internals
|
13
13
|
require "crab/utilities"
|
14
|
+
require "crab/cli"
|
14
15
|
require "crab/rally"
|
15
16
|
require "crab/story"
|
16
17
|
require "crab/testcase"
|
17
|
-
require "crab/cli"
|
18
|
-
require "crab/scenario"
|
19
18
|
|
20
19
|
# supported commands
|
21
|
-
require "crab/commands/
|
22
|
-
require "crab/commands/
|
20
|
+
require "crab/commands/create"
|
21
|
+
require "crab/commands/delete"
|
23
22
|
require "crab/commands/find"
|
24
23
|
require "crab/commands/login"
|
25
|
-
require "crab/commands/
|
24
|
+
require "crab/commands/move"
|
26
25
|
require "crab/commands/project"
|
27
|
-
require "crab/commands/
|
28
|
-
require "crab/commands/
|
26
|
+
require "crab/commands/pull"
|
27
|
+
require "crab/commands/show"
|
29
28
|
require "crab/commands/testcase"
|
29
|
+
require "crab/commands/update"
|
30
30
|
|
31
31
|
# cucumber support
|
32
32
|
require "crab/cucumber_feature"
|
data/lib/crab/cli.rb
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
module Crab
|
2
2
|
|
3
|
-
SUB_COMMANDS =
|
3
|
+
SUB_COMMANDS = {
|
4
|
+
"create" => "Create a new story in Rally",
|
5
|
+
"delete" => "Delete an existing story in Rally",
|
6
|
+
"find" => "Find stories by text in name, description or notes",
|
7
|
+
"login" => "Persistently authenticate user with Rally",
|
8
|
+
"project" => "Persistently select project to work with in Rally",
|
9
|
+
"pull" => "Downloads stories (and its test cases) as Cucumber feature files",
|
10
|
+
"show" => "Show a story (and its test cases) as a Cucumber feature",
|
11
|
+
"testcase" => "Manage test cases in a story (add, update, delete)",
|
12
|
+
"update" => "Update a story (name, estimate, etc)",
|
13
|
+
"move" => "Move a story from one status to the next (or previous)",
|
14
|
+
}
|
4
15
|
|
5
16
|
class CLI
|
6
17
|
def self.start
|
@@ -9,17 +20,9 @@ module Crab
|
|
9
20
|
banner """
|
10
21
|
crab version #{Crab::VERSION}: A Cucumber-Rally bridge
|
11
22
|
|
12
|
-
|
13
|
-
delete Delete an existing story in Rally
|
14
|
-
find Find stories by text in name, description or notes
|
15
|
-
login Persistently authenticate user with Rally
|
16
|
-
project Persistently select project to work with in Rally
|
17
|
-
pull Downloads stories (and its test cases) as Cucumber feature files
|
18
|
-
show Show a story (and its test cases) as a Cucumber feature
|
19
|
-
testcase Manage test cases in a story (add, update, delete)
|
20
|
-
update Update a story (name, estimate, etc)
|
23
|
+
#{SUB_COMMANDS.keys.sort.map {|k| sprintf "%10s %s\n", k, SUB_COMMANDS[k] }.join}
|
21
24
|
"""
|
22
|
-
stop_on SUB_COMMANDS
|
25
|
+
stop_on SUB_COMMANDS.keys
|
23
26
|
end
|
24
27
|
|
25
28
|
cmd = ARGV.shift # get the subcommand
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Crab::Commands
|
2
|
+
|
3
|
+
class Move
|
4
|
+
|
5
|
+
include Crab::Utilities
|
6
|
+
|
7
|
+
def initialize(global_opts, args)
|
8
|
+
@global_opts = global_opts
|
9
|
+
@args = args
|
10
|
+
|
11
|
+
@cmd_opts = Trollop::options do
|
12
|
+
banner "crab move: move a story from one status to the next (or previous)
|
13
|
+
|
14
|
+
Usage: crab [options] move story [options]"
|
15
|
+
opt :back, "Move story backwards (from accepted to completed, for example)"
|
16
|
+
end
|
17
|
+
|
18
|
+
@rally = Crab::Rally.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
story_id = @args.join(" ")
|
23
|
+
Trollop::die "No story given" if story_id.empty?
|
24
|
+
|
25
|
+
@rally.connect
|
26
|
+
|
27
|
+
story = @rally.find_story_with_id story_id
|
28
|
+
state = state_from(story.state)
|
29
|
+
|
30
|
+
story.update :schedule_state => (@cmd_opts[:back] ? state_before(state) : state_after(state))
|
31
|
+
|
32
|
+
puts "#{story.formatted_id}: #{story.name} (#{story.state})"
|
33
|
+
end
|
34
|
+
|
35
|
+
def state_before(state)
|
36
|
+
i = (Crab::Story::VALID_STATES.index(state) || 0) - 1
|
37
|
+
Crab::Story::VALID_STATES[i < 0 ? 0 : i]
|
38
|
+
end
|
39
|
+
|
40
|
+
def state_after(state)
|
41
|
+
i = (Crab::Story::VALID_STATES.index(state) || 0) + 1
|
42
|
+
max = Crab::Story::VALID_STATES.size
|
43
|
+
Crab::Story::VALID_STATES[i >= max ? max -1 : i]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -76,7 +76,7 @@ Usage: crab [options] testcase add story name [options]
|
|
76
76
|
@rally.connect
|
77
77
|
tc = @rally.find_test_case(tc_id)
|
78
78
|
tc.update(sanitize_options(opts))
|
79
|
-
puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")}"
|
79
|
+
puts "#{tc.story.formatted_id}/#{tc.formatted_id}: #{tc.name} (#{tc.tags.join(" ")})"
|
80
80
|
end
|
81
81
|
|
82
82
|
def delete(tc_id)
|
data/lib/crab/commands/update.rb
CHANGED
@@ -2,6 +2,8 @@ module Crab::Commands
|
|
2
2
|
|
3
3
|
class Update
|
4
4
|
|
5
|
+
include Crab::Utilities
|
6
|
+
|
5
7
|
def initialize(global_opts, args)
|
6
8
|
@global_opts = global_opts
|
7
9
|
@args = args
|
@@ -74,10 +76,5 @@ Usage: crab [options] update story [options]"
|
|
74
76
|
opts
|
75
77
|
end
|
76
78
|
|
77
|
-
def state_from(option)
|
78
|
-
fixed_option = option.gsub(/(^\w|[-_]\w)/) { $1.upcase.gsub(/_/, '-') }
|
79
|
-
Trollop::die :state, "has an invalid value" unless Crab::Story::VALID_STATES.include? fixed_option
|
80
|
-
fixed_option
|
81
|
-
end
|
82
79
|
end
|
83
80
|
end
|
@@ -6,10 +6,9 @@ module Crab
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def generate_from(scenario)
|
9
|
-
tags = [scenario.method, scenario.test_type]
|
10
9
|
return <<-SCENARIO
|
11
10
|
|
12
|
-
#{tags.map {|
|
11
|
+
#{scenario.tags.map {|tag| "@" + tag }.join(" ")}
|
13
12
|
#{@language.keywords('scenario').last}: [#{scenario.formatted_id}] #{scenario.name}
|
14
13
|
#{scenario.steps.join("\n ")}
|
15
14
|
SCENARIO
|
data/lib/crab/rally.rb
CHANGED
data/lib/crab/story.rb
CHANGED
data/lib/crab/testcase.rb
CHANGED
data/lib/crab/utilities.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Crab
|
2
2
|
module Utilities
|
3
|
+
|
3
4
|
def credentials_file
|
4
5
|
FileUtils.mkdir_p File.expand_path("~/.crab")
|
5
6
|
File.expand_path("~/.crab/credentials")
|
@@ -15,5 +16,12 @@ module Crab
|
|
15
16
|
Trollop::die :project, "must be specified" if project_name.blank?
|
16
17
|
project_name
|
17
18
|
end
|
19
|
+
|
20
|
+
def state_from(option)
|
21
|
+
fixed_option = option.gsub(/(^\w|[-_]\w)/) { $1.upcase.gsub(/_/, '-') }
|
22
|
+
Trollop::die :state, "has an invalid value" unless Crab::Story::VALID_STATES.include? fixed_option
|
23
|
+
fixed_option
|
24
|
+
end
|
25
|
+
|
18
26
|
end
|
19
27
|
end
|
data/lib/crab/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crab
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 7
|
10
|
+
version: 0.1.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Carlos Villela
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-09-
|
18
|
+
date: 2011-09-28 00:00:00 -03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -177,6 +177,7 @@ files:
|
|
177
177
|
- lib/crab/commands/delete.rb
|
178
178
|
- lib/crab/commands/find.rb
|
179
179
|
- lib/crab/commands/login.rb
|
180
|
+
- lib/crab/commands/move.rb
|
180
181
|
- lib/crab/commands/project.rb
|
181
182
|
- lib/crab/commands/pull.rb
|
182
183
|
- lib/crab/commands/show.rb
|
@@ -185,7 +186,6 @@ files:
|
|
185
186
|
- lib/crab/cucumber_feature.rb
|
186
187
|
- lib/crab/cucumber_scenario.rb
|
187
188
|
- lib/crab/rally.rb
|
188
|
-
- lib/crab/scenario.rb
|
189
189
|
- lib/crab/story.rb
|
190
190
|
- lib/crab/testcase.rb
|
191
191
|
- lib/crab/utilities.rb
|
data/lib/crab/scenario.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module Crab
|
2
|
-
|
3
|
-
class Scenario
|
4
|
-
|
5
|
-
def initialize(rally_test_case)
|
6
|
-
@rally_test_case = rally_test_case
|
7
|
-
end
|
8
|
-
|
9
|
-
def formatted_id
|
10
|
-
@rally_test_case.formatted_i_d
|
11
|
-
end
|
12
|
-
|
13
|
-
def name
|
14
|
-
@rally_test_case.name
|
15
|
-
end
|
16
|
-
|
17
|
-
def steps
|
18
|
-
Array(@rally_test_case.steps).map {|step| step.input }
|
19
|
-
end
|
20
|
-
|
21
|
-
def method
|
22
|
-
@rally_test_case.elements[:method].parameterize
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_type
|
26
|
-
@rally_test_case.elements[:type].parameterize
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|