trackinator 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,11 +12,11 @@ benefits to this approach:
12
12
 
13
13
  The format of the spreadsheet is as follows (columns can be in any order):
14
14
 
15
- ####project
15
+ ####project (required)
16
16
  The abbreviation for the project in YouTrack. The project must
17
17
  exist in YouTrack already, this gem will not create the project for you
18
18
 
19
- ####id
19
+ ####id (required)
20
20
  Similar to a version number. Must be unique in this test plan. Follows
21
21
  the format x.y.z (this example is 3 levels deep) and there is no limit
22
22
  to nesting depth. Each level denotes sub-tickets that will be created
@@ -25,29 +25,29 @@ and associated to the level above.
25
25
  ####type
26
26
  "Story" for top level items, "Features" and "Tasks" for items one or more
27
27
  levels below "Story". “Features” are user facing and "Tasks" are
28
- implementation details. "Tasks" will not be acceptance tested.
28
+ implementation details. "Tasks" will not be acceptance tested. Defaults to "bug"
29
29
 
30
- ####summary
30
+ ####subsystem (required)
31
+ This is one of iOS, Android, Backend
32
+
33
+ ####summary (required)
31
34
  A one-line summarizing of the feature.
32
35
 
33
- ####description
36
+ ####description (required)
34
37
  A description of the feature including steps to use the feature.
35
38
 
36
- ####outcome
39
+ ####outcome (required)
37
40
  The expected outcome if the feature is used per the steps in the description.
38
41
 
39
42
  ####notes
40
43
  Any additional notes (which will show up as a comment) that might be useful
41
44
  for the developer or tester.
42
45
 
43
- ####references
46
+ ####design reference
44
47
  A reference to the design document. The format should be wf/c-<page>-<screen
45
48
  (or range)>. E.g. wf-12-5 or c-9-2-3 (where "wf" refers to wireframe and "c"
46
49
  refers to composition)
47
50
 
48
- ####platform
49
- This is usually one of iOS, iPhone, iPad, Android, Desktop Web, Mobile Web
50
-
51
51
  ####priority
52
52
  One of Low, Normal, High, Show-stopper
53
53
 
@@ -76,6 +76,8 @@ Options:
76
76
  --youtrack-host, -o <s>: YouTrack host
77
77
  --youtrack-port, -r <i>: YouTrack port (default: 80)
78
78
  --youtrack-path-prefix, -e <s>: YouTrack path prefix (e.g. '/youtrack/') (default: /)
79
+ --create-rc, -c: Create a .trackinatorrc file in your home dir
80
+ --dry-run, -d: Try it out but don't actually import
79
81
  --help, -h: Show this message
80
82
  filename: File name in Google Docs
81
83
  </pre>
@@ -18,7 +18,9 @@ module Trackinator
18
18
  def import file_name
19
19
  ticket_data = @google.get_tickets file_name
20
20
 
21
- issues = validate_tickets(ticket_data)
21
+ issues = []
22
+ issues.concat validate_headings(ticket_data[0])
23
+ issues.concat validate_tickets(ticket_data)
22
24
 
23
25
  if issues.length == 0 && !@dry_run
24
26
  puts "importing..."
@@ -34,6 +36,10 @@ module Trackinator
34
36
 
35
37
  private
36
38
 
39
+ def validate_headings headings
40
+ []
41
+ end
42
+
37
43
  def validate_tickets tickets
38
44
  puts "validating..."
39
45
  issues = []
@@ -47,7 +53,7 @@ module Trackinator
47
53
  issues.concat(@you_track.project_exists?(project))
48
54
 
49
55
  tickets.each do |ticket|
50
- issues.concat(@you_track.you_track_fields_defined?(project, ticket.keys.collect! { |key| key.downcase }))
56
+ issues.concat(@you_track.required_you_track_fields_defined?(project))
51
57
 
52
58
  issues.concat(validate_fields(ticket))
53
59
  issues.concat(validate_formats(ticket))
@@ -59,7 +65,7 @@ module Trackinator
59
65
  def validate_fields ticket
60
66
  issues = []
61
67
 
62
- REQUIRED.each do |req_field|
68
+ GOOGLE_REQUIRED.each do |req_field|
63
69
  unless ticket.keys.include?(req_field) || ticket["type"].downcase.eql?("story")
64
70
  issues << "Validation Error: Ticket with ID: #{ticket["id"]} is missing required field '#{req_field}'"
65
71
  end
@@ -72,7 +78,9 @@ module Trackinator
72
78
  issues = []
73
79
 
74
80
  ticket.keys.each do |key|
75
- validate_format(key, ticket[key])
81
+ unless validate_format(key, ticket[key])
82
+ issues << "Validation Error: Ticket with ID: #{ticket["id"]} has field '#{key}' with invalid format"
83
+ end
76
84
  end
77
85
 
78
86
  issues
@@ -80,7 +88,9 @@ module Trackinator
80
88
 
81
89
  def validate_format key, value
82
90
  if Trackinator.const_defined?("#{key.upcase}") && Trackinator.const_get("#{key.upcase}").match(value.downcase).nil?
83
- issues << "Validation Error: Ticket with ID: #{ticket["id"]} has field '#{key}' with invalid format"
91
+ false
92
+ else
93
+ true
84
94
  end
85
95
  end
86
96
  end
@@ -1,3 +1,3 @@
1
1
  module Trackinator
2
- VERSION = "0.0.14"
2
+ VERSION = "0.0.15"
3
3
  end
@@ -52,23 +52,35 @@ module Trackinator
52
52
  issues
53
53
  end
54
54
 
55
- def you_track_fields_defined?(project, fields)
55
+ # Here's a potential approach for validating that YouTrack fields are present
56
+ #
57
+ # get YouTrack fields from server
58
+ # augment YouTrack fields where necessary (import identifier?)
59
+ # copy YouTrack fields and normalize copy (remove spaces, downcase)
60
+ # create map of YouTrack fields to nYouTrack fields
61
+ # get Google fields from doc
62
+ # normalize Google fields (remove spaces, downcase)
63
+ # subtract nGoogle from nYouTrack (leaving only missing YouTrack fields)
64
+ # subtract nYouTrack from nGoogle (leaving only missing Google fields)
65
+ # warn on missing nGoogle
66
+ # fail validation on nYouTrack using map to get actual field names for display
67
+ # ...
68
+ # or, just hard code the fucking thing and be done with it
69
+
70
+ def required_you_track_fields_defined?(project)
71
+ you_track_fields = []
56
72
  issues = []
57
73
 
58
74
  response = @connection.get("#{@path_prefix}rest/admin/project/#{project}/customfield", { 'Cookie' => @cookie, 'Content-Type' => 'text/plain; charset=utf-8' })
59
75
  response_xml = REXML::Document.new(response.body)
60
76
 
61
- you_track_fields = %w{ notes }
62
-
63
77
  response_xml.elements.each('projectCustomFieldRefs/projectCustomField') do |element|
64
- you_track_fields << element.attributes["name"].sub(' ', '').downcase
78
+ you_track_fields << element.attributes["name"]
65
79
  end
66
80
 
67
- required_fields = fields - REQUIRED
68
-
69
- required_fields.each do |document_field|
70
- unless you_track_fields.include?(document_field)
71
- issues << "Validation Error: Custom field '#{document_field}' not found in YouTrack"
81
+ YOU_TRACK_REQUIRED.each do |required_field|
82
+ unless you_track_fields.include?(required_field)
83
+ issues << "Validation Error: Required field '#{required_field}' not found in YouTrack project"
72
84
  end
73
85
  end
74
86
 
data/lib/trackinator.rb CHANGED
@@ -13,14 +13,21 @@ module Trackinator
13
13
 
14
14
  SUBSYSTEM = /^android$|^backend$|^ios$/
15
15
 
16
- REQUIRED = %w{
16
+ GOOGLE_REQUIRED = %w{
17
17
  project
18
18
  id
19
+ subsystem
19
20
  summary
20
21
  description
21
22
  outcome
22
23
  }
23
24
 
25
+ YOU_TRACK_REQUIRED = [
26
+ "Type",
27
+ "Subsystem",
28
+ "Import Identifier"
29
+ ]
30
+
24
31
  TRACKINATOR_RC = %w{
25
32
  youtrack_username
26
33
  youtrack_password
@@ -68,36 +68,42 @@ module Trackinator
68
68
  end
69
69
 
70
70
  it "#validate_fields should return no issues and validate feature" do
71
- issues = @importer.send(:validate_fields, { "type" => "feature", "project" => "YTTP", "id" => "1.2", "summary" => "A summary", "description" => "A description", "outcome" => "An outcome" })
71
+ issues = @importer.send(:validate_fields, { "project" => "YTTP", "id" => "1.2", "type" => "feature", "subsystem" => "ios", "summary" => "A summary", "description" => "A description", "outcome" => "An outcome" })
72
72
  issues.should == []
73
73
  end
74
74
 
75
75
  it "#validate_fields should return 1 issue: missing project" do
76
- issues = @importer.send(:validate_fields, { "type" => "feature", "id" => "1.2", "summary" => "A summary", "description" => "A description", "outcome" => "An outcome" })
76
+ issues = @importer.send(:validate_fields, { "id" => "1.2", "type" => "feature", "subsystem" => "ios", "summary" => "A summary", "description" => "A description", "outcome" => "An outcome" })
77
77
  issues.size.should == 1
78
78
  issues[0].should == "Validation Error: Ticket with ID: 1.2 is missing required field 'project'"
79
79
  end
80
80
 
81
81
  it "#validate_fields should return 1 issue: missing id" do
82
- issues = @importer.send(:validate_fields, { "type" => "feature", "project" => "YTTP", "summary" => "A summary", "description" => "A description", "outcome" => "An outcome" })
82
+ issues = @importer.send(:validate_fields, { "project" => "YTTP", "type" => "feature", "subsystem" => "ios", "summary" => "A summary", "description" => "A description", "outcome" => "An outcome" })
83
83
  issues.size.should == 1
84
84
  issues[0].should == "Validation Error: Ticket with ID: is missing required field 'id'"
85
85
  end
86
86
 
87
+ it "#validate_fields should return 1 issue: missing subsystem" do
88
+ issues = @importer.send(:validate_fields, { "project" => "YTTP", "id" => "1.2", "type" => "feature", "summary" => "A summary", "description" => "A description", "outcome" => "An outcome" })
89
+ issues.size.should == 1
90
+ issues[0].should == "Validation Error: Ticket with ID: 1.2 is missing required field 'subsystem'"
91
+ end
92
+
87
93
  it "#validate_fields should return 1 issue: missing summary" do
88
- issues = @importer.send(:validate_fields, { "type" => "feature", "project" => "YTTP", "id" => "1.2", "description" => "A description", "outcome" => "An outcome" })
94
+ issues = @importer.send(:validate_fields, { "project" => "YTTP", "id" => "1.2", "type" => "feature", "subsystem" => "ios", "description" => "A description", "outcome" => "An outcome" })
89
95
  issues.size.should == 1
90
96
  issues[0].should == "Validation Error: Ticket with ID: 1.2 is missing required field 'summary'"
91
97
  end
92
98
 
93
99
  it "#validate_fields should return 1 issue: missing description" do
94
- issues = @importer.send(:validate_fields, { "type" => "feature", "project" => "YTTP", "id" => "1.2", "summary" => "A summary", "outcome" => "An outcome" })
100
+ issues = @importer.send(:validate_fields, { "project" => "YTTP", "id" => "1.2", "type" => "feature", "subsystem" => "ios", "summary" => "A summary", "outcome" => "An outcome" })
95
101
  issues.size.should == 1
96
102
  issues[0].should == "Validation Error: Ticket with ID: 1.2 is missing required field 'description'"
97
103
  end
98
104
 
99
105
  it "#validate_fields should return 1 issue: missing outcome" do
100
- issues = @importer.send(:validate_fields, { "type" => "feature", "project" => "YTTP", "id" => "1.2", "summary" => "A summary", "description" => "A description" })
106
+ issues = @importer.send(:validate_fields, { "project" => "YTTP", "id" => "1.2", "type" => "feature", "subsystem" => "ios", "summary" => "A summary", "description" => "A description" })
101
107
  issues.size.should == 1
102
108
  issues[0].should == "Validation Error: Ticket with ID: 1.2 is missing required field 'outcome'"
103
109
  end
@@ -111,34 +117,34 @@ module Trackinator
111
117
  @importer = Importer.new @you_track, @google
112
118
  end
113
119
 
114
- it "#validate_formats should return no issues and validate" do
120
+ it "#validate_formats should return no issues and validate type" do
115
121
  issues = @importer.send(:validate_formats, { "type" => "feature" })
116
122
  issues.should == []
117
123
  end
118
124
 
119
- it "#validate_formats should return no issues and validate" do
125
+ it "#validate_formats should fail validation on type" do
120
126
  issues = @importer.send(:validate_formats, { "type" => "foo" })
121
127
  issues.size.should == 1
122
128
  issues[0].should == "Validation Error: Ticket with ID: has field 'type' with invalid format"
123
129
  end
124
130
 
125
- it "#validate_formats should return no issues and validate" do
131
+ it "#validate_formats should fail validation on id" do
126
132
  issues = @importer.send(:validate_formats, { "id" => "1.2" })
127
133
  issues.should == []
128
134
  end
129
135
 
130
- it "#validate_formats should return no issues and validate" do
136
+ it "#validate_formats should fail validation on id" do
131
137
  issues = @importer.send(:validate_formats, { "id" => "junk" })
132
138
  issues.size.should == 1
133
139
  issues[0].should == "Validation Error: Ticket with ID: junk has field 'id' with invalid format"
134
140
  end
135
141
 
136
- it "#validate_formats should return no issues and validate" do
142
+ it "#validate_formats should return no issues and validate priority" do
137
143
  issues = @importer.send(:validate_formats, { "priority" => "normal" })
138
144
  issues.should == []
139
145
  end
140
146
 
141
- it "#validate_formats should return no issues and validate" do
147
+ it "#validate_formats should fail validation on priority" do
142
148
  issues = @importer.send(:validate_formats, { "priority" => "junk" })
143
149
  issues.size.should == 1
144
150
  issues[0].should == "Validation Error: Ticket with ID: has field 'priority' with invalid format"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trackinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-06 00:00:00.000000000 Z
12
+ date: 2012-09-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gdata_19