penetrator 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  This gem aimed to help with reuse code in ruby projects.
4
4
  Highly inspired from http://github.com/makandra/modularity gem but slightly modified for supporting
5
5
  conventional *super* inheritance chaining methods.
6
-
6
+ Also shameless borrowed code from ActiveSupport::Coerce and I should say thanks that Ruby Hackers, who wrote it.
7
7
 
8
8
  ## Installation
9
9
 
@@ -24,7 +24,7 @@ Or install it yourself as:
24
24
 
25
25
  *config/application.rb*
26
26
  ```ruby
27
- config.autoload_paths += Dir[Rails.root.join( 'app', '**/*' )].select { |fn| File.directory?(fn) }
27
+ config.autoload_paths += Rails.root.join( 'app', 'traits' )
28
28
  ```
29
29
 
30
30
  *app/controllers/traits/crudable_trait.rb*
@@ -51,7 +51,7 @@ config.autoload_paths += Dir[Rails.root.join( 'app', '**/*' )].select { |fn| Fil
51
51
  end
52
52
  end
53
53
 
54
- # ... and so on
54
+ # ... and so on ...
55
55
 
56
56
  private
57
57
  def take_layout
@@ -68,7 +68,7 @@ config.autoload_paths += Dir[Rails.root.join( 'app', '**/*' )].select { |fn| Fil
68
68
  ```ruby
69
69
  class AccomodationsController < ApplicationController
70
70
  #
71
- # CrudableTrait required parameters
71
+ # CrudableTrait required this mehod
72
72
  private
73
73
  def resource_class
74
74
  Accomodation
@@ -91,6 +91,15 @@ config.autoload_paths += Dir[Rails.root.join( 'app', '**/*' )].select { |fn| Fil
91
91
  def default_order
92
92
  "accomodations.name desc"
93
93
  end
94
+
95
+ public
96
+ # Override traits methods
97
+ # with respecting call chaining
98
+ #
99
+ def kill_all_humans
100
+ "Yes" or super
101
+ end
102
+
94
103
  end
95
104
  ```
96
105
 
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module Penetrator
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
data/lib/penetrator.rb CHANGED
@@ -3,23 +3,48 @@ require "penetrator/inflector"
3
3
  require "penetrator/version"
4
4
 
5
5
  module Penetrator
6
- module Behavior
6
+ module Concern
7
+ def self.extended(base) #:nodoc:
8
+ base.instance_variable_set("@_dependencies", [])
9
+ end
10
+
11
+ def append_features(base)
12
+ if base.instance_variable_defined?("@_dependencies")
13
+ base.instance_variable_get("@_dependencies") << self
14
+ return false
15
+ else
16
+ return false if base < self
17
+ @_dependencies.each { |dep| base.send(:include, dep) }
18
+ super
19
+ base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
20
+ base.class_exec(*@_trait_args, &@_included_block) if instance_variable_defined?("@_included_block")
21
+ end
22
+ end
7
23
 
24
+ def included(base = nil, &block)
25
+ if base.nil?
26
+ @_included_block = block
27
+ else
28
+ super
29
+ end
30
+ end
31
+ end # Concern
32
+
33
+ module Behavior
8
34
  def self.included(base)
9
35
  base.extend ClassMethods
10
36
  end
11
37
 
12
38
  module ClassMethods
13
- def behave_like(trait_name, *args)
39
+ def behaves_like(trait_name, *args)
14
40
  full_name = "#{Penetrator::Inflector.camelize(trait_name.to_s)}Trait"
15
41
  trait = Penetrator::Inflector.constantize(full_name)
16
- trait_args_var = "@@" + trait_name.to_s.downcase.gsub(/[^_a-z]+/, '_')+"_args"
17
- self.class_variable_set(trait_args_var.to_sym, (args || nil))
42
+ trait.instance_variable_set(:@_trait_args, args)
18
43
  include trait
19
44
  end
20
- end
45
+ end # ClassMethods
46
+ end # Behavior
21
47
 
22
- end
23
48
  end
24
49
 
25
50
  Object.send :include, Penetrator::Behavior
data/penetrator.gemspec CHANGED
@@ -17,5 +17,6 @@ Gem::Specification.new do |gem|
17
17
  if RUBY_VERSION < '1.9.0'
18
18
  gem.add_development_dependency "minitest"
19
19
  end
20
+ gem.add_development_dependency "rake"
20
21
  gem.add_development_dependency "mocha"
21
22
  end
@@ -0,0 +1,92 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'penetrator'
3
+ require 'minitest/spec'
4
+ require 'minitest/autorun'
5
+
6
+ describe 'behavior when trait can be parameterized by arguments passed into included module' do
7
+ module CanHaveArgsTrait
8
+ extend Penetrator::Concern
9
+ included do |*args|
10
+ args.each do |method_name|
11
+ define_method(method_name) do
12
+ method_name.to_s
13
+ end
14
+ end
15
+ end # included
16
+ end # CanHaveArgs
17
+
18
+ it 'receive trait arguments' do
19
+ class Victim
20
+ behaves_like :CanHaveArgs, 'arg1', 'arg2'
21
+ end
22
+ obj = Victim.new
23
+ obj.must_respond_to :arg1
24
+ obj.arg1.must_be :==, 'arg1'
25
+ obj.must_respond_to :arg2
26
+ obj.arg2.must_be :==, 'arg2'
27
+
28
+ class OtherVictim
29
+ behaves_like :CanHaveArgs
30
+ end
31
+ obj = OtherVictim.new
32
+ obj.wont_respond_to :arg1
33
+ obj.wont_respond_to :arg2
34
+ end
35
+
36
+ end # trait argument
37
+
38
+ describe 'behavior when trait add ClassMethods and Instance methods' do
39
+ module RichTrait
40
+ extend Penetrator::Concern
41
+ module ClassMethods
42
+ def class_method
43
+ end
44
+ end
45
+
46
+ def instance_method
47
+ end
48
+ end
49
+
50
+ it 'add class and instance methods from traits' do
51
+ class VictimWithNoArguments
52
+ behaves_like 'rich'
53
+ end
54
+ obj = VictimWithNoArguments.new
55
+ obj.must_respond_to :instance_method
56
+ VictimWithNoArguments.must_respond_to :class_method
57
+ end
58
+ end
59
+
60
+
61
+ describe 'behavior when trait add ClassMethods and Instance methods alongside with existing' do
62
+ module SuperRichTrait
63
+ extend Penetrator::Concern
64
+ module ClassMethods
65
+ def class_method(arg)
66
+ "From Trait with chaining"
67
+ end
68
+ end
69
+
70
+ def instance_method(arg)
71
+ "From Trait with chaining"
72
+ end
73
+ end
74
+
75
+ it 'add class and instance methods from traits' do
76
+ class Innocent
77
+ def self.class_method arg
78
+ "This is class argument: #{arg} " + super
79
+ end
80
+ def instance_method arg
81
+ "This is instance argument: #{arg} " + super
82
+ end
83
+
84
+ behaves_like 'super_rich'
85
+ end
86
+
87
+ obj = Innocent.new
88
+ obj.instance_method('iarg').must_be :==, 'This is instance argument: iarg From Trait with chaining'
89
+ Innocent.class_method('carg').must_be :==, 'This is class argument: carg From Trait with chaining'
90
+ end
91
+
92
+ end
data/spec/core_spec.rb CHANGED
@@ -6,7 +6,7 @@ require 'mocha'
6
6
 
7
7
  describe 'Class' do
8
8
  it 'should be accesable' do
9
- Class.must_respond_to :behave_like
9
+ Class.must_respond_to :behaves_like
10
10
  end
11
11
  end # Class method
12
12
 
@@ -19,7 +19,7 @@ describe 'mixing behavior' do
19
19
 
20
20
  it 'add trait methods' do
21
21
  class Victim
22
- behave_like 'first'
22
+ behaves_like 'first'
23
23
  end
24
24
 
25
25
  Victim.new.must_respond_to :test
@@ -35,7 +35,7 @@ describe 'mixing behavior' do
35
35
 
36
36
  it 'add traits methods from nested modules' do
37
37
  class Victim
38
- behave_like 'outer/inner'
38
+ behaves_like 'outer/inner'
39
39
  end
40
40
  Victim.new.must_respond_to :inner_test
41
41
  end
@@ -53,7 +53,7 @@ describe 'methods chainings' do
53
53
 
54
54
  it 'have traits methods' do
55
55
  class Victim
56
- behave_like 'super'
56
+ behaves_like 'super'
57
57
  def test
58
58
  'this from class and that ' + super
59
59
  end
@@ -72,23 +72,23 @@ describe 'callbacks' do
72
72
  class Victim; end
73
73
  CallbackTrait.expects(:included).with(Victim)
74
74
  class Victim
75
- behave_like 'callback'
75
+ behaves_like 'callback'
76
76
  end
77
77
  end
78
78
  end # callbacks
79
79
 
80
80
  describe 'visibility' do
81
81
  module VisibilityTrait
82
- def public_method_from_trait; end
82
+ def public_method_from_trait; end
83
83
  protected
84
- def protected_method_from_trait; end
84
+ def protected_method_from_trait; end
85
85
  private
86
86
  def private_method_from_trait; end
87
87
  end
88
88
 
89
89
  it 'allow trait to define methods with different visibility' do
90
90
  class Victim
91
- behave_like 'visibility'
91
+ behaves_like 'visibility'
92
92
  end
93
93
 
94
94
  instance = Victim.new
@@ -99,42 +99,3 @@ describe 'visibility' do
99
99
  end
100
100
 
101
101
  end # visibility
102
-
103
- describe 'trait arguments' do
104
- module HaveArgsTrait; end
105
-
106
- it 'receive trait arguments' do
107
- class Victim; end
108
- Victim.expects(:behave_like).with('have_args', 'arg1', 'arg2')
109
-
110
- class Victim
111
- behave_like 'have_args', 'arg1', 'arg2'
112
- end
113
-
114
- end
115
-
116
- it 'base holds arguments' do
117
- class Victim
118
- behave_like 'have_args', 'arg1', 'arg2'
119
- end
120
- Victim.class_variable_get(:@@have_args_args).must_equal ['arg1','arg2']
121
- end
122
-
123
-
124
- describe 'arguments defined before trait included' do
125
- module HandyTrait
126
- def self.included(base)
127
- base.send :stub, base.class_variable_get(:@@handy_args)
128
- end
129
- end
130
-
131
- class Victim; end
132
- Victim.expects(:stub).with(['arg'])
133
-
134
- class Victim
135
- behave_like :handy, 'arg'
136
- end
137
- end # 'trait use arguments'
138
-
139
-
140
- end # trait argument
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: penetrator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,27 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-05 00:00:00.000000000 Z
12
+ date: 2012-10-04 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: mocha
16
- requirement: &70150947089080 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
17
33
  none: false
18
34
  requirements:
19
35
  - - ! '>='
@@ -21,7 +37,12 @@ dependencies:
21
37
  version: '0'
22
38
  type: :development
23
39
  prerelease: false
24
- version_requirements: *70150947089080
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
25
46
  description: Implement traits behavior to get rid of code repetition
26
47
  email:
27
48
  - jurbat@gmail.com
@@ -38,6 +59,7 @@ files:
38
59
  - lib/penetrator/inflector.rb
39
60
  - lib/penetrator/version.rb
40
61
  - penetrator.gemspec
62
+ - spec/coerce_spec.rb
41
63
  - spec/core_spec.rb
42
64
  homepage: https://github.com/svenyurgensson/penetrator
43
65
  licenses: []
@@ -59,9 +81,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
81
  version: '0'
60
82
  requirements: []
61
83
  rubyforge_project:
62
- rubygems_version: 1.8.15
84
+ rubygems_version: 1.8.24
63
85
  signing_key:
64
86
  specification_version: 3
65
87
  summary: Implement traits behavior to get rid of code repetition
66
88
  test_files:
89
+ - spec/coerce_spec.rb
67
90
  - spec/core_spec.rb