mattwynne-cucover 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.markdown +19 -0
  2. data/bin/cucover +5 -0
  3. data/lib/cucover.rb +110 -0
  4. metadata +75 -0
data/README.markdown ADDED
@@ -0,0 +1,19 @@
1
+ # Cucover
2
+
3
+ Cucover is a thin wrapper for [Cucumber](http://github.com/aslakhellesoy/cucumber/tree/master) which makes it lazy.
4
+
5
+ What does it mean for Cucumber to be lazy? It will only run a feature if it needs to.
6
+
7
+ How does it decide whether it needs to run a feature? Every time you run a feature using Cucover, it watches the code in your application that is executed, and remembers. The next time you run Cucover, it skips a feature if the source files (or the feature itself) have not been changed since it was last run.
8
+
9
+ ## Installation and Usage
10
+
11
+ There's no gem for now, so just clone the code from github.
12
+
13
+ To run your features lazily, just use the cucover binary instead of cucumber. Use the same command-line options as usual, they are all passed directly to cucumber. No magic to see here, just a little gentle duck-punching.
14
+
15
+ ## Limitations
16
+
17
+ * Cucover uses RCov to watch the code executed by each feature. RCov does not report ERB view templates so Rails views, for example, that are touched will not cause any features to be re-run.
18
+ * Anything that runs out of process will not be covered, and therefore cannot trigger a re-run, so if you use Cucumber to drive Selenium, for example, you're out of luck.
19
+ * This is very new and experimental. There may be bugs. Feedback is welcome via github messages.
data/bin/cucover ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'cucumber'
4
+ require File.expand_path(File.dirname(__FILE__) + '../../lib/cucover')
5
+ load Cucumber::BINARY
data/lib/cucover.rb ADDED
@@ -0,0 +1,110 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rubygems'
5
+ require 'rcov'
6
+
7
+ module Cucover
8
+
9
+ class SourceFileCache
10
+ def initialize(feature_file)
11
+ @feature_file = feature_file
12
+ end
13
+
14
+ def save(analyzed_files)
15
+ FileUtils.mkdir_p File.dirname(cache_filename)
16
+ File.open(cache_filename, "w") do |file|
17
+ file.puts analyzed_files
18
+ end
19
+ end
20
+
21
+ def exists?
22
+ File.exist?(cache_filename)
23
+ end
24
+
25
+ def dirty_files
26
+ source_files.select do |source_file|
27
+ File.mtime(Dir.pwd + '/' + source_file.strip) > time
28
+ end
29
+ end
30
+
31
+ def time
32
+ File.mtime(cache_filename)
33
+ end
34
+
35
+ private
36
+
37
+ def source_files
38
+ result = []
39
+ File.open(cache_filename, "r") do |file|
40
+ file.each_line do |line|
41
+ result.push line
42
+ end
43
+ end
44
+ result
45
+ end
46
+
47
+ def cache_filename
48
+ @feature_file.gsub /([^\/]*\.feature)/, '.coverage/\1'
49
+ end
50
+ end
51
+
52
+ module LazyFeature
53
+
54
+ def accept(visitor)
55
+ return unless dirty?
56
+ analyzer.run_hooked do
57
+ super
58
+ end
59
+ source_files_cache.save analyzed_files
60
+ end
61
+
62
+ private
63
+
64
+ def dirty?
65
+ return true unless source_files_cache.exists?
66
+ return true if File.mtime(@file) >= source_files_cache.time
67
+ not source_files_cache.dirty_files.empty?
68
+ end
69
+
70
+ def source_files_cache
71
+ @source_files_cache ||= SourceFileCache.new(@file)
72
+ end
73
+
74
+ def source_files
75
+ analyzed_files
76
+ end
77
+
78
+ def analyzed_files
79
+ normalized_files = analyzer.analyzed_files.map{ |f| File.expand_path(f).gsub(/^#{Dir.pwd}\//, '') }
80
+ interesting_files = normalized_files.reject{ |f| boring?(f) }
81
+ interesting_files.sort
82
+ end
83
+
84
+ def boring?(file)
85
+ (file.match /gem/) || (file.match /vendor/) || (file.match /lib\/ruby/)
86
+ end
87
+
88
+ def analyzer
89
+ @analyzer ||= Rcov::CodeCoverageAnalyzer.new
90
+ end
91
+ end
92
+
93
+ module LazyFeatures
94
+ def add_feature(feature)
95
+ super feature.extend(LazyFeature)
96
+ end
97
+ end
98
+ end
99
+
100
+ module Cucumber
101
+ module Ast
102
+ class Features
103
+ class << self
104
+ def new(*args)
105
+ super(*args).extend(Cucover::LazyFeatures)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mattwynne-cucover
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Matt Wynne
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-18 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: cucumber
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0.2"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rcov
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.8.1.5
34
+ version:
35
+ description: Cucover is a thin wrapper for Cucumber which makes it lazy.
36
+ email: matt@mattwynne.net
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - lib/cucover.rb
45
+ - bin/cucover
46
+ - README.markdown
47
+ has_rdoc: false
48
+ homepage: http://github.com/mattwynne/cucover
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ - bin
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project: cucover
70
+ rubygems_version: 1.2.0
71
+ signing_key:
72
+ specification_version: 2
73
+ summary: Cucover is a thin wrapper for Cucumber which makes it lazy.
74
+ test_files: []
75
+