crab 0.2.9 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
data/bin/crab-project CHANGED
@@ -18,17 +18,17 @@ Usage: crab project [name] [options*]
18
18
  opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
19
19
  end
20
20
 
21
- if current_project_name.present?
22
- puts current_project_name
23
- exit 0
21
+ name = args.join(" ").strip
24
22
 
25
- elsif args.reject {|arg| arg.blank? }.empty?
26
- puts "No project currently selected."
23
+ if name.empty?
24
+ if current_project_name.present?
25
+ puts current_project_name
26
+ else
27
+ puts "No project currently selected."
28
+ end
27
29
  exit 1
28
30
  end
29
31
 
30
- name = args.join(" ").strip
31
-
32
32
  Crab::Rally.new(opts[:dry]) do |rally|
33
33
  project = rally.find_project name
34
34
  Trollop::die "#{name.inspect} is not a valid project" if project.nil?
data/bin/crab-st-move CHANGED
@@ -14,21 +14,26 @@ class Crab::StoryMove
14
14
  banner <<-BANNER
15
15
  crab story move: move a story from one status to the next (or previous)
16
16
 
17
- Usage: crab story move <id> [options*]
17
+ Usage: crab story move <id> [state] [options*]
18
18
  BANNER
19
19
  opt :back, "Move story backwards (from accepted to completed, for example)"
20
20
  opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
21
21
  end
22
22
 
23
- id = args.join(" ")
23
+ id = args.shift
24
24
  Trollop::die "No story given" if id.empty?
25
25
 
26
26
  Crab::Rally.new(opts[:dry]) do |rally|
27
27
  story = rally.find_story_with_id id
28
- state = state_from(story.state)
29
28
 
30
- story.update :schedule_state => (opts[:back] ? state_before(state) : state_after(state))
29
+ state = args.shift
30
+ if state.blank?
31
+ state = (opts[:back] ? state_before(story.state) : state_after(story.state))
32
+ else
33
+ state = state_from(state)
34
+ end
31
35
 
36
+ story.update :schedule_state => state
32
37
  puts "#{story.formatted_id}: #{story.name} (#{story.state})"
33
38
  end
34
39
  end
data/bin/crab-st-mv CHANGED
@@ -14,21 +14,26 @@ class Crab::StoryMove
14
14
  banner <<-BANNER
15
15
  crab story move: move a story from one status to the next (or previous)
16
16
 
17
- Usage: crab story move <id> [options*]
17
+ Usage: crab story move <id> [state] [options*]
18
18
  BANNER
19
19
  opt :back, "Move story backwards (from accepted to completed, for example)"
20
20
  opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
21
21
  end
22
22
 
23
- id = args.join(" ")
23
+ id = args.shift
24
24
  Trollop::die "No story given" if id.empty?
25
25
 
26
26
  Crab::Rally.new(opts[:dry]) do |rally|
27
27
  story = rally.find_story_with_id id
28
- state = state_from(story.state)
29
28
 
30
- story.update :schedule_state => (opts[:back] ? state_before(state) : state_after(state))
29
+ state = args.shift
30
+ if state.blank?
31
+ state = (opts[:back] ? state_before(story.state) : state_after(story.state))
32
+ else
33
+ state = state_from(state)
34
+ end
31
35
 
36
+ story.update :schedule_state => state
32
37
  puts "#{story.formatted_id}: #{story.name} (#{story.state})"
33
38
  end
34
39
  end
data/bin/crab-story-move CHANGED
@@ -14,21 +14,26 @@ class Crab::StoryMove
14
14
  banner <<-BANNER
15
15
  crab story move: move a story from one status to the next (or previous)
16
16
 
17
- Usage: crab story move <id> [options*]
17
+ Usage: crab story move <id> [state] [options*]
18
18
  BANNER
19
19
  opt :back, "Move story backwards (from accepted to completed, for example)"
20
20
  opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
21
21
  end
22
22
 
23
- id = args.join(" ")
23
+ id = args.shift
24
24
  Trollop::die "No story given" if id.empty?
25
25
 
26
26
  Crab::Rally.new(opts[:dry]) do |rally|
27
27
  story = rally.find_story_with_id id
28
- state = state_from(story.state)
29
28
 
30
- story.update :schedule_state => (opts[:back] ? state_before(state) : state_after(state))
29
+ state = args.shift
30
+ if state.blank?
31
+ state = (opts[:back] ? state_before(story.state) : state_after(story.state))
32
+ else
33
+ state = state_from(state)
34
+ end
31
35
 
36
+ story.update :schedule_state => state
32
37
  puts "#{story.formatted_id}: #{story.name} (#{story.state})"
33
38
  end
34
39
  end
data/bin/crab-story-mv CHANGED
@@ -14,21 +14,26 @@ class Crab::StoryMove
14
14
  banner <<-BANNER
15
15
  crab story move: move a story from one status to the next (or previous)
16
16
 
17
- Usage: crab story move <id> [options*]
17
+ Usage: crab story move <id> [state] [options*]
18
18
  BANNER
19
19
  opt :back, "Move story backwards (from accepted to completed, for example)"
20
20
  opt :dry, "Dry-run (don't change anything)", :short => "-D", :default => false
21
21
  end
22
22
 
23
- id = args.join(" ")
23
+ id = args.shift
24
24
  Trollop::die "No story given" if id.empty?
25
25
 
26
26
  Crab::Rally.new(opts[:dry]) do |rally|
27
27
  story = rally.find_story_with_id id
28
- state = state_from(story.state)
29
28
 
30
- story.update :schedule_state => (opts[:back] ? state_before(state) : state_after(state))
29
+ state = args.shift
30
+ if state.blank?
31
+ state = (opts[:back] ? state_before(story.state) : state_after(story.state))
32
+ else
33
+ state = state_from(state)
34
+ end
31
35
 
36
+ story.update :schedule_state => state
32
37
  puts "#{story.formatted_id}: #{story.name} (#{story.state})"
33
38
  end
34
39
  end
@@ -14,13 +14,9 @@ Feature: Pull From Rally Into Cucumber
14
14
  Then the output should contain "US4988: features/grooming/US4988-sample-crab-story.feature"
15
15
  And a directory named "features" should exist
16
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
- # language: en
20
- Feature: [US4988] Sample Crab Story
21
-
22
- Sample Description
23
- """
17
+ And the file "features/grooming/US4988-sample-crab-story.feature" should contain "# language: en"
18
+ And the file "features/grooming/US4988-sample-crab-story.feature" should contain "Feature: [US4988] Sample Crab Story"
19
+ And the file "features/grooming/US4988-sample-crab-story.feature" should contain " Sample Description"
24
20
 
25
21
  Scenario: Pulling Multiple Stories
26
22
  When I run `crab story pull US4988 US5000`
@@ -9,12 +9,8 @@ Feature: Show Story From Rally
9
9
 
10
10
  Scenario: Show Simple Story
11
11
  When I run `crab story show US4988`
12
- Then the output should contain:
13
- """
14
- Feature: [US4988] Sample Crab Story
15
-
16
- Sample Description
17
- """
12
+ Then the output should contain "Feature: [US4988] Sample Crab Story"
13
+ And the output should contain " Sample Description"
18
14
 
19
15
  Scenario: Show Story With Test Cases
20
16
  When I run `crab story show US5000`
@@ -32,7 +32,7 @@ Feature: Subcommand Help
32
32
  | story delete | Usage: crab story delete <id> [options*] |
33
33
  | story diff | Usage: crab story diff <file> [file*] [options*] |
34
34
  | story find | Usage: crab story find [options*] [text] |
35
- | story move | Usage: crab story move <id> [options*] |
35
+ | story move | Usage: crab story move <id> [state] [options*] |
36
36
  | story pull | Usage: crab story pull <id> [id*] [options*] |
37
37
  | story rename | Usage: crab story rename <id> <name> [options*] |
38
38
  | story show | Usage: crab story show <id> [options*] |
data/lib/crab.rb CHANGED
@@ -5,6 +5,7 @@ require 'active_support/all'
5
5
  require 'fileutils'
6
6
  require 'gherkin'
7
7
  require 'gherkin/i18n'
8
+ require 'gherkin/formatter/pretty_formatter'
8
9
  require 'highline/import'
9
10
  require 'rally_rest_api'
10
11
  require 'sanitize'
@@ -16,6 +17,7 @@ require "crab/rally"
16
17
  require "crab/story"
17
18
  require "crab/testcase"
18
19
  require "crab/cucumber_to_rally_adapter"
20
+ require "crab/rally_to_cucumber_adapter"
19
21
 
20
22
  # cucumber support
21
23
  require "crab/cucumber_feature"
@@ -2,25 +2,31 @@ module Crab
2
2
 
3
3
  class CucumberFeature
4
4
 
5
+ include Crab::Utilities
6
+
5
7
  def initialize(language)
6
8
  @language = Gherkin::I18n.new(language)
9
+ @adapter = Crab::RallyToCucumberAdapter.new @language
7
10
  end
8
11
 
9
12
  def generate_from(story, include_testcases)
10
- text = <<-FEATURE
11
- # language: #{@language.iso_code}
12
- #{@language.keywords('feature').last}: [#{story.formatted_id}] #{story.name}
13
-
14
- #{story.description}
15
- FEATURE
13
+ text = StringIO.new
14
+ formatter = Gherkin::Formatter::PrettyFormatter.new(text, true, false)
15
+ feature = @adapter.feature_from story
16
+ formatter.feature feature
16
17
 
17
18
  if include_testcases
18
- text << <<-SCENARIOS
19
- #{Array(story.scenarios).map {|scenario| CucumberScenario.new(@language.iso_code).generate_from scenario }}
20
- SCENARIOS
19
+ Array(story.test_cases).tap {|tcs| logger.info "#{tcs.size} test case(s) found" }.each do |test_case|
20
+ formatter.scenario @adapter.scenario_from(test_case)
21
+ @adapter.steps_from(test_case).each do |step|
22
+ formatter.step step
23
+ end
24
+ end
21
25
  end
22
26
 
23
- text.strip
27
+ formatter.eof
28
+
29
+ text.string.strip
24
30
  end
25
31
  end
26
32
  end
@@ -1,17 +1,24 @@
1
1
  module Crab
2
2
  class CucumberScenario
3
3
 
4
+ include Crab::Utilities
5
+
4
6
  def initialize(language)
5
7
  @language = Gherkin::I18n.new(language)
8
+ @adapter = Crab::RallyToCucumberAdapter.new @language
6
9
  end
7
10
 
8
- def generate_from(scenario)
9
- return <<-SCENARIO
11
+ def generate_from(test_case)
12
+ text = StringIO.new
13
+ formatter = Gherkin::Formatter::PrettyFormatter.new(text, true, false)
14
+
15
+ formatter.scenario @adapter.scenario_from(test_case)
16
+ @adapter.steps_from(test_case).each do |step|
17
+ formatter.step step
18
+ end
19
+ formatter.eof
10
20
 
11
- #{scenario.tags.map {|tag| "@" + tag }.join(" ")}
12
- #{@language.keywords('scenario').last}: [#{scenario.formatted_id}] #{scenario.name}
13
- #{scenario.steps.join("\n ")}
14
- SCENARIO
21
+ text.string.strip
15
22
  end
16
23
  end
17
24
  end
@@ -0,0 +1,43 @@
1
+ class Crab::RallyToCucumberAdapter
2
+
3
+ include Crab::Utilities
4
+
5
+ def initialize(language)
6
+ @language = language
7
+ end
8
+
9
+ def feature_from(story)
10
+ comments = [Gherkin::Formatter::Model::Comment.new("# language: #{@language.iso_code}", 0)]
11
+ tags = []
12
+ keyword = @language.keywords('feature').last
13
+ name = "[#{story.formatted_id}] #{story.name}"
14
+ description = story.description
15
+ line = 0
16
+
17
+ Gherkin::Formatter::Model::Feature.new(comments, tags, keyword, name, description, line)
18
+ end
19
+
20
+ def scenario_from(test_case)
21
+ comments = []
22
+ tags = test_case.tags.map {|tag| Gherkin::Formatter::Model::Tag.new("@#{tag}", 0) }
23
+ keyword = @language.keywords('scenario').last
24
+ name = "[#{test_case.formatted_id}] #{test_case.name}"
25
+ description = test_case.description
26
+ line = 0
27
+
28
+ Gherkin::Formatter::Model::Scenario.new(comments, tags, keyword, name, description, line)
29
+ end
30
+
31
+ def steps_from(test_case)
32
+ test_case.steps.tap {|steps| logger.info "#{steps.size} step(s) found"}.map do |step|
33
+ step_words = step.split(' ')
34
+ comments = []
35
+ keyword = step_words.shift
36
+ name = " " + step_words.join(' ')
37
+ line = 0
38
+
39
+ Gherkin::Formatter::Model::Step.new(comments, keyword, name, line)
40
+ end
41
+ end
42
+
43
+ end
data/lib/crab/story.rb CHANGED
@@ -41,6 +41,10 @@ module Crab
41
41
  Array(@rally_story.test_cases).map {|tc| Crab::TestCase.new(tc, @dry_run) }
42
42
  end
43
43
 
44
+ def test_cases
45
+ scenarios
46
+ end
47
+
44
48
  def update(opts)
45
49
  if @dry_run
46
50
  puts "Would update story #{formatted_id} with #{opts.inspect}"
data/lib/crab/testcase.rb CHANGED
@@ -20,6 +20,10 @@ module Crab
20
20
  @rally_test_case.name
21
21
  end
22
22
 
23
+ def description
24
+ @rally_test_case.description
25
+ end
26
+
23
27
  def tags
24
28
  [priority, risk, test_method, test_type].map &:parameterize
25
29
  end
@@ -54,7 +54,7 @@ module Crab
54
54
  banner banner
55
55
  opt :priority, "Priority (one of: #{Crab::TestCase::PRIORITIES.join(" ")}", :default => "important", :short => '-p'
56
56
  opt :risk, "Risk (one of: #{Crab::TestCase::RISKS.join(" ")})", :default => "medium", :short => '-r'
57
- opt :method, "Method (one of: #{Crab::TestCase::METHODS.join(" ")})", :default => "automated", :short => '-m'
57
+ opt :method, "Method (one of: #{Crab::TestCase::METHODS.join(" ")})", :default => "manual", :short => '-m'
58
58
  opt :type, "Type (one of: #{Crab::TestCase::TYPES.join(" ")})", :default => "acceptance", :short => '-t'
59
59
  opt :pre, "Pre-conditions", :default => "N/A"
60
60
  opt :post, "Post-conditions", :default => "N/A"
data/lib/crab/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Crab
2
- VERSION = "0.2.9"
2
+ VERSION = "0.2.10"
3
3
  end
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: 5
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 9
10
- version: 0.2.9
9
+ - 10
10
+ version: 0.2.10
11
11
  platform: ruby
12
12
  authors:
13
13
  - Carlos Villela
@@ -355,6 +355,7 @@ files:
355
355
  - lib/crab/cucumber_scenario.rb
356
356
  - lib/crab/cucumber_to_rally_adapter.rb
357
357
  - lib/crab/rally.rb
358
+ - lib/crab/rally_to_cucumber_adapter.rb
358
359
  - lib/crab/story.rb
359
360
  - lib/crab/testcase.rb
360
361
  - lib/crab/utilities.rb