abstract_type 0.0.2 → 0.0.3

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/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format progress
3
+ --profile
4
+ --order random
@@ -1,19 +1,21 @@
1
1
  language: ruby
2
2
  before_install: gem install bundler
3
- bundler_args: --without yard guard
4
- script: "bundle exec rake spec"
3
+ bundler_args: --without yard guard benchmarks
4
+ script: "bundle exec rake ci"
5
5
  rvm:
6
+ - ree
6
7
  - 1.8.7
7
8
  - 1.9.2
8
9
  - 1.9.3
10
+ - 2.0.0
11
+ - ruby-head
9
12
  - jruby-18mode
10
13
  - jruby-19mode
14
+ - jruby-head
11
15
  - rbx-18mode
12
16
  - rbx-19mode
13
- - ree
14
- - ruby-head
15
- - jruby-head
16
17
  notifications:
18
+ irc: "irc.freenode.org#datamapper"
17
19
  email:
18
20
  - dan.kubb@gmail.com
19
21
  - mbj@seonic.net
data/Gemfile CHANGED
@@ -4,56 +4,5 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
- group :yard do
8
- gem 'yard', '~> 0.8.3'
9
- gem 'redcarpet', '~> 2.2.2', :platforms => [ :mri, :rbx ]
10
- end
11
-
12
- group :guard do
13
- gem 'guard', '~> 1.5.4'
14
- gem 'guard-bundler', '~> 1.0.0'
15
- gem 'guard-rspec', '~> 1.2.1'
16
- end
17
-
18
- group :benchmarks do
19
- gem 'rbench', '~> 0.2.3'
20
- end
21
-
22
- platform :jruby do
23
- group :jruby do
24
- gem 'jruby-openssl', '~> 0.7.4'
25
- end
26
- end
27
-
28
- group :metrics do
29
- gem 'flay', '~> 1.4.3'
30
- gem 'flog', '~> 2.5.3'
31
- gem 'reek', '~> 1.2.8', :github => 'dkubb/reek'
32
- gem 'roodi', '~> 2.1.0'
33
- gem 'yardstick', '~> 0.8.0'
34
-
35
- platforms :ruby_18, :ruby_19 do
36
- # this indirectly depends on ffi which does not build on ruby-head
37
- gem 'yard-spellcheck', '~> 0.1.5'
38
- end
39
-
40
- platforms :mri_18 do
41
- gem 'arrayfields', '~> 4.7.4' # for metric_fu
42
- gem 'fattr', '~> 2.2.0' # for metric_fu
43
- gem 'heckle', '~> 1.4.3'
44
- gem 'json', '~> 1.7.3' # for metric_fu rake task
45
- gem 'map', '~> 6.2.0' # for metric_fu
46
- gem 'metric_fu', '~> 2.1.1'
47
- gem 'mspec', '~> 1.5.17'
48
- gem 'rcov', '~> 1.0.0'
49
- gem 'ruby2ruby', '= 1.2.2' # for heckle
50
- end
51
-
52
- platforms :ruby_19 do
53
- gem 'simplecov', '~> 0.7.1'
54
- end
55
-
56
- platforms :rbx do
57
- gem 'pelusa', '~> 0.2.1'
58
- end
59
- end
7
+ gem 'devtools', :git => 'https://github.com/datamapper/devtools.git'
8
+ eval File.read('Gemfile.devtools')
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ group :development do
4
+ gem 'rake', '~> 10.0.3'
5
+ gem 'rspec', '~> 2.12.0'
6
+ gem 'yard', '~> 0.8.4.1'
7
+ end
8
+
9
+ group :yard do
10
+ gem 'redcarpet', '~> 2.2.2', :platforms => [ :mri, :rbx ]
11
+ end
12
+
13
+ group :guard do
14
+ gem 'guard', '~> 1.6.2'
15
+ gem 'guard-bundler', '~> 1.0.0'
16
+ gem 'guard-rspec', '~> 2.3.3'
17
+
18
+ # file system change event handling
19
+ gem 'rb-fchange', '~> 0.0.6', :require => false
20
+ gem 'rb-fsevent', '~> 0.9.3', :require => false
21
+ gem 'rb-inotify', '~> 0.9.0', :require => false
22
+
23
+ # Remove this one https://github.com/guard/listen/pull/78 is released
24
+ gem 'listen', '~> 0.7.2', :git => 'https://github.com/guard/listen.git'
25
+
26
+ # notification handling
27
+ gem 'libnotify', '~> 0.8.0', :require => false
28
+ gem 'rb-notifu', '~> 0.0.4', :require => false
29
+ gem 'terminal-notifier-guard', '~> 1.5.3', :require => false
30
+ end
31
+
32
+ group :metrics do
33
+ gem 'flay', '~> 1.4.3'
34
+ gem 'flog', '~> 2.5.3'
35
+ gem 'reek', '~> 1.2.13', :git => 'https://github.com/troessner/reek.git', :ref => 'ef77fcecaa21c9ebcbe4d9a79d41b0e70196bf18'
36
+ gem 'roodi', '~> 2.2.0'
37
+ gem 'yardstick', '~> 0.9.2'
38
+
39
+ platforms :ruby_18, :ruby_19 do
40
+ # this indirectly depends on ffi which does not build on ruby-head
41
+ gem 'yard-spellcheck', '~> 0.1.5'
42
+ end
43
+
44
+ platforms :mri_19, :rbx do
45
+ # gem 'mutant', '~> 0.2.16'
46
+ end
47
+
48
+ platforms :mri_19 do
49
+ gem 'simplecov', '~> 0.7.1'
50
+ end
51
+
52
+ platforms :rbx do
53
+ gem 'pelusa', '~> 0.2.2'
54
+ end
55
+ end
56
+
57
+ group :benchmarks do
58
+ gem 'rbench', '~> 0.2.3'
59
+ end
60
+
61
+ platform :jruby do
62
+ group :jruby do
63
+ gem 'jruby-openssl', '~> 0.8.2'
64
+ end
65
+ end
data/README.md CHANGED
@@ -3,7 +3,7 @@ abstract_type
3
3
 
4
4
  [![Build Status](https://secure.travis-ci.org/dkubb/abstract_type.png?branch=master)](http://travis-ci.org/dkubb/abstract_type)
5
5
  [![Dependency Status](https://gemnasium.com/dkubb/abstract_type.png)](https://gemnasium.com/dkubb/abstract_type)
6
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/dkubb/abstract_type)
6
+ [![Code Climate](https://codeclimate.com/github/dkubb/abstract_type.png)](https://codeclimate.com/github/dkubb/abstract_type)
7
7
 
8
8
  This is a small standalone gem featuring a module ripped out from [veritas](https://github.com/dkubb/veritas).
9
9
  It allows to declare abstract_type classes and modules in an unobstrusive way.
@@ -39,16 +39,16 @@ class Foo
39
39
  include AbstractType
40
40
 
41
41
  # Declare abstract instance method
42
- abstract :bar
42
+ abstract_method :bar
43
43
 
44
44
  # Declare abstract singleton method
45
- abstract_singleton_method :singleton_method
45
+ abstract_singleton_method :baz
46
46
  end
47
47
 
48
- Foo.new # raises NotImplementedError: Foo is an abstract type
49
- Foo.singleton_method # raises NotImplementedError: Foo.bar is not implemented
48
+ Foo.new # raises NotImplementedError: Foo is an abstract type
49
+ Foo.baz # raises NotImplementedError: Foo.baz is not implemented
50
50
 
51
- # Subclassing to allow instanciation
51
+ # Subclassing to allow instantiation
52
52
  class Baz < Foo; end
53
53
 
54
54
  object = Baz.new
@@ -60,7 +60,7 @@ Credits
60
60
  -------
61
61
 
62
62
  * Dan Kubb ([dkubb](https://github.com/dkubb))
63
- * Markus Schirp ([dkubb](https://github.com/mbj))
63
+ * Markus Schirp ([mbj](https://github.com/mbj))
64
64
 
65
65
  Contributing
66
66
  -------------
data/Rakefile CHANGED
@@ -1,9 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'rake'
4
+ require 'devtools'
4
5
 
5
- require File.expand_path('../lib/abstract_type/version', __FILE__)
6
-
7
- FileList['tasks/**/*.rake'].each { |task| import task }
8
-
9
- task :default => :spec
6
+ Devtools.init
@@ -15,6 +15,8 @@ Gem::Specification.new do |gem|
15
15
  gem.test_files = `git ls-files -- {spec}/*`.split($/)
16
16
  gem.extra_rdoc_files = %w[LICENSE README.md TODO]
17
17
 
18
- gem.add_development_dependency('rake', '~> 10.0.2')
18
+ gem.add_runtime_dependency('backports', '~> 2.8.2')
19
+
20
+ gem.add_development_dependency('rake', '~> 10.0.3')
19
21
  gem.add_development_dependency('rspec', '~> 1.3.2')
20
22
  end
@@ -1,3 +1,3 @@
1
1
  ---
2
- threshold: 18
3
- total_score: 35
2
+ threshold: 13
3
+ total_score: 25
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 8.9
2
+ threshold: 18.4
@@ -0,0 +1,3 @@
1
+ ---
2
+ name: abstract_type
3
+ namespace: AbstractType
@@ -46,7 +46,9 @@ UncommunicativeModuleName:
46
46
  - !ruby/regexp /[0-9]$/
47
47
  NestedIterators:
48
48
  ignore_iterators: []
49
- exclude: []
49
+ exclude: [
50
+ 'AbstractType::ClassMethods#create_abstract_singleton_method'
51
+ ]
50
52
  enabled: true
51
53
  max_allowed_nesting: 1
52
54
  LongMethod:
@@ -8,15 +8,16 @@ module AbstractType
8
8
  # @param [Module] descendant
9
9
  # the module or class including AbstractType
10
10
  #
11
- # @return [self]
11
+ # @return [undefined]
12
12
  #
13
13
  # @api private
14
14
  def self.included(descendant)
15
15
  super
16
16
  descendant.extend(ClassMethods)
17
- self
18
17
  end
19
18
 
19
+ private_class_method :included
20
+
20
21
  module ClassMethods
21
22
 
22
23
  # Instantiate a new object
@@ -89,11 +90,11 @@ module AbstractType
89
90
  #
90
91
  # @api private
91
92
  def create_abstract_singleton_method(name)
92
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
93
- def self.#{name}(*) # def self.name(*)
94
- raise NotImplementedError, "\#{inspect}.#{name} is not implemented" # raise NotImplementedError, '\#{inspect}.name is not implemented'
95
- end # end
96
- RUBY
93
+ singleton_class.class_eval do
94
+ define_method(name) do
95
+ raise NotImplementedError, "#{inspect}.#{name} is not implemented"
96
+ end
97
+ end
97
98
  end
98
99
 
99
100
  # Create abstract instance method
@@ -105,11 +106,9 @@ module AbstractType
105
106
  #
106
107
  # @api private
107
108
  def create_abstract_instance_method(name)
108
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
109
- def #{name}(*) # def name(*)
110
- raise NotImplementedError, "\#{self.class.inspect}##{name} is not implemented" # raise NotImplementedError, "\#{self.class.inspect}#name is not implemented"
111
- end # end
112
- RUBY
109
+ define_method(name) do
110
+ raise NotImplementedError, "#{self.class.inspect}##{name} is not implemented"
111
+ end
113
112
  end
114
113
 
115
114
  end # module ClassMethods
@@ -1,3 +1,8 @@
1
+ # encoding: utf-8
2
+
1
3
  module AbstractType
2
- VERSION = '0.0.2'.freeze
3
- end
4
+
5
+ # Released gem version
6
+ VERSION = '0.0.3'.freeze
7
+
8
+ end # module AbstractType
@@ -1,11 +1,25 @@
1
1
  # encoding: utf-8
2
2
 
3
+ if ENV['COVERAGE'] == 'true'
4
+ require 'simplecov'
5
+
6
+ SimpleCov.start do
7
+ command_name 'spec:unit'
8
+ add_filter 'config'
9
+ add_filter 'spec'
10
+ minimum_coverage 100
11
+ end
12
+ end
13
+
3
14
  require 'abstract_type'
4
- require 'spec'
5
- require 'spec/autorun'
15
+ require 'backports'
16
+ require 'rspec'
17
+ require 'rspec/autorun' if RUBY_VERSION < '1.9'
6
18
 
7
19
  # require spec support files and shared behavior
8
- Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each { |f| require f }
20
+ Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
21
+ require file
22
+ end
9
23
 
10
- Spec::Runner.configure do |config|
24
+ RSpec.configure do |config|
11
25
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'rbconfig'
2
4
 
3
5
  ::Config = RbConfig unless defined?(::Config)
@@ -3,31 +3,29 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe AbstractType::ClassMethods, '#abstract_method' do
6
- subject { object.some_method }
6
+ subject { object.abstract_method(:some_method) }
7
7
 
8
- let(:abstract_type) do
9
- Class.new do
10
- include AbstractType
11
-
12
- abstract_method :some_method
13
- end
14
- end
15
-
16
- let(:class_under_test) do
17
- Class.new(abstract_type)
18
- end
8
+ let(:object) { Class.new { include AbstractType } }
9
+ let(:subclass) { Class.new(object) }
19
10
 
20
11
  before do
21
- TheClassName = class_under_test
12
+ Subclass = subclass
22
13
  end
23
14
 
24
15
  after do
25
- Object.class_eval { remove_const(:TheClassName) }
16
+ Object.class_eval { remove_const(:Subclass) }
26
17
  end
27
18
 
28
- let(:object) { class_under_test.new }
19
+ it { should equal(object) }
29
20
 
30
21
  it 'creates an abstract method' do
31
- expect { subject }.to raise_error(NotImplementedError,'TheClassName#some_method is not implemented')
22
+ expect { subject }.to change { subclass.method_defined?(:some_method) }.
23
+ from(false).
24
+ to(true)
25
+ end
26
+
27
+ it 'creates a method that raises an exception' do
28
+ subject
29
+ expect { subclass.new.some_method }.to raise_error(NotImplementedError, 'Subclass#some_method is not implemented')
32
30
  end
33
31
  end
@@ -2,26 +2,30 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe AbstractType::ClassMethods, '#abstract_method' do
6
- subject { object.some_method }
5
+ describe AbstractType::ClassMethods, '#abstract_singleton_method' do
6
+ subject { object.abstract_singleton_method(:some_method) }
7
7
 
8
- let(:object) do
9
- Class.new do
10
- include AbstractType
11
-
12
- abstract_singleton_method :some_method
13
- end
14
- end
8
+ let(:object) { Class.new { include AbstractType } }
9
+ let(:subclass) { Class.new(object) }
15
10
 
16
11
  before do
17
- TheClassName = object
12
+ Subclass = subclass
18
13
  end
19
14
 
20
15
  after do
21
- Object.class_eval { remove_const(:TheClassName) }
16
+ Object.class_eval { remove_const(:Subclass) }
22
17
  end
23
18
 
19
+ it { should equal(object) }
20
+
24
21
  it 'creates an abstract method' do
25
- expect { subject }.to raise_error(NotImplementedError, 'TheClassName.some_method is not implemented')
22
+ expect { subject }.to change { subclass.respond_to?(:some_method) }.
23
+ from(false).
24
+ to(true)
25
+ end
26
+
27
+ it 'creates a method that raises an exception' do
28
+ subject
29
+ expect { subclass.some_method }.to raise_error(NotImplementedError, 'Subclass.some_method is not implemented')
26
30
  end
27
31
  end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe AbstractType, '.included' do
6
+ subject { object }
7
+
8
+ let(:object) { described_class }
9
+ let(:klass) { Class.new }
10
+
11
+ it 'extends the klass' do
12
+ klass.singleton_class.should_not include(described_class::ClassMethods)
13
+ klass.send(:include, subject)
14
+ klass.singleton_class.should include(described_class::ClassMethods)
15
+ end
16
+
17
+ it 'delegates to the ancestor' do
18
+ included_ancestor = false
19
+ subject.extend Module.new {
20
+ define_method(:included) { |_| included_ancestor = true }
21
+ }
22
+ expect {
23
+ klass.send(:include, subject)
24
+ }.to change { included_ancestor }.from(false).to(true)
25
+ end
26
+ end
metadata CHANGED
@@ -1,70 +1,80 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: abstract_type
3
- version: !ruby/object:Gem::Version
4
- hash: 27
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 2
10
- version: 0.0.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Dan Kubb
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-11-26 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: rake
12
+ date: 2013-02-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: backports
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.8.2
22
+ type: :runtime
22
23
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
24
25
  none: false
25
- requirements:
26
+ requirements:
26
27
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 75
29
- segments:
30
- - 10
31
- - 0
32
- - 2
33
- version: 10.0.2
28
+ - !ruby/object:Gem::Version
29
+ version: 2.8.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 10.0.3
34
38
  type: :development
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: rspec
38
39
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
40
41
  none: false
41
- requirements:
42
+ requirements:
42
43
  - - ~>
43
- - !ruby/object:Gem::Version
44
- hash: 31
45
- segments:
46
- - 1
47
- - 3
48
- - 2
44
+ - !ruby/object:Gem::Version
45
+ version: 10.0.3
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
49
53
  version: 1.3.2
50
54
  type: :development
51
- version_requirements: *id002
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.2
52
62
  description: Module to declare abstract classes and methods
53
- email:
63
+ email:
54
64
  - dan.kubb@gmail.com
55
65
  executables: []
56
-
57
66
  extensions: []
58
-
59
- extra_rdoc_files:
67
+ extra_rdoc_files:
60
68
  - LICENSE
61
69
  - README.md
62
70
  - TODO
63
- files:
71
+ files:
64
72
  - .gitignore
73
+ - .rspec
65
74
  - .rvmrc
66
75
  - .travis.yml
67
76
  - Gemfile
77
+ - Gemfile.devtools
68
78
  - Guardfile
69
79
  - LICENSE
70
80
  - README.md
@@ -73,66 +83,46 @@ files:
73
83
  - abstract_type.gemspec
74
84
  - config/flay.yml
75
85
  - config/flog.yml
86
+ - config/mutant.yml
76
87
  - config/roodi.yml
77
88
  - config/site.reek
78
89
  - config/yardstick.yml
79
90
  - lib/abstract_type.rb
80
91
  - lib/abstract_type/version.rb
81
- - spec/rcov.opts
82
92
  - spec/shared/command_method_behavior.rb
83
93
  - spec/shared/each_method_behaviour.rb
84
94
  - spec/shared/hash_method_behavior.rb
85
95
  - spec/shared/idempotent_method_behavior.rb
86
96
  - spec/shared/invertible_method_behaviour.rb
87
- - spec/spec.opts
88
97
  - spec/spec_helper.rb
89
98
  - spec/support/config_alias.rb
90
99
  - spec/unit/abstract_type/class_methods/abstract_method_spec.rb
91
100
  - spec/unit/abstract_type/class_methods/abstract_singleton_method_spec.rb
101
+ - spec/unit/abstract_type/class_methods/included_spec.rb
92
102
  - spec/unit/abstract_type/class_methods/new_spec.rb
93
- - tasks/metrics/ci.rake
94
- - tasks/metrics/flay.rake
95
- - tasks/metrics/flog.rake
96
- - tasks/metrics/heckle.rake
97
- - tasks/metrics/metric_fu.rake
98
- - tasks/metrics/reek.rake
99
- - tasks/metrics/roodi.rake
100
- - tasks/metrics/yardstick.rake
101
- - tasks/spec.rake
102
- - tasks/yard.rake
103
103
  homepage: https://github.com/dkubb/abstract_type
104
104
  licenses: []
105
-
106
105
  post_install_message:
107
106
  rdoc_options: []
108
-
109
- require_paths:
107
+ require_paths:
110
108
  - lib
111
- required_ruby_version: !ruby/object:Gem::Requirement
109
+ required_ruby_version: !ruby/object:Gem::Requirement
112
110
  none: false
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- hash: 3
117
- segments:
118
- - 0
119
- version: "0"
120
- required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
116
  none: false
122
- requirements:
123
- - - ">="
124
- - !ruby/object:Gem::Version
125
- hash: 3
126
- segments:
127
- - 0
128
- version: "0"
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
129
121
  requirements: []
130
-
131
122
  rubyforge_project:
132
- rubygems_version: 1.8.24
123
+ rubygems_version: 1.8.25
133
124
  signing_key:
134
125
  specification_version: 3
135
126
  summary: Module to declare abstract classes and methods
136
127
  test_files: []
137
-
138
128
  has_rdoc:
@@ -1,7 +0,0 @@
1
- --exclude-only "spec/,^/"
2
- --sort coverage
3
- --callsites
4
- --xrefs
5
- --profile
6
- --text-summary
7
- --failure-threshold 100
@@ -1,3 +0,0 @@
1
- --color
2
- --loadby random
3
- --format profile
@@ -1,9 +0,0 @@
1
- # encoding: utf-8
2
-
3
- desc 'Run metrics with Heckle'
4
- task :ci => %w[ ci:metrics metrics:heckle ]
5
-
6
- namespace :ci do
7
- desc 'Run metrics (except heckle) and spec'
8
- task :metrics => %w[ spec metrics:verify_measurements metrics:flog metrics:flay metrics:reek metrics:roodi metrics:all ]
9
- end
@@ -1,45 +0,0 @@
1
- # encoding: utf-8
2
-
3
- begin
4
- require 'flay'
5
- require 'yaml'
6
-
7
- config = YAML.load_file(File.expand_path('../../../config/flay.yml', __FILE__)).freeze
8
- threshold = config.fetch('threshold').to_i
9
- total_score = config.fetch('total_score').to_f
10
- files = Flay.expand_dirs_to_files(config.fetch('path', 'lib')).sort
11
-
12
- namespace :metrics do
13
- # original code by Marty Andrews:
14
- # http://blog.martyandrews.net/2009/05/enforcing-ruby-code-quality.html
15
- desc 'Analyze for code duplication'
16
- task :flay do
17
- # run flay once without a threshold to ensure the max mass matches the threshold
18
- flay = Flay.new(:fuzzy => false, :verbose => false, :mass => 0)
19
- flay.process(*files)
20
-
21
- max = (flay.masses.map { |hash, mass| mass.to_f / flay.hashes[hash].size }.max) || 0
22
- unless max >= threshold
23
- raise "Adjust flay threshold down to #{max}"
24
- end
25
-
26
- total = flay.masses.reduce(0.0) { |total, (hash, mass)| total + (mass.to_f / flay.hashes[hash].size) }
27
- unless total == total_score
28
- raise "Flay total is now #{total}, but expected #{total_score}"
29
- end
30
-
31
- # run flay a second time with the threshold set
32
- flay = Flay.new(:fuzzy => false, :verbose => false, :mass => threshold.succ)
33
- flay.process(*files)
34
-
35
- if flay.masses.any?
36
- flay.report
37
- raise "#{flay.masses.size} chunks of code have a duplicate mass > #{threshold}"
38
- end
39
- end
40
- end
41
- rescue LoadError
42
- task :flay do
43
- $stderr.puts 'Flay is not available. In order to run flay, you must: gem install flay'
44
- end
45
- end
@@ -1,49 +0,0 @@
1
- # encoding: utf-8
2
-
3
- begin
4
- require 'flog'
5
- require 'yaml'
6
-
7
- class Float
8
- def round_to(n)
9
- (self * 10**n).round.to_f * 10**-n
10
- end
11
- end
12
-
13
- config = YAML.load_file(File.expand_path('../../../config/flog.yml', __FILE__)).freeze
14
- threshold = config.fetch('threshold').to_f.round_to(1)
15
-
16
- namespace :metrics do
17
- # original code by Marty Andrews:
18
- # http://blog.martyandrews.net/2009/05/enforcing-ruby-code-quality.html
19
- desc 'Analyze for code complexity'
20
- task :flog do
21
- flog = Flog.new
22
- flog.flog Array(config.fetch('path', 'lib'))
23
-
24
- totals = flog.totals.select { |name, score| name[-5, 5] != '#none' }.
25
- map { |name, score| [ name, score.round_to(1) ] }.
26
- sort_by { |name, score| score }
27
-
28
- if totals.any?
29
- max = totals.last[1]
30
- unless max >= threshold
31
- raise "Adjust flog score down to #{max}"
32
- end
33
- end
34
-
35
- bad_methods = totals.select { |name, score| score > threshold }
36
- if bad_methods.any?
37
- bad_methods.reverse_each do |name, score|
38
- puts '%8.1f: %s' % [ score, name ]
39
- end
40
-
41
- raise "#{bad_methods.size} methods have a flog complexity > #{threshold}"
42
- end
43
- end
44
- end
45
- rescue LoadError
46
- task :flog do
47
- $stderr.puts 'Flog is not available. In order to run flog, you must: gem install flog'
48
- end
49
- end
@@ -1,208 +0,0 @@
1
- # encoding: utf-8
2
-
3
- $LOAD_PATH.unshift(File.expand_path('../../../lib', __FILE__))
4
-
5
- # original code by Ashley Moran:
6
- # http://aviewfromafar.net/2007/11/1/rake-task-for-heckling-your-specs
7
-
8
- begin
9
- require 'pathname'
10
- require 'heckle'
11
- require 'mspec'
12
- require 'mspec/utils/name_map'
13
-
14
- SKIP_METHODS = %w[ blank_slate_method_added ].freeze
15
-
16
- class NameMap
17
- def file_name(method, constant)
18
- map = MAP[method]
19
- name = if map
20
- map[constant] || map[:default]
21
- else
22
- method.gsub(/[?!=]\z/, '')
23
- end
24
- "#{name}_spec.rb"
25
- end
26
- end
27
-
28
- namespace :metrics do
29
- desc 'Heckle each module and class'
30
- task :heckle => :coverage do
31
- unless Ruby2Ruby::VERSION == '1.2.2'
32
- raise "ruby2ruby version #{Ruby2Ruby::VERSION} may not work properly, 1.2.2 *only* is recommended for use with heckle"
33
- end
34
-
35
- require 'abstract_type'
36
-
37
- root_module_regexp = Regexp.union('AbstractType')
38
-
39
- spec_dir = Pathname('spec/unit')
40
-
41
- NameMap::MAP.each do |op, method|
42
- next if method.kind_of?(Hash)
43
- NameMap::MAP[op] = { :default => method }
44
- end
45
-
46
- aliases = Hash.new { |h,mod| h[mod] = Hash.new { |h,method| h[method] = method } }
47
- map = NameMap.new
48
-
49
- heckle_caught_modules = Hash.new { |hash, key| hash[key] = [] }
50
- uncovered_methods = 0
51
-
52
- ObjectSpace.each_object(Module) do |mod|
53
- next unless mod.name =~ /\A#{root_module_regexp}(?::|\z)/
54
-
55
- spec_prefix = spec_dir.join(mod.name.underscore)
56
-
57
- specs = []
58
-
59
- # get the public class methods
60
- metaclass = class << mod; self end
61
- ancestors = metaclass.ancestors
62
-
63
- spec_class_methods = mod.singleton_methods(false)
64
-
65
- spec_class_methods.reject! do |method|
66
- %w[ yaml_new yaml_tag_subclasses? included nesting constants ].include?(method.to_s)
67
- end
68
-
69
- if mod.ancestors.include?(Singleton)
70
- spec_class_methods.reject! { |method| method.to_s == 'instance' }
71
- end
72
-
73
- # get the protected and private class methods
74
- other_class_methods = metaclass.protected_instance_methods(false) |
75
- metaclass.private_instance_methods(false)
76
-
77
- ancestors.each do |ancestor|
78
- other_class_methods -= ancestor.protected_instance_methods(false) |
79
- ancestor.private_instance_methods(false)
80
- end
81
-
82
- other_class_methods.reject! do |method|
83
- method.to_s == 'allocate' || SKIP_METHODS.include?(method.to_s)
84
- end
85
-
86
- other_class_methods.reject! do |method|
87
- next unless spec_class_methods.any? { |specced| specced.to_s == $1 }
88
-
89
- spec_class_methods << method
90
- end
91
-
92
- spec_class_methods -= other_class_methods
93
-
94
- # get the instances methods
95
- spec_methods = mod.public_instance_methods(false)
96
-
97
- other_methods = mod.protected_instance_methods(false) |
98
- mod.private_instance_methods(false)
99
-
100
- other_methods.reject! do |method|
101
- next unless spec_methods.any? { |specced| specced.to_s == $1 }
102
-
103
- spec_methods << method
104
- end
105
-
106
- # map the class methods to spec files
107
- spec_class_methods.each do |method|
108
- method = aliases[mod.name][method]
109
- next if SKIP_METHODS.include?(method.to_s)
110
-
111
- spec_file = spec_prefix.join('class_methods').join(map.file_name(method, mod.name))
112
-
113
- unless spec_file.file?
114
- raise "No spec file #{spec_file} for #{mod}.#{method}"
115
- end
116
-
117
- specs << [ ".#{method}", [ spec_file ] ]
118
- end
119
-
120
- # map the instance methods to spec files
121
- spec_methods.each do |method|
122
- method = aliases[mod.name][method]
123
- next if SKIP_METHODS.include?(method.to_s)
124
-
125
- spec_file = spec_prefix.join(map.file_name(method, mod.name))
126
-
127
- unless spec_file.file?
128
- raise "No spec file #{spec_file} for #{mod}##{method}"
129
- end
130
-
131
- specs << [ "##{method}", [ spec_file ] ]
132
- end
133
-
134
- # non-public methods are considered covered if they can be mutated
135
- # and any spec fails for the current or descendant modules
136
- other_methods.each do |method|
137
- descedant_specs = []
138
-
139
- ObjectSpace.each_object(Module) do |descedant|
140
- next unless descedant.name =~ /\A#{root_module_regexp}(?::|\z)/ && mod >= descedant
141
- descedant_spec_prefix = spec_dir.join(descedant.name.underscore)
142
- descedant_specs << descedant_spec_prefix
143
-
144
- if method.to_s == 'initialize'
145
- descedant_specs.concat(Pathname.glob(descedant_spec_prefix.join('class_methods/new_spec.rb')))
146
- end
147
- end
148
-
149
- specs << [ "##{method}", descedant_specs ]
150
- end
151
-
152
- other_class_methods.each do |method|
153
- descedant_specs = []
154
-
155
- ObjectSpace.each_object(Module) do |descedant|
156
- next unless descedant.name =~ /\A#{root_module_regexp}(?::|\z)/ && mod >= descedant
157
- descedant_specs << spec_dir.join(descedant.name.underscore).join('class_methods')
158
- end
159
-
160
- specs << [ ".#{method}", descedant_specs ]
161
- end
162
-
163
- specs.sort.each do |(method, spec_files)|
164
- puts "Heckling #{mod}#{method}"
165
- IO.popen("spec #{spec_files.join(' ')} --heckle '#{mod}#{method}'") do |pipe|
166
- while line = pipe.gets
167
- case line = line.chomp
168
- when "The following mutations didn't cause test failures:"
169
- heckle_caught_modules[mod.name] << method
170
- uncovered_methods += 1
171
- end
172
- end
173
- end
174
- end
175
- end
176
-
177
- if uncovered_methods > 0
178
- error_message_lines = [ "*************\n" ]
179
-
180
- error_message_lines << "Heckle found #{uncovered_methods} " \
181
- "method#{"s" unless uncovered_methods == 1} " \
182
- "where mutations didn't cause spec violations\n"
183
-
184
- heckle_caught_modules.each do |mod, methods|
185
- error_message_lines << "#{mod} contains the following " \
186
- 'poorly-specified methods:'
187
- methods.each do |method|
188
- error_message_lines << " - #{method}"
189
- end
190
- error_message_lines << ''
191
- end
192
-
193
- error_message_lines << 'Get your act together and come back ' \
194
- 'when your specs are doing their job!'
195
-
196
- raise error_message_lines.join("\n")
197
- else
198
- puts 'Well done! Your code withstood a heckling.'
199
- end
200
- end
201
- end
202
- rescue LoadError
203
- namespace :metrics do
204
- task :heckle => :coverage do
205
- $stderr.puts 'Heckle or mspec is not available. In order to run heckle, you must: gem install heckle mspec'
206
- end
207
- end
208
- end
@@ -1,31 +0,0 @@
1
- # encoding: utf-8
2
-
3
- begin
4
- require 'metric_fu'
5
- require 'json'
6
-
7
- # XXX: temporary hack until metric_fu is fixed
8
- MetricFu::Saikuro.class_eval { include FileUtils }
9
-
10
- MetricFu::Configuration.run do |config|
11
- config.rcov = {
12
- :environment => 'test',
13
- :test_files => %w[ spec/**/*_spec.rb ],
14
- :rcov_opts => %w[
15
- --sort coverage
16
- --no-html
17
- --text-coverage
18
- --no-color
19
- --profile
20
- --exclude spec/,^/
21
- --include lib:spec
22
- ],
23
- }
24
- end
25
- rescue LoadError
26
- namespace :metrics do
27
- task :all do
28
- $stderr.puts 'metric_fu is not available. In order to run metrics:all, you must: gem install metric_fu'
29
- end
30
- end
31
- end
@@ -1,21 +0,0 @@
1
- # encoding: utf-8
2
-
3
- begin
4
- require 'reek/rake/task'
5
-
6
- RBX_18_MODE = RUBY_VERSION < '1.9' && defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
7
-
8
- namespace :metrics do
9
- Reek::Rake::Task.new do |t|
10
- # reek has some problems under rbx in 1.8 mode that cause the underlying
11
- # script to raise an exception. Rather than halt the "rake ci" process due
12
- # to one bug, we choose to ignore it in this specific case until reek can be
13
- # fixed.
14
- t.fail_on_error = ! RBX_18_MODE # always true, except under rbx 18 mode
15
- end
16
- end
17
- rescue LoadError
18
- task :reek do
19
- $stderr.puts 'Reek is not available. In order to run reek, you must: gem install reek'
20
- end
21
- end
@@ -1,19 +0,0 @@
1
- # encoding: utf-8
2
-
3
- begin
4
- require 'roodi'
5
- require 'rake/tasklib'
6
- require 'roodi_task'
7
-
8
- namespace :metrics do
9
- RoodiTask.new do |t|
10
- t.verbose = false
11
- t.config = File.expand_path('../../../config/roodi.yml', __FILE__)
12
- t.patterns = %w[ lib/**/*.rb ]
13
- end
14
- end
15
- rescue LoadError
16
- task :roodi do
17
- $stderr.puts 'Roodi is not available. In order to run roodi, you must: gem install roodi'
18
- end
19
- end
@@ -1,25 +0,0 @@
1
- # encoding: utf-8
2
-
3
- begin
4
- require 'yardstick/rake/measurement'
5
- require 'yardstick/rake/verify'
6
- require 'yaml'
7
-
8
- config = YAML.load_file(File.expand_path('../../../config/yardstick.yml', __FILE__))
9
-
10
- namespace :metrics do
11
- # yardstick_measure task
12
- Yardstick::Rake::Measurement.new
13
-
14
- # verify_measurements task
15
- Yardstick::Rake::Verify.new do |verify|
16
- verify.threshold = config.fetch('threshold')
17
- end
18
- end
19
- rescue LoadError
20
- %w[ yardstick_measure verify_measurements ].each do |name|
21
- task name.to_s do
22
- $stderr.puts "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
23
- end
24
- end
25
- end
@@ -1,60 +0,0 @@
1
- # encoding: utf-8
2
-
3
- spec_defaults = lambda do |spec|
4
- spec.ruby_opts = %w[ -r./spec/support/config_alias ]
5
- spec.spec_opts << '--options' << 'spec/spec.opts'
6
- end
7
-
8
- begin
9
- require 'spec/rake/spectask'
10
-
11
- desc 'Run all specs'
12
- task :spec => %w[ spec:unit spec:integration ]
13
-
14
- namespace :spec do
15
- desc 'Run unit specs'
16
- Spec::Rake::SpecTask.new(:unit) do |unit|
17
- spec_defaults.call(unit)
18
- unit.pattern = 'spec/unit/**/*_spec.rb'
19
- end
20
-
21
- desc 'Run integration specs'
22
- Spec::Rake::SpecTask.new(:integration) do |integration|
23
- spec_defaults.call(integration)
24
- integration.pattern = 'spec/integration/**/*_spec.rb'
25
- end
26
- end
27
- rescue LoadError
28
- %w[ spec spec:unit spec:integration ].each do |name|
29
- task name do
30
- $stderr.puts "rspec is not available. In order to run #{name}, you must: gem install rspec"
31
- end
32
- end
33
- end
34
-
35
- namespace :metrics do
36
- begin
37
- if RUBY_VERSION < '1.9'
38
- desc 'Generate code coverage'
39
- Spec::Rake::SpecTask.new(:coverage) do |rcov|
40
- spec_defaults.call(rcov)
41
- rcov.rcov = true
42
- rcov.pattern = 'spec/unit/**/*_spec.rb'
43
- rcov.rcov_opts = File.read('spec/rcov.opts').split(/\s+/)
44
- end
45
- else
46
- desc 'Generate code coverage'
47
- task :coverage do
48
- ENV['COVERAGE'] = 'true'
49
- Rake::Task['spec:unit'].execute
50
- end
51
- end
52
- rescue LoadError
53
- task :coverage do
54
- lib = RUBY_VERSION < '1.9' ? 'rcov' : 'simplecov'
55
- $stderr.puts "coverage is not available. In order to run #{lib}, you must: gem install #{lib}"
56
- end
57
- end
58
- end
59
-
60
- task :test => :spec
@@ -1,11 +0,0 @@
1
- # encoding: utf-8
2
-
3
- begin
4
- require 'yard'
5
-
6
- YARD::Rake::YardocTask.new
7
- rescue LoadError
8
- task :yard do
9
- $stderr.puts 'YARD is not available. In order to run yard, you must: gem install yard'
10
- end
11
- end