abstract_type 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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