crab 0.2.9 → 0.2.10

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/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