adamantium 0.0.8 → 0.0.9

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +25 -11
  4. data/Gemfile +2 -67
  5. data/Gemfile.devtools +59 -0
  6. data/Rakefile +2 -7
  7. data/config/flay.yml +2 -2
  8. data/config/flog.yml +1 -1
  9. data/config/heckle.yml +3 -0
  10. data/config/mutant.yml +3 -0
  11. data/config/{site.reek → reek.yml} +5 -5
  12. data/lib/adamantium.rb +5 -4
  13. data/lib/adamantium/module_methods.rb +42 -0
  14. data/lib/adamantium/version.rb +2 -2
  15. data/spec/spec_helper.rb +2 -15
  16. data/spec/unit/adamantium/class_methods/included_spec.rb +38 -0
  17. data/spec/unit/adamantium/flat/class_methods/included_spec.rb +15 -0
  18. data/spec/unit/adamantium/freezer/class_methods/parse_spec.rb +5 -4
  19. data/spec/unit/adamantium/freezer/deep/class_methods/call_spec.rb +1 -1
  20. data/spec/unit/adamantium/freezer/flat/class_methods/call_spec.rb +1 -1
  21. data/spec/unit/adamantium/memoize_spec.rb +6 -0
  22. data/spec/unit/adamantium/module_methods/memoize_spec.rb +1 -1
  23. data/spec/unit/adamantium/module_methods/original_instance_method_spec.rb +34 -0
  24. metadata +13 -18
  25. data/spec/shared/command_method_behavior.rb +0 -7
  26. data/spec/shared/each_method_behaviour.rb +0 -15
  27. data/spec/shared/hash_method_behavior.rb +0 -17
  28. data/spec/shared/idempotent_method_behavior.rb +0 -7
  29. data/spec/shared/invertible_method_behaviour.rb +0 -9
  30. data/spec/spec.opts +0 -3
  31. data/tasks/metrics/ci.rake +0 -9
  32. data/tasks/metrics/flay.rake +0 -45
  33. data/tasks/metrics/flog.rake +0 -49
  34. data/tasks/metrics/heckle.rake +0 -208
  35. data/tasks/metrics/metric_fu.rake +0 -31
  36. data/tasks/metrics/roodi.rake +0 -19
  37. data/tasks/metrics/yardstick.rake +0 -25
  38. data/tasks/spec.rake +0 -60
  39. data/tasks/yard.rake +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c606a9e55367a10cc16a7c93a1ba7338661deaa
4
- data.tar.gz: 941057fd6680efc4ae04d8a7fabec7b6ee2d5e8a
3
+ metadata.gz: a106380b26c0c580838bdca91828157a4d78af22
4
+ data.tar.gz: 2428edceb354531cd1df081e47108abcfe1ba626
5
5
  SHA512:
6
- metadata.gz: 0e8137cb22a161cfcdf6162057e9a29310ade5bc47ecc177caa03f4fe042c5ebdb7bfd7aaf3d8f6ee34882affdde4c23c1092d200d14c3bc23eda7863f522f5e
7
- data.tar.gz: 4d8decf7dce34b9b6add23b20189011b8b6ff3c4de601f7562a1303a81cbcd39b20c91a9766af7bbd2c8c9c9764dc08e0d1ec6b81b6dd8f7a8f1011b2206b60f
6
+ metadata.gz: 94ab91bd30dc4764feaee048f7b9839e03fbcc24c5a725a4ac47feca64fc6b97b33c5f6392032faa9db8ac1cc484d61acae9615c21905f030a85d7e1f3372b5b
7
+ data.tar.gz: 487094b783776a59126ca78820f69a996f890ca579b4b511aeb951f50d525454c8c4a785ae2b98c26faf53c741b2a1df0ff7d9e9788f74cbc97943eaf5863b7e
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -1,21 +1,35 @@
1
1
  language: ruby
2
2
  before_install: gem install bundler
3
- bundler_args: --without yard guard metrics benchmarks
4
- script: "bundle exec rake spec"
3
+ bundler_args: --without yard guard benchmarks
4
+ script: "bundle exec rake ci"
5
5
  rvm:
6
- - ree
7
- - 1.8.7
8
6
  - 1.9.2
9
7
  - 1.9.3
10
8
  - 2.0.0
11
9
  - ruby-head
12
- - jruby-18mode
13
- - jruby-19mode
14
- - jruby-head
15
- - rbx-18mode
16
10
  - rbx-19mode
17
11
  notifications:
18
- irc: "irc.freenode.org#datamapper"
12
+ irc:
13
+ channels:
14
+ - irc.freenode.org#rom-rb
15
+ on_success: never
16
+ on_failure: change
19
17
  email:
20
- - dan.kubb@gmail.com
21
- - mbj@seonic.net
18
+ recipients:
19
+ - dan.kubb@gmail.com
20
+ - mbj@schirp-dso.com
21
+ on_success: never
22
+ on_failure: change
23
+ matrix:
24
+ include:
25
+ - rvm: jruby-19mode
26
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug"
27
+ - rvm: jruby-head
28
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug"
29
+ allow_failures:
30
+ # mutant fails
31
+ - rvm: 1.9.3
32
+ - rvm: 2.0.0
33
+ - rvm: rbx-19mode
34
+ # broken on travis
35
+ - rvm: ruby-head
data/Gemfile CHANGED
@@ -4,70 +4,5 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
- group :development do
8
- gem 'rake', '~> 10.1.0'
9
- gem 'rspec', '= 1.3.2'
10
- gem 'yard', '~> 0.8.6.1'
11
- end
12
-
13
- group :yard do
14
- gem 'kramdown', '~> 1.0.1'
15
- end
16
-
17
- group :guard do
18
- gem 'guard', '~> 1.8.1'
19
- gem 'guard-bundler', '~> 1.0.0'
20
- gem 'guard-rspec', '~> 1.2.1'
21
-
22
- # file system change event handling
23
- gem 'listen', '~> 1.2.2'
24
- gem 'rb-fchange', '~> 0.0.6', :require => false
25
- gem 'rb-fsevent', '~> 0.9.3', :require => false
26
- gem 'rb-inotify', '~> 0.9.0', :require => false
27
-
28
- # notification handling
29
- gem 'libnotify', '~> 0.8.0', :require => false
30
- gem 'rb-notifu', '~> 0.0.4', :require => false
31
- gem 'terminal-notifier-guard', '~> 1.5.3', :require => false
32
- end
33
-
34
- group :metrics do
35
- gem 'backports', '~> 3.3', '>= 3.3.2'
36
- gem 'coveralls', '~> 0.6.7'
37
- gem 'flay', '~> 1.4.3'
38
- gem 'flog', '~> 2.5.3'
39
- gem 'roodi', '~> 2.2.0'
40
- gem 'simplecov', '~> 0.7.1'
41
- gem 'yardstick', '~> 0.9.6'
42
-
43
- platforms :ruby_19 do
44
- gem 'yard-spellcheck', '~> 0.1.5'
45
- end
46
-
47
- platforms :mri_18 do
48
- gem 'arrayfields', '~> 4.9.0' # for metric_fu
49
- gem 'fattr', '~> 2.2.0' # for metric_fu
50
- gem 'heckle', '~> 1.4.3'
51
- gem 'json', '~> 1.8.0' # for metric_fu rake task
52
- gem 'map', '~> 6.5.1' # for metric_fu
53
- gem 'metric_fu', '~> 2.1.1'
54
- gem 'mspec', '~> 1.5.17'
55
- gem 'rails_best_practices', '= 1.13.3' # for metric_fu
56
- gem 'rcov', '~> 1.0.0'
57
- gem 'ruby2ruby', '= 1.2.2' # for heckle
58
- end
59
-
60
- platforms :rbx do
61
- gem 'pelusa', '~> 0.2.2'
62
- end
63
- end
64
-
65
- group :benchmarks do
66
- gem 'rbench', '~> 0.2.3'
67
- end
68
-
69
- platform :jruby do
70
- group :jruby do
71
- gem 'jruby-openssl', '~> 0.8.5'
72
- end
73
- end
7
+ gem 'devtools', :git => 'https://github.com/datamapper/devtools.git'
8
+ eval File.read('Gemfile.devtools')
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ group :development do
4
+ gem 'rake', '~> 10.1.0'
5
+ gem 'rspec', '~> 2.13.0'
6
+ gem 'yard', '~> 0.8.6.2'
7
+ end
8
+
9
+ group :yard do
10
+ gem 'kramdown', '~> 1.1.0'
11
+ end
12
+
13
+ group :guard do
14
+ gem 'guard', '~> 1.8.1'
15
+ gem 'guard-bundler', '~> 1.0.0'
16
+ gem 'guard-rspec', '~> 3.0.2'
17
+
18
+ # file system change event handling
19
+ gem 'listen', '~> 1.2.2'
20
+ gem 'rb-fchange', '~> 0.0.6', :require => false
21
+ gem 'rb-fsevent', '~> 0.9.3', :require => false
22
+ gem 'rb-inotify', '~> 0.9.0', :require => false
23
+
24
+ # notification handling
25
+ gem 'libnotify', '~> 0.8.0', :require => false
26
+ gem 'rb-notifu', '~> 0.0.4', :require => false
27
+ gem 'terminal-notifier-guard', '~> 1.5.3', :require => false
28
+ end
29
+
30
+ group :metrics do
31
+ gem 'coveralls', '~> 0.6.7'
32
+ gem 'flay', '~> 2.3.0'
33
+ gem 'flog', '~> 4.1.0'
34
+ gem 'reek', '~> 1.3.1', :git => 'https://github.com/troessner/reek.git'
35
+ gem 'simplecov', '~> 0.7.1'
36
+ gem 'yardstick', '~> 0.9.6'
37
+
38
+ platforms :ruby_19 do
39
+ gem 'yard-spellcheck', '~> 0.1.5'
40
+ end
41
+
42
+ platforms :ruby_19, :ruby_20 do
43
+ gem 'mutant', '~> 0.3.0.beta8'
44
+ end
45
+
46
+ platforms :rbx do
47
+ gem 'pelusa', '~> 0.2.2'
48
+ end
49
+ end
50
+
51
+ group :benchmarks do
52
+ gem 'rbench', '~> 0.2.3'
53
+ end
54
+
55
+ platform :jruby do
56
+ group :jruby do
57
+ gem 'jruby-openssl', '~> 0.8.5'
58
+ end
59
+ end
data/Rakefile CHANGED
@@ -1,8 +1,3 @@
1
1
  # encoding: utf-8
2
-
3
- require 'rake'
4
-
5
- FileList['tasks/**/*.rake'].each { |task| import task }
6
-
7
- desc 'Default: run all specs'
8
- task :default => :spec
2
+ require 'devtools'
3
+ Devtools.init_rake_tasks
@@ -1,3 +1,3 @@
1
1
  ---
2
- threshold: 9
3
- total_score: 66
2
+ threshold: 7
3
+ total_score: 53
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 20.6
2
+ threshold: 17.5
@@ -0,0 +1,3 @@
1
+ ---
2
+ library: adamantium
3
+ namespace: Adamantium
@@ -0,0 +1,3 @@
1
+ ---
2
+ name: adamantium
3
+ namespace: Adamantium
@@ -7,7 +7,7 @@ UncommunicativeParameterName:
7
7
  - !ruby/regexp /^.$/
8
8
  - !ruby/regexp /[0-9]$/
9
9
  - !ruby/regexp /[A-Z]/
10
- LargeClass:
10
+ TooManyMethods:
11
11
  max_methods: 10
12
12
  exclude: []
13
13
  enabled: true
@@ -50,11 +50,11 @@ NestedIterators:
50
50
  - Adamantium::ModuleMethods#define_memoize_method # 2 levels
51
51
  enabled: true
52
52
  max_allowed_nesting: 1
53
- LongMethod:
53
+ TooManyStatements:
54
54
  max_statements: 7 # TODO: decrease max_statements to 5 or less
55
55
  exclude: []
56
56
  enabled: true
57
- Duplication:
57
+ DuplicateMethodCall:
58
58
  allow_calls: []
59
59
  exclude: []
60
60
  enabled: true
@@ -74,7 +74,7 @@ UncommunicativeVariableName:
74
74
  - !ruby/regexp /^.$/
75
75
  - !ruby/regexp /[0-9]$/
76
76
  - !ruby/regexp /[A-Z]/
77
- SimulatedPolymorphism:
77
+ RepeatedConditional:
78
78
  exclude: []
79
79
  enabled: true
80
80
  max_ifs: 1
@@ -83,7 +83,7 @@ DataClump:
83
83
  enabled: true
84
84
  max_copies: 1
85
85
  min_clump_size: 3
86
- ControlCouple:
86
+ ControlParameter:
87
87
  exclude: []
88
88
  enabled: true
89
89
  LongYieldList:
@@ -25,16 +25,17 @@ module Adamantium
25
25
  #
26
26
  # @param [Class,Module] descendant
27
27
  #
28
- # @return [self]
28
+ # @return [undefined]
29
29
  #
30
30
  # @api private
31
31
  def self.included(descendant)
32
32
  super
33
33
  descendant.send(:include, Adamantium)
34
34
  descendant.extend(self)
35
- self
36
35
  end
37
- end
36
+ private_class_method :included
37
+
38
+ end # Flat
38
39
 
39
40
  # Hook called when module is included
40
41
  #
@@ -45,7 +46,7 @@ module Adamantium
45
46
  #
46
47
  # @api private
47
48
  def self.included(descendant)
48
- descendant.extend ModuleMethods if descendant.kind_of?(Module)
49
+ descendant.extend ModuleMethods
49
50
  descendant.extend ClassMethods if descendant.kind_of?(Class)
50
51
  self
51
52
  end
@@ -46,6 +46,35 @@ module Adamantium
46
46
  self
47
47
  end
48
48
 
49
+ # Return original instance method
50
+ #
51
+ # @example
52
+ #
53
+ # class Foo
54
+ # include Adamantium
55
+ #
56
+ # def bar
57
+ # end
58
+ # memoize :bar
59
+ #
60
+ # end
61
+ #
62
+ # Foo.original_instance_method(:bar) #=> UnboundMethod, where source_location still points to original!
63
+ #
64
+ # @param [Symbol] name
65
+ #
66
+ # @return [UnboundMethod]
67
+ # if method was memoized before
68
+ #
69
+ # @raise [ArgumentError]
70
+ # otherwise
71
+ #
72
+ # @api public
73
+ #
74
+ def original_instance_method(name)
75
+ memoized_methods[name]
76
+ end
77
+
49
78
  private
50
79
 
51
80
  # Memoize the named method
@@ -63,11 +92,24 @@ module Adamantium
63
92
  if method.arity.nonzero?
64
93
  raise ArgumentError, 'Cannot memoize method with nonzero arity'
65
94
  end
95
+ memoized_methods[method_name] = method
66
96
  visibility = method_visibility(method_name)
67
97
  define_memoize_method(method, freezer)
68
98
  send(visibility, method_name)
69
99
  end
70
100
 
101
+ # Return original method registry
102
+ #
103
+ # @return [Hash<Symbol, UnboundMethod>]
104
+ #
105
+ # @api private
106
+ #
107
+ def memoized_methods
108
+ @memoized_methods ||= Hash.new do |_, name|
109
+ raise ArgumentError, "No method #{name.inspect} was memoized"
110
+ end
111
+ end
112
+
71
113
  # Define a memoized method that delegates to the original method
72
114
  #
73
115
  # @param [UnboundMethod] method
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Adamantium
4
4
 
5
- # Unreleased gem version
6
- VERSION = '0.0.8'.freeze
5
+ # Released gem version
6
+ VERSION = '0.0.9'.freeze
7
7
 
8
8
  end # module Adamantium
@@ -1,15 +1,9 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'adamantium'
4
- require 'spec'
5
- require 'spec/autorun'
4
+ require 'devtools/spec_helper'
6
5
 
7
- # require spec support files and shared behavior
8
- Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
9
- require file
10
- end
11
-
12
- Spec::Runner.configure do |config|
6
+ RSpec.configure do |config|
13
7
  end
14
8
 
15
9
  if RUBY_VERSION >= '1.9' and ENV['COVERAGE'] == 'true'
@@ -19,10 +13,3 @@ if RUBY_VERSION >= '1.9' and ENV['COVERAGE'] == 'true'
19
13
  add_filter 'spec'
20
14
  end
21
15
  end
22
-
23
- # change the heckle timeout to be 5 seconds
24
- if defined?(::Heckle)
25
- class ::Heckle
26
- @@timeout = 5
27
- end
28
- end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Adamantium, '.included' do
4
+ let(:object) { described_class }
5
+
6
+ subject { object.included(target) }
7
+
8
+ let(:included_modules) do
9
+ target.singleton_class.included_modules
10
+ end
11
+
12
+ before { subject }
13
+
14
+ context 'when target is a module' do
15
+ let(:target) { Module.new }
16
+
17
+ it_should_behave_like 'a command method'
18
+
19
+ it 'includes Adamantium::ModuleMethods' do
20
+ included_modules.should include(Adamantium::ModuleMethods)
21
+ end
22
+
23
+ it 'does not include Adamantium::ClassMethods' do
24
+ included_modules.should_not include(Adamantium::ClassMethods)
25
+ end
26
+ end
27
+
28
+ context 'when target is a class' do
29
+ let(:target) { Class.new }
30
+
31
+ it 'includes Adamantium::{Class,Module}Methods' do
32
+ included_modules.should include(Adamantium::ModuleMethods)
33
+ included_modules.should include(Adamantium::ClassMethods)
34
+ end
35
+
36
+ it_should_behave_like 'a command method'
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Adamantium::Flat, '.included' do
4
+ subject do
5
+ Class.new do
6
+ include Adamantium::Flat
7
+ end
8
+ end
9
+
10
+ its(:ancestors) { should include(Adamantium) }
11
+
12
+ it 'extends class with Adamantium::Flat' do
13
+ subject.singleton_class.included_modules.should include(described_class)
14
+ end
15
+ end
@@ -5,12 +5,13 @@ require 'spec_helper'
5
5
  describe Adamantium::Freezer, '.parse' do
6
6
  subject { object.parse(options) }
7
7
 
8
- let(:object) { described_class }
9
- let(:freezer) { mock('Freezer') }
8
+ let(:object) { described_class }
9
+ let(:freezer) { mock('Freezer') }
10
10
 
11
11
  context 'with empty options' do
12
- let(:options) { {} }
13
- it { should be(nil) }
12
+ let(:options) { {} }
13
+
14
+ it { should be(nil) }
14
15
  end
15
16
 
16
17
  context 'with :freezer key' do
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe Adamantium::Freezer::Deep, '.call' do
6
6
  subject { object.call(value) }
7
7
 
8
- let(:object) { self.class.described_type }
8
+ let(:object) { described_class }
9
9
 
10
10
  context 'with a numeric value' do
11
11
  let(:value) { 1 }
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe Adamantium::Freezer::Flat, '.call' do
6
6
  subject { object.call(value) }
7
7
 
8
- let(:object) { self.class.described_type }
8
+ let(:object) { described_class }
9
9
 
10
10
  context 'with a numeric value' do
11
11
  let(:value) { 1 }
@@ -26,6 +26,8 @@ describe Adamantium, '#memoize' do
26
26
  subject
27
27
  object.send(method).should be_frozen
28
28
  end
29
+
30
+ it_should_behave_like 'a command method'
29
31
  end
30
32
 
31
33
  context 'when the value is not frozen' do
@@ -40,6 +42,8 @@ describe Adamantium, '#memoize' do
40
42
  subject
41
43
  object.send(method).should be_frozen
42
44
  end
45
+
46
+ it_should_behave_like 'a command method'
43
47
  end
44
48
 
45
49
  context 'when the method is already memoized' do
@@ -53,5 +57,7 @@ describe Adamantium, '#memoize' do
53
57
  it 'does not change the value' do
54
58
  expect { subject }.to_not change { object.send(method) }
55
59
  end
60
+
61
+ it_should_behave_like 'a command method'
56
62
  end
57
63
  end
@@ -61,7 +61,7 @@ describe Adamantium::ModuleMethods, '#memoize' do
61
61
  end
62
62
 
63
63
  context 'with :noop freezer option' do
64
- let(:method) { :some_state }
64
+ let(:method) { :some_state }
65
65
  let(:options) { { :freezer => :noop } }
66
66
 
67
67
  it_should_behave_like 'a command method'
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Adamantium::ModuleMethods, '#original_instance_method' do
4
+ subject { object.original_instance_method(name).source_location }
5
+
6
+ let(:object) do
7
+ Class.new do
8
+ include Adamantium
9
+
10
+ def foo; end
11
+
12
+ const_set(:ORIGINAL, instance_method(:foo).source_location)
13
+
14
+ memoize :foo
15
+ end
16
+ end
17
+
18
+ context 'when the method was memoized' do
19
+ let(:name) { :foo }
20
+
21
+ it 'returns the original method' do
22
+ should eql(object::ORIGINAL)
23
+ end
24
+ end
25
+
26
+ context 'when the method was not memoized' do
27
+ let(:name) { :bar }
28
+
29
+ it 'raises an exception' do
30
+ expect { subject }.
31
+ to raise_error(ArgumentError, 'No method :bar was memoized')
32
+ end
33
+ end
34
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adamantium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Kubb
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-23 00:00:00.000000000 Z
12
+ date: 2013-07-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ice_nine
@@ -57,9 +57,11 @@ extra_rdoc_files:
57
57
  - TODO
58
58
  files:
59
59
  - .gitignore
60
+ - .rspec
60
61
  - .ruby-gemset
61
62
  - .travis.yml
62
63
  - Gemfile
64
+ - Gemfile.devtools
63
65
  - Guardfile
64
66
  - LICENSE
65
67
  - README.md
@@ -68,8 +70,10 @@ files:
68
70
  - adamantium.gemspec
69
71
  - config/flay.yml
70
72
  - config/flog.yml
73
+ - config/heckle.yml
74
+ - config/mutant.yml
75
+ - config/reek.yml
71
76
  - config/roodi.yml
72
- - config/site.reek
73
77
  - config/yardstick.yml
74
78
  - lib/adamantium.rb
75
79
  - lib/adamantium/class_methods.rb
@@ -78,17 +82,13 @@ files:
78
82
  - lib/adamantium/version.rb
79
83
  - spec/integration/adamantium_spec.rb
80
84
  - spec/rcov.opts
81
- - spec/shared/command_method_behavior.rb
82
- - spec/shared/each_method_behaviour.rb
83
- - spec/shared/hash_method_behavior.rb
84
- - spec/shared/idempotent_method_behavior.rb
85
- - spec/shared/invertible_method_behaviour.rb
86
- - spec/spec.opts
87
85
  - spec/spec_helper.rb
88
86
  - spec/support/config_alias.rb
87
+ - spec/unit/adamantium/class_methods/included_spec.rb
89
88
  - spec/unit/adamantium/class_methods/new_spec.rb
90
89
  - spec/unit/adamantium/dup_spec.rb
91
90
  - spec/unit/adamantium/fixtures/classes.rb
91
+ - spec/unit/adamantium/flat/class_methods/included_spec.rb
92
92
  - spec/unit/adamantium/flat/freezer_spec.rb
93
93
  - spec/unit/adamantium/freeze_spec.rb
94
94
  - spec/unit/adamantium/freezer/class_methods/get_spec.rb
@@ -102,15 +102,7 @@ files:
102
102
  - spec/unit/adamantium/module_methods/freezer_spec.rb
103
103
  - spec/unit/adamantium/module_methods/included_spec.rb
104
104
  - spec/unit/adamantium/module_methods/memoize_spec.rb
105
- - tasks/metrics/ci.rake
106
- - tasks/metrics/flay.rake
107
- - tasks/metrics/flog.rake
108
- - tasks/metrics/heckle.rake
109
- - tasks/metrics/metric_fu.rake
110
- - tasks/metrics/roodi.rake
111
- - tasks/metrics/yardstick.rake
112
- - tasks/spec.rake
113
- - tasks/yard.rake
105
+ - spec/unit/adamantium/module_methods/original_instance_method_spec.rb
114
106
  homepage: https://github.com/dkubb/adamantium
115
107
  licenses: []
116
108
  metadata: {}
@@ -136,9 +128,11 @@ specification_version: 4
136
128
  summary: Immutable extensions to objects
137
129
  test_files:
138
130
  - spec/integration/adamantium_spec.rb
131
+ - spec/unit/adamantium/class_methods/included_spec.rb
139
132
  - spec/unit/adamantium/class_methods/new_spec.rb
140
133
  - spec/unit/adamantium/dup_spec.rb
141
134
  - spec/unit/adamantium/fixtures/classes.rb
135
+ - spec/unit/adamantium/flat/class_methods/included_spec.rb
142
136
  - spec/unit/adamantium/flat/freezer_spec.rb
143
137
  - spec/unit/adamantium/freeze_spec.rb
144
138
  - spec/unit/adamantium/freezer/class_methods/get_spec.rb
@@ -152,4 +146,5 @@ test_files:
152
146
  - spec/unit/adamantium/module_methods/freezer_spec.rb
153
147
  - spec/unit/adamantium/module_methods/included_spec.rb
154
148
  - spec/unit/adamantium/module_methods/memoize_spec.rb
149
+ - spec/unit/adamantium/module_methods/original_instance_method_spec.rb
155
150
  has_rdoc:
@@ -1,7 +0,0 @@
1
- # encoding: utf-8
2
-
3
- shared_examples_for 'a command method' do
4
- it 'returns self' do
5
- should equal(object)
6
- end
7
- end
@@ -1,15 +0,0 @@
1
- # encoding: utf-8
2
-
3
- shared_examples_for 'an #each method' do
4
- it_should_behave_like 'a command method'
5
-
6
- context 'with no block' do
7
- subject { object.each }
8
-
9
- it { should be_instance_of(to_enum.class) }
10
-
11
- it 'yields the expected values' do
12
- subject.to_a.should eql(object.to_a)
13
- end
14
- end
15
- end
@@ -1,17 +0,0 @@
1
- # encoding: utf-8
2
-
3
- shared_examples_for 'a hash method' do
4
- it_should_behave_like 'an idempotent method'
5
-
6
- specification = proc do
7
- should be_instance_of(Fixnum)
8
- end
9
-
10
- it 'is a fixnum' do
11
- instance_eval(&specification)
12
- end
13
-
14
- it 'memoizes the hash code' do
15
- subject.should eql(object.memoized(:hash))
16
- end
17
- end
@@ -1,7 +0,0 @@
1
- # encoding: utf-8
2
-
3
- shared_examples_for 'an idempotent method' do
4
- it 'is idempotent' do
5
- should equal(instance_eval(&self.class.subject))
6
- end
7
- end
@@ -1,9 +0,0 @@
1
- # encoding: utf-8
2
-
3
- shared_examples_for 'an invertible method' do
4
- it_should_behave_like 'an idempotent method'
5
-
6
- it 'is invertible' do
7
- subject.inverse.should equal(object)
8
- end
9
- end
@@ -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: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 'adamantium'
36
-
37
- root_module_regexp = Regexp.union('Adamantium')
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,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