cucumber_fm-core 0.1

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.
Files changed (74) hide show
  1. data/LICENCE +20 -0
  2. data/lib/cucumber_f_m/aggregator.rb +65 -0
  3. data/lib/cucumber_f_m/comment_module/comment.rb +7 -0
  4. data/lib/cucumber_f_m/config.rb +37 -0
  5. data/lib/cucumber_f_m/cvs/git.rb +7 -0
  6. data/lib/cucumber_f_m/feature.rb +141 -0
  7. data/lib/cucumber_f_m/feature_element/background.rb +10 -0
  8. data/lib/cucumber_f_m/feature_element/comment.rb +13 -0
  9. data/lib/cucumber_f_m/feature_element/component/comments.rb +21 -0
  10. data/lib/cucumber_f_m/feature_element/component/information/component.rb +16 -0
  11. data/lib/cucumber_f_m/feature_element/component/tags.rb +108 -0
  12. data/lib/cucumber_f_m/feature_element/component/title.rb +26 -0
  13. data/lib/cucumber_f_m/feature_element/component/total_estimation.rb +42 -0
  14. data/lib/cucumber_f_m/feature_element/example.rb +7 -0
  15. data/lib/cucumber_f_m/feature_element/info.rb +13 -0
  16. data/lib/cucumber_f_m/feature_element/narrative.rb +7 -0
  17. data/lib/cucumber_f_m/feature_element/scenario.rb +15 -0
  18. data/lib/cucumber_f_m/feature_element/scenario_outline.rb +23 -0
  19. data/lib/cucumber_f_m/feature_element/step.rb +7 -0
  20. data/lib/cucumber_f_m/statistic.rb +31 -0
  21. data/lib/cucumber_f_m/tag_filter.rb +85 -0
  22. data/lib/cucumber_feature_manager.rb +164 -0
  23. data/lib/grit/lib/grit.rb +75 -0
  24. data/lib/grit/lib/grit/actor.rb +36 -0
  25. data/lib/grit/lib/grit/blame.rb +61 -0
  26. data/lib/grit/lib/grit/blob.rb +126 -0
  27. data/lib/grit/lib/grit/commit.rb +247 -0
  28. data/lib/grit/lib/grit/commit_stats.rb +128 -0
  29. data/lib/grit/lib/grit/config.rb +44 -0
  30. data/lib/grit/lib/grit/diff.rb +70 -0
  31. data/lib/grit/lib/grit/errors.rb +7 -0
  32. data/lib/grit/lib/grit/git-ruby.rb +267 -0
  33. data/lib/grit/lib/grit/git-ruby/commit_db.rb +52 -0
  34. data/lib/grit/lib/grit/git-ruby/file_index.rb +193 -0
  35. data/lib/grit/lib/grit/git-ruby/git_object.rb +350 -0
  36. data/lib/grit/lib/grit/git-ruby/internal/file_window.rb +58 -0
  37. data/lib/grit/lib/grit/git-ruby/internal/loose.rb +137 -0
  38. data/lib/grit/lib/grit/git-ruby/internal/pack.rb +384 -0
  39. data/lib/grit/lib/grit/git-ruby/internal/raw_object.rb +37 -0
  40. data/lib/grit/lib/grit/git-ruby/object.rb +325 -0
  41. data/lib/grit/lib/grit/git-ruby/repository.rb +767 -0
  42. data/lib/grit/lib/grit/git.rb +323 -0
  43. data/lib/grit/lib/grit/index.rb +122 -0
  44. data/lib/grit/lib/grit/lazy.rb +33 -0
  45. data/lib/grit/lib/grit/merge.rb +45 -0
  46. data/lib/grit/lib/grit/ref.rb +74 -0
  47. data/lib/grit/lib/grit/repo.rb +482 -0
  48. data/lib/grit/lib/grit/ruby1.9.rb +7 -0
  49. data/lib/grit/lib/grit/status.rb +151 -0
  50. data/lib/grit/lib/grit/submodule.rb +88 -0
  51. data/lib/grit/lib/grit/tag.rb +16 -0
  52. data/lib/grit/lib/grit/tree.rb +123 -0
  53. data/lib/grit/lib/open3_detach.rb +46 -0
  54. data/spec/cucumber_f_m/aggregator_spec.rb +210 -0
  55. data/spec/cucumber_f_m/comment_module/comment_spec.rb +4 -0
  56. data/spec/cucumber_f_m/config_spec.rb +27 -0
  57. data/spec/cucumber_f_m/cvs/git_spec.rb +40 -0
  58. data/spec/cucumber_f_m/feature_all_tags_to_scenario_spec.rb +7 -0
  59. data/spec/cucumber_f_m/feature_file_manipulation_spec.rb +29 -0
  60. data/spec/cucumber_f_m/feature_module/background_spec.rb +30 -0
  61. data/spec/cucumber_f_m/feature_module/comment_spec.rb +23 -0
  62. data/spec/cucumber_f_m/feature_module/example_spec.rb +5 -0
  63. data/spec/cucumber_f_m/feature_module/info_spec.rb +30 -0
  64. data/spec/cucumber_f_m/feature_module/narrative_spec.rb +7 -0
  65. data/spec/cucumber_f_m/feature_module/scenario_outline_spec.rb +39 -0
  66. data/spec/cucumber_f_m/feature_module/scenario_spec.rb +33 -0
  67. data/spec/cucumber_f_m/feature_module/step_spec.rb +7 -0
  68. data/spec/cucumber_f_m/feature_module/tag_spec.rb +96 -0
  69. data/spec/cucumber_f_m/feature_spec.rb +229 -0
  70. data/spec/cucumber_f_m/tag_filter_spec.rb +191 -0
  71. data/spec/cucumber_feature_manager_spec.rb +59 -0
  72. data/spec/data/feature_manager/some_ruby_file.rb +0 -0
  73. data/spec/spec_helper.rb +1 -0
  74. metadata +141 -0
@@ -0,0 +1,36 @@
1
+ module Grit
2
+
3
+ class Actor
4
+ attr_reader :name
5
+ attr_reader :email
6
+
7
+ def initialize(name, email)
8
+ @name = name
9
+ @email = email
10
+ end
11
+ alias_method :to_s, :name
12
+
13
+ # Create an Actor from a string.
14
+ # +str+ is the string, which is expected to be in regular git format
15
+ #
16
+ # Format
17
+ # John Doe <jdoe@example.com>
18
+ #
19
+ # Returns Actor
20
+ def self.from_string(str)
21
+ case str
22
+ when /<.+>/
23
+ m, name, email = *str.match(/(.*) <(.+?)>/)
24
+ return self.new(name, email)
25
+ else
26
+ return self.new(str, nil)
27
+ end
28
+ end
29
+
30
+ # Pretty object inspection
31
+ def inspect
32
+ %Q{#<Grit::Actor "#{@name} <#{@email}>">}
33
+ end
34
+ end # Actor
35
+
36
+ end # Grit
@@ -0,0 +1,61 @@
1
+ module Grit
2
+
3
+ class Blame
4
+
5
+ attr_reader :lines
6
+
7
+ def initialize(repo, file, commit)
8
+ @repo = repo
9
+ @file = file
10
+ @commit = commit
11
+ @lines = []
12
+ load_blame
13
+ end
14
+
15
+ def load_blame
16
+ output = @repo.git.blame({'p' => true}, @commit, '--', @file)
17
+ process_raw_blame(output)
18
+ end
19
+
20
+ def process_raw_blame(output)
21
+ lines, final = [], []
22
+ info, commits = {}, {}
23
+
24
+ # process the output
25
+ output.split("\n").each do |line|
26
+ if line[0, 1] == "\t"
27
+ lines << line[1, line.size]
28
+ elsif m = /^(\w{40}) (\d+) (\d+)/.match(line)
29
+ if !commits[m[1]]
30
+ commits[m[1]] = @repo.commit(m[1])
31
+ end
32
+ info[m[3].to_i] = [commits[m[1]], m[2].to_i]
33
+ end
34
+ end
35
+
36
+ # get it together
37
+ info.sort.each do |lineno, commit|
38
+ final << BlameLine.new(lineno, commit[1], commit[0], lines[lineno - 1])
39
+ end
40
+
41
+ @lines = final
42
+ end
43
+
44
+ # Pretty object inspection
45
+ def inspect
46
+ %Q{#<Grit::Blame "#{@file} <#{@commit}>">}
47
+ end
48
+
49
+ class BlameLine
50
+ attr_accessor :lineno, :oldlineno, :commit, :line
51
+ def initialize(lineno, oldlineno, commit, line)
52
+ @lineno = lineno
53
+ @oldlineno = oldlineno
54
+ @commit = commit
55
+ @line = line
56
+ end
57
+ end
58
+
59
+ end # Blame
60
+
61
+ end # Grit
@@ -0,0 +1,126 @@
1
+ module Grit
2
+
3
+ class Blob
4
+ DEFAULT_MIME_TYPE = "text/plain"
5
+
6
+ attr_reader :id
7
+ attr_reader :mode
8
+ attr_reader :name
9
+
10
+ # Create an unbaked Blob containing just the specified attributes
11
+ # +repo+ is the Repo
12
+ # +atts+ is a Hash of instance variable data
13
+ #
14
+ # Returns Grit::Blob (unbaked)
15
+ def self.create(repo, atts)
16
+ self.allocate.create_initialize(repo, atts)
17
+ end
18
+
19
+ # Initializer for Blob.create
20
+ # +repo+ is the Repo
21
+ # +atts+ is a Hash of instance variable data
22
+ #
23
+ # Returns Grit::Blob (unbaked)
24
+ def create_initialize(repo, atts)
25
+ @repo = repo
26
+ atts.each do |k, v|
27
+ instance_variable_set("@#{k}".to_sym, v)
28
+ end
29
+ self
30
+ end
31
+
32
+ # The size of this blob in bytes
33
+ #
34
+ # Returns Integer
35
+ def size
36
+ @size ||= @repo.git.cat_file({:s => true}, id).chomp.to_i
37
+ end
38
+
39
+ # The binary contents of this blob.
40
+ #
41
+ # Returns String
42
+ def data
43
+ @data ||= @repo.git.cat_file({:p => true}, id)
44
+ end
45
+
46
+ # The mime type of this file (based on the filename)
47
+ #
48
+ # Returns String
49
+ def mime_type
50
+ guesses = MIME::Types.type_for(self.name) rescue []
51
+ guesses.first ? guesses.first.simplified : DEFAULT_MIME_TYPE
52
+ end
53
+
54
+ # The blame information for the given file at the given commit
55
+ #
56
+ # Returns Array: [Grit::Commit, Array: [<line>]]
57
+ def self.blame(repo, commit, file)
58
+ data = repo.git.blame({:p => true}, commit, '--', file)
59
+
60
+ commits = {}
61
+ blames = []
62
+ info = nil
63
+
64
+ data.split("\n").each do |line|
65
+ parts = line.split(/\s+/, 2)
66
+ case parts.first
67
+ when /^[0-9A-Fa-f]{40}$/
68
+ case line
69
+ when /^([0-9A-Fa-f]{40}) (\d+) (\d+) (\d+)$/
70
+ _, id, origin_line, final_line, group_lines = *line.match(/^([0-9A-Fa-f]{40}) (\d+) (\d+) (\d+)$/)
71
+ info = {:id => id}
72
+ blames << [nil, []]
73
+ when /^([0-9A-Fa-f]{40}) (\d+) (\d+)$/
74
+ _, id, origin_line, final_line = *line.match(/^([0-9A-Fa-f]{40}) (\d+) (\d+)$/)
75
+ info = {:id => id}
76
+ end
77
+ when /^(author|committer)/
78
+ case parts.first
79
+ when /^(.+)-mail$/
80
+ info["#{$1}_email".intern] = parts.last
81
+ when /^(.+)-time$/
82
+ info["#{$1}_date".intern] = Time.at(parts.last.to_i)
83
+ when /^(author|committer)$/
84
+ info[$1.intern] = parts.last
85
+ end
86
+ when /^filename/
87
+ info[:filename] = parts.last
88
+ when /^summary/
89
+ info[:summary] = parts.last
90
+ when ''
91
+ c = commits[info[:id]]
92
+ unless c
93
+ c = Commit.create(repo, :id => info[:id],
94
+ :author => Actor.from_string(info[:author] + ' ' + info[:author_email]),
95
+ :authored_date => info[:author_date],
96
+ :committer => Actor.from_string(info[:committer] + ' ' + info[:committer_email]),
97
+ :committed_date => info[:committer_date],
98
+ :message => info[:summary])
99
+ commits[info[:id]] = c
100
+ end
101
+ _, text = *line.match(/^\t(.*)$/)
102
+ blames.last[0] = c
103
+ blames.last[1] << text
104
+ info = nil
105
+ end
106
+ end
107
+
108
+ blames
109
+ end
110
+
111
+ def basename
112
+ File.basename(name)
113
+ end
114
+
115
+ # Pretty object inspection
116
+ def inspect
117
+ %Q{#<Grit::Blob "#{@id}">}
118
+ end
119
+
120
+ # Compares blobs by name
121
+ def <=>(other)
122
+ name <=> other.name
123
+ end
124
+ end # Blob
125
+
126
+ end # Grit
@@ -0,0 +1,247 @@
1
+ module Grit
2
+
3
+ class Commit
4
+ attr_reader :id
5
+ lazy_reader :parents
6
+ lazy_reader :tree
7
+ lazy_reader :author
8
+ lazy_reader :authored_date
9
+ lazy_reader :committer
10
+ lazy_reader :committed_date
11
+ lazy_reader :message
12
+ lazy_reader :short_message
13
+ lazy_reader :author_string
14
+
15
+ # Instantiate a new Commit
16
+ # +id+ is the id of the commit
17
+ # +parents+ is an array of commit ids (will be converted into Commit instances)
18
+ # +tree+ is the correspdonding tree id (will be converted into a Tree object)
19
+ # +author+ is the author string
20
+ # +authored_date+ is the authored Time
21
+ # +committer+ is the committer string
22
+ # +committed_date+ is the committed Time
23
+ # +message+ is an array of commit message lines
24
+ #
25
+ # Returns Grit::Commit (baked)
26
+ def initialize(repo, id, parents, tree, author, authored_date, committer, committed_date, message)
27
+ @repo = repo
28
+ @id = id
29
+ @parents = parents.map { |p| Commit.create(repo, :id => p) }
30
+ @tree = Tree.create(repo, :id => tree)
31
+ @author = author
32
+ @authored_date = authored_date
33
+ @committer = committer
34
+ @committed_date = committed_date
35
+ @message = message.join("\n")
36
+ @short_message = message.select { |x| !x.strip.empty? }[0] || ''
37
+ end
38
+
39
+ def id_abbrev
40
+ @id_abbrev ||= @repo.git.rev_parse({}, self.id).chomp[0, 7]
41
+ end
42
+
43
+ # Create an unbaked Commit containing just the specified attributes
44
+ # +repo+ is the Repo
45
+ # +atts+ is a Hash of instance variable data
46
+ #
47
+ # Returns Grit::Commit (unbaked)
48
+ def self.create(repo, atts)
49
+ self.allocate.create_initialize(repo, atts)
50
+ end
51
+
52
+ # Initializer for Commit.create
53
+ # +repo+ is the Repo
54
+ # +atts+ is a Hash of instance variable data
55
+ #
56
+ # Returns Grit::Commit (unbaked)
57
+ def create_initialize(repo, atts)
58
+ @repo = repo
59
+ atts.each do |k, v|
60
+ instance_variable_set("@#{k}", v)
61
+ end
62
+ self
63
+ end
64
+
65
+ def lazy_source
66
+ self.class.find_all(@repo, @id, {:max_count => 1}).first
67
+ end
68
+
69
+ # Count the number of commits reachable from this ref
70
+ # +repo+ is the Repo
71
+ # +ref+ is the ref from which to begin (SHA1 or name)
72
+ #
73
+ # Returns Integer
74
+ def self.count(repo, ref)
75
+ repo.git.rev_list({}, ref).size / 41
76
+ end
77
+
78
+ # Find all commits matching the given criteria.
79
+ # +repo+ is the Repo
80
+ # +ref+ is the ref from which to begin (SHA1 or name) or nil for --all
81
+ # +options+ is a Hash of optional arguments to git
82
+ # :max_count is the maximum number of commits to fetch
83
+ # :skip is the number of commits to skip
84
+ #
85
+ # Returns Grit::Commit[] (baked)
86
+ def self.find_all(repo, ref, options = {})
87
+ allowed_options = [:max_count, :skip, :since]
88
+
89
+ default_options = {:pretty => "raw"}
90
+ actual_options = default_options.merge(options)
91
+
92
+ if ref
93
+ output = repo.git.rev_list(actual_options, ref)
94
+ else
95
+ output = repo.git.rev_list(actual_options.merge(:all => true))
96
+ end
97
+
98
+ self.list_from_string(repo, output)
99
+ rescue Grit::GitRuby::Repository::NoSuchShaFound
100
+ []
101
+ end
102
+
103
+ # Parse out commit information into an array of baked Commit objects
104
+ # +repo+ is the Repo
105
+ # +text+ is the text output from the git command (raw format)
106
+ #
107
+ # Returns Grit::Commit[] (baked)
108
+ #
109
+ # really should re-write this to be more accepting of non-standard commit messages
110
+ # - it broke when 'encoding' was introduced - not sure what else might show up
111
+ #
112
+ def self.list_from_string(repo, text)
113
+ lines = text.split("\n")
114
+
115
+ commits = []
116
+
117
+ while !lines.empty?
118
+ id = lines.shift.split.last
119
+ tree = lines.shift.split.last
120
+
121
+ parents = []
122
+ parents << lines.shift.split.last while lines.first =~ /^parent/
123
+
124
+ author, authored_date = self.actor(lines.shift)
125
+ committer, committed_date = self.actor(lines.shift)
126
+
127
+ # not doing anything with this yet, but it's sometimes there
128
+ encoding = lines.shift.split.last if lines.first =~ /^encoding/
129
+
130
+ lines.shift
131
+
132
+ message_lines = []
133
+ message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
134
+
135
+ lines.shift while lines.first && lines.first.empty?
136
+
137
+ commits << Commit.new(repo, id, parents, tree, author, authored_date, committer, committed_date, message_lines)
138
+ end
139
+
140
+ commits
141
+ end
142
+
143
+ # Show diffs between two trees:
144
+ # +repo+ is the Repo
145
+ # +a+ is a named commit
146
+ # +b+ is an optional named commit. Passing an array assumes you
147
+ # wish to omit the second named commit and limit the diff to the
148
+ # given paths.
149
+ # +paths* is an array of paths to limit the diff.
150
+ #
151
+ # Returns Grit::Diff[] (baked)
152
+ def self.diff(repo, a, b = nil, paths = [])
153
+ if b.is_a?(Array)
154
+ paths = b
155
+ b = nil
156
+ end
157
+ paths.unshift("--") unless paths.empty?
158
+ paths.unshift(b) unless b.nil?
159
+ paths.unshift(a)
160
+ text = repo.git.diff({:full_index => true}, *paths)
161
+ Diff.list_from_string(repo, text)
162
+ end
163
+
164
+ def show
165
+ if parents.size > 1
166
+ diff = @repo.git.native("diff #{parents[0].id}...#{parents[1].id}", {:full_index => true})
167
+ else
168
+ diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
169
+ end
170
+
171
+ if diff =~ /diff --git a/
172
+ diff = diff.sub(/.+?(diff --git a)/m, '\1')
173
+ else
174
+ diff = ''
175
+ end
176
+ Diff.list_from_string(@repo, diff)
177
+ end
178
+
179
+ def diffs
180
+ if parents.empty?
181
+ show
182
+ else
183
+ self.class.diff(@repo, parents.first.id, @id)
184
+ end
185
+ end
186
+
187
+ def stats
188
+ stats = @repo.commit_stats(self.sha, 1)[0][-1]
189
+ end
190
+
191
+ # Convert this Commit to a String which is just the SHA1 id
192
+ def to_s
193
+ @id
194
+ end
195
+
196
+ def sha
197
+ @id
198
+ end
199
+
200
+ def date
201
+ @committed_date
202
+ end
203
+
204
+ def to_patch
205
+ @repo.git.format_patch({'1' => true, :stdout => true}, to_s)
206
+ end
207
+
208
+ # Pretty object inspection
209
+ def inspect
210
+ %Q{#<Grit::Commit "#{@id}">}
211
+ end
212
+
213
+ # private
214
+
215
+ # Parse out the actor (author or committer) info
216
+ #
217
+ # Returns [String (actor name and email), Time (acted at time)]
218
+ def self.actor(line)
219
+ m, actor, epoch = *line.match(/^.+? (.*) (\d+) .*$/)
220
+ [Actor.from_string(actor), Time.at(epoch.to_i)]
221
+ end
222
+
223
+ def author_string
224
+ "%s <%s> %s %+05d" % [author.name, author.email, authored_date.to_i, 800]
225
+ end
226
+
227
+ def to_hash
228
+ {
229
+ 'id' => id,
230
+ 'parents' => parents.map { |p| { 'id' => p.id } },
231
+ 'tree' => tree.id,
232
+ 'message' => message,
233
+ 'author' => {
234
+ 'name' => author.name,
235
+ 'email' => author.email
236
+ },
237
+ 'committer' => {
238
+ 'name' => committer.name,
239
+ 'email' => committer.email
240
+ },
241
+ 'authored_date' => authored_date.xmlschema,
242
+ 'committed_date' => committed_date.xmlschema,
243
+ }
244
+ end
245
+ end # Commit
246
+
247
+ end # Grit