Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 13 files changed
  • 0 comments
  • 1 contributor
Jun 05, 2012
Markus Schirp Setup infrastructure 92e2724
Markus Schirp Prepare for heckle based unit specs 4c7ef80
3  .gitignore
... ... @@ -1 +1,4 @@
1 1 Gemfile.lock
  2 +profiling
  3 +coverage
  4 +tmp
1  Gemfile
@@ -15,6 +15,7 @@ group :metrics do
15 15 gem 'reek', '~> 1.2.8', :git => 'git://github.com/dkubb/reek.git'
16 16 gem 'roodi', '~> 2.1.0'
17 17 gem 'yardstick', '~> 0.4.0'
  18 + gem 'rspec', '~> 1.3.2'
18 19
19 20 platforms :mri_18 do
20 21 gem 'heckle', '~> 1.4.3'
2  config/flay.yml
... ... @@ -1,3 +1,3 @@
1 1 ---
2 2 threshold: 14
3   -total_score: 211
  3 +total_score: 203
25 config/roodi.yml
... ... @@ -1,17 +1,20 @@
1 1 ---
2   -AbcMetricMethodCheck: { score: 12.1 }
  2 +AbcMetricMethodCheck:
  3 + score: 6.0
3 4 AssignmentInConditionalCheck: { }
4 5 CaseMissingElseCheck: { }
5   -ClassLineCountCheck: { line_count: 325 }
6   -ClassNameCheck: { pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/ }
  6 +ClassLineCountCheck: { line_count: 257 }
  7 +ClassNameCheck:
  8 + pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/
7 9 ClassVariableCheck: { }
8   -CyclomaticComplexityBlockCheck: { complexity: 4 }
9   -CyclomaticComplexityMethodCheck: { complexity: 4 }
  10 +CyclomaticComplexityBlockCheck: { complexity: 1 }
  11 +CyclomaticComplexityMethodCheck: { complexity: 2 }
10 12 EmptyRescueBodyCheck: { }
11 13 ForLoopCheck: { }
12   -MethodLineCountCheck: { line_count: 10 }
13   -MethodNameCheck: { pattern: !ruby/regexp /\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/ }
14   -ModuleLineCountCheck: { line_count: 331 }
15   -ModuleNameCheck: { pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/ }
16   -# TODO: decrease parameter_count to 2 or less
17   -ParameterNumberCheck: { parameter_count: 3 }
  14 +MethodLineCountCheck: { line_count: 8 }
  15 +MethodNameCheck:
  16 + pattern: !ruby/regexp /\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/
  17 +ModuleLineCountCheck: { line_count: 260 }
  18 +ModuleNameCheck:
  19 + pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/
  20 +ParameterNumberCheck: { parameter_count: 2 }
2  lib/mapper/attribute.rb
@@ -14,7 +14,7 @@ def self.determine_type(class_or_name)
14 14 end
15 15
16 16 unless type
17   - raise "cannot determine type from: #{class_or_name.inspect}"
  17 + raise ArgumentError,"unable to determine type from: #{class_or_name.inspect}"
18 18 end
19 19
20 20 type
8 lib/mapper/class_methods.rb
@@ -47,14 +47,6 @@ def loader_klass
47 47 const_get(:Loader)
48 48 end
49 49
50   - def dumper(object)
51   - dumper_klass.new(self,object)
52   - end
53   -
54   - def loader(dump)
55   - loader_klass.new(self,dump)
56   - end
57   -
58 50 def instanciate_model(attributes)
59 51 model.new(attributes)
60 52 end
13 lib/mapper/transformer.rb
@@ -11,16 +11,13 @@ def self.transfer(names,transformator)
11 11 end
12 12 end
13 13
  14 +
  15 + private
  16 +
14 17 def mapper
15 18 self.class.mapper
16 19 end
17 20
18   - def self.attributes
19   - mapper.attributes
20   - end
21   -
22   - private
23   -
24 21 def memonize(name)
25 22 @memonized ||= {}
26 23 @memonized.fetch(name) do
@@ -50,7 +47,7 @@ def self.load(dump)
50 47
51 48 attributes = transfer(mapper.load_names,loader)
52 49
53   - mapper.model.new(attributes)
  50 + mapper.instanciate_model(attributes)
54 51 end
55 52 end
56 53
@@ -73,7 +70,7 @@ def dump(name)
73 70 def self.dump(object)
74 71 dumper = self.new(object)
75 72
76   - transfer(mapper.dump_names,dumper)
  73 + transfer(self.mapper.dump_names,dumper)
77 74 end
78 75 end
79 76 end
1  spec/spec.opts
... ... @@ -0,0 +1 @@
  1 +--color
23 spec/unit/mapper/attribute/class_methods/determine_type_spec.rb
... ... @@ -0,0 +1,23 @@
  1 +require 'spec_helper'
  2 +
  3 +describe Mapper::Attribute, '.determine_type' do
  4 + let(:object) { described_class }
  5 +
  6 + subject { object.determine_type(class_or_name) }
  7 +
  8 + context 'with ::Object' do
  9 + let(:class_or_name) { ::Object }
  10 +
  11 + it 'should return Mapper::Attribute::Object' do
  12 + should be(Mapper::Attribute::Object)
  13 + end
  14 + end
  15 +
  16 + context 'with undeterminable type' do
  17 + let(:class_or_name) { Object.new }
  18 +
  19 + it 'should raise error' do
  20 + expect { subject }.to raise_error(ArgumentError,"unable to determine type from: #{class_or_name.inspect}")
  21 + end
  22 + end
  23 +end
28 spec/unit/mapper/transformer/class_methods/mapper_spec.rb
... ... @@ -0,0 +1,28 @@
  1 +require 'spec_helper'
  2 +
  3 +describe Mapper::Transformer, '.mapper' do
  4 + let(:object) do
  5 + Class.new(described_class)
  6 + end
  7 +
  8 + let(:mapper) { mock }
  9 +
  10 + subject { object.mapper }
  11 +
  12 + context 'when mapper setup was done' do
  13 + before do
  14 + object.instance_variable_set(:@mapper,mapper)
  15 + end
  16 +
  17 + it 'should return mapper' do
  18 + should be(mapper)
  19 + end
  20 + end
  21 +
  22 + context 'when mapper setup was NOT done' do
  23 + it 'should raise error' do
  24 + expect { subject }.to raise_error(RuntimeError,'mapper setup missing')
  25 + end
  26 + end
  27 +end
  28 +
171 spec/unit/spike_spec.rb
... ... @@ -0,0 +1,171 @@
  1 +require 'spec_helper'
  2 +
  3 +describe 'spike spec' do
  4 + class Phone
  5 + include Virtus::ValueObject
  6 +
  7 + attribute :number,String
  8 + attribute :type,String
  9 +
  10 + class Mapper
  11 + include ::Mapper
  12 + model Phone
  13 + map :number, Object
  14 + map :type, Object
  15 + end
  16 +
  17 + class LoaderByHand
  18 + def initialize(dump)
  19 + @dump = dump
  20 + end
  21 +
  22 + def number
  23 + @dump.fetch(:number)
  24 + end
  25 +
  26 + def type
  27 + @dump.fetch(:type)
  28 + end
  29 +
  30 + def load
  31 + Phone.new(
  32 + :number => number,
  33 + :type => type
  34 + )
  35 + end
  36 + end
  37 +
  38 + class DumperByHand
  39 + def initialize(phone)
  40 + @phone = phone
  41 + end
  42 +
  43 + def phone
  44 + @phone.number
  45 + end
  46 +
  47 + def type
  48 + @phone.type
  49 + end
  50 +
  51 + def dump
  52 + {
  53 + :number => number,
  54 + :type => type
  55 + }
  56 + end
  57 + end
  58 + end
  59 +
  60 + class Address
  61 + include Virtus::ValueObject
  62 +
  63 + attribute :lines,String
  64 + attribute :postcode,String
  65 +
  66 + class Mapper
  67 + include ::Mapper
  68 + model Address
  69 + map :lines, Object
  70 + map :postcode, Object
  71 + end
  72 + end
  73 +
  74 + class User
  75 + include Virtus::ValueObject
  76 +
  77 + attribute :firstname,String
  78 + attribute :lastname,String
  79 + attribute :address,Address
  80 + attribute :phones,Array[Phone]
  81 + attribute :preferred_phone,Phone
  82 + attribute :vat_rate,Rational
  83 +
  84 + class Mapper
  85 + include ::Mapper
  86 + model ::User
  87 +
  88 + map :firstname, Object, :to => :surname
  89 + map :lastname, Object
  90 + map :address, EmbeddedDocument, :mapper => Address::Mapper
  91 + map :phones, EmbeddedCollection, :mapper => Phone::Mapper
  92 + map :vat_rate, Custom, :to => [:vat_rate_numerator,:vat_rate_denominator,:vat_rate]
  93 + map :preferred_phone, Custom, :to => :preferred_phone_idx
  94 +
  95 + class Dumper
  96 + def preferred_phone_idx
  97 + object.phones.index(object.preferred_phone)
  98 + end
  99 +
  100 + def vat_rate_numerator
  101 + with_vat_rate(&:numerator)
  102 + end
  103 +
  104 + def vat_rate_denominator
  105 + with_vat_rate(&:denominator)
  106 + end
  107 +
  108 + def vat_rate
  109 + with_vat_rate(&:to_f)
  110 + end
  111 +
  112 + def with_vat_rate
  113 + vat_rate = object.vat_rate
  114 + yield vat_rate if vat_rate
  115 + end
  116 + end
  117 +
  118 + class Loader
  119 + def vat_rate
  120 + Rational(@dump[:vat_rate_numerator],@dump[:vat_rate_denominator])
  121 + end
  122 +
  123 + def preferred_phone
  124 + prefered_phone_idx = @dump[:preferred_phone_idx]
  125 + if prefered_phone_idx
  126 + phones.fetch(prefered_phone_idx)
  127 + end
  128 + end
  129 + end
  130 + end
  131 + end
  132 +
  133 + it 'should work' do
  134 + phone_a = Phone.new(:type => :home, :number => '0815 - 1')
  135 + phone_b = Phone.new(:type => :mobile,:number => '0815 - 2')
  136 +
  137 + address = Address.new(
  138 + :lines => "Snake Oil Ink\nPostbox foo bar",
  139 + :postcode => "085123"
  140 + )
  141 +
  142 + user = User.new(
  143 + :firstname => 'John',
  144 + :lastname => 'Doe',
  145 + :address => address,
  146 + :phones => [phone_a,phone_b],
  147 + :preferred_phone => phone_b,
  148 + :vat_rate => Rational(21,100)
  149 + )
  150 +
  151 + dump = User::Mapper.dump(user)
  152 +
  153 + dump.should == {
  154 + :surname =>'John',
  155 + :lastname =>'Doe',
  156 + :address =>{:lines=>"Snake Oil Ink\nPostbox foo bar", :postcode=>'085123'},
  157 + :phones =>
  158 + [
  159 + {:number=>"0815 - 1", :type=>"home"},
  160 + {:number=>"0815 - 2", :type=>"mobile"}
  161 + ],
  162 + :vat_rate_numerator => 21,
  163 + :vat_rate_denominator => 100,
  164 + :vat_rate => 0.21,
  165 + :preferred_phone_idx=>1
  166 + }
  167 +
  168 + loaded = User::Mapper.load(dump)
  169 + loaded.should == user
  170 + end
  171 +end
4 tasks/metrics/heckle.rake
@@ -34,9 +34,9 @@ begin
34 34 raise "ruby2ruby version #{Ruby2Ruby::VERSION} may not work properly, 1.2.2 *only* is recommended for use with heckle"
35 35 end
36 36
37   - require 'session'
  37 + require 'mapper'
38 38
39   - root_module_regexp = Regexp.union('Session')
  39 + root_module_regexp = Regexp.union('Mapper')
40 40
41 41 spec_dir = Pathname('spec/unit')
42 42
175 test.rb
... ... @@ -1,175 +0,0 @@
1   -require 'forwardable'
2   -require 'rational'
3   -require 'virtus'
4   -require 'pp'
5   -require 'rspec'
6   -
7   -$: << "lib"
8   -
9   -require 'mapper'
10   -
11   -class Phone
12   - include Virtus::ValueObject
13   -
14   - attribute :number,String
15   - attribute :type,String
16   -
17   - class Mapper
18   - include ::Mapper
19   - model Phone
20   - map :number, Object
21   - map :type, Object
22   - end
23   -
24   - class LoaderByHand
25   - def initialize(dump)
26   - @dump = dump
27   - end
28   -
29   - def number
30   - @dump.fetch(:number)
31   - end
32   -
33   - def type
34   - @dump.fetch(:type)
35   - end
36   -
37   - def load
38   - Phone.new(
39   - :number => number,
40   - :type => type
41   - )
42   - end
43   - end
44   -
45   - class DumperByHand
46   - def initialize(phone)
47   - @phone = phone
48   - end
49   -
50   - def phone
51   - @phone.number
52   - end
53   -
54   - def type
55   - @phone.type
56   - end
57   -
58   - def dump
59   - {
60   - :number => number,
61   - :type => type
62   - }
63   - end
64   - end
65   -end
66   -
67   -class Address
68   - include Virtus::ValueObject
69   -
70   - attribute :lines,String
71   - attribute :postcode,String
72   -
73   - class Mapper
74   - include ::Mapper
75   - model Address
76   - map :lines, Object
77   - map :postcode, Object
78   - end
79   -end
80   -
81   -class User
82   - include Virtus::ValueObject
83   -
84   - attribute :firstname,String
85   - attribute :lastname,String
86   - attribute :address,Address
87   - attribute :phones,Array[Phone]
88   - attribute :preferred_phone,Phone
89   - attribute :vat_rate,Rational
90   -
91   - class Mapper
92   - include ::Mapper
93   - model ::User
94   -
95   - map :firstname, Object, :to => :surname
96   - map :lastname, Object
97   - map :address, EmbeddedDocument, :mapper => Address::Mapper
98   - map :phones, EmbeddedCollection, :mapper => Phone::Mapper
99   - map :vat_rate, Custom, :to => [:vat_rate_numerator,:vat_rate_denominator,:vat_rate]
100   - map :preferred_phone, Custom, :to => :preferred_phone_idx
101   -
102   - class Dumper
103   - def preferred_phone_idx
104   - object.phones.index(object.preferred_phone)
105   - end
106   -
107   - def vat_rate_numerator
108   - with_vat_rate(&:numerator)
109   - end
110   -
111   - def vat_rate_denominator
112   - with_vat_rate(&:denominator)
113   - end
114   -
115   - def vat_rate
116   - with_vat_rate(&:to_f)
117   - end
118   -
119   - def with_vat_rate
120   - vat_rate = object.vat_rate
121   - yield vat_rate if vat_rate
122   - end
123   - end
124   -
125   - class Loader
126   - def vat_rate
127   - Rational(@dump[:vat_rate_numerator],@dump[:vat_rate_denominator])
128   - end
129   -
130   - def preferred_phone
131   - prefered_phone_idx = @dump[:preferred_phone_idx]
132   - if prefered_phone_idx
133   - phones.fetch(prefered_phone_idx)
134   - end
135   - end
136   - end
137   - end
138   -end
139   -
140   -phone_a = Phone.new(:type => :home, :number => '0815 - 1')
141   -phone_b = Phone.new(:type => :mobile,:number => '0815 - 2')
142   -
143   -address = Address.new(
144   - :lines => "Snake Oil Ink\nPostbox foo bar",
145   - :postcode => "085123"
146   -)
147   -
148   -user = User.new(
149   - :firstname => 'John',
150   - :lastname => 'Doe',
151   - :address => address,
152   - :phones => [phone_a,phone_b],
153   - :preferred_phone => phone_b,
154   - :vat_rate => Rational(21,100)
155   -)
156   -
157   -dump = User::Mapper.dump(user)
158   -
159   -dump.should == {
160   - :surname =>'John',
161   - :lastname =>'Doe',
162   - :address =>{:lines=>"Snake Oil Ink\nPostbox foo bar", :postcode=>'085123'},
163   - :phones =>
164   - [
165   - {:number=>"0815 - 1", :type=>"home"},
166   - {:number=>"0815 - 2", :type=>"mobile"}
167   - ],
168   - :vat_rate_numerator => 21,
169   - :vat_rate_denominator => 100,
170   - :vat_rate => 0.21,
171   - :preferred_phone_idx=>1
172   -}
173   -
174   -loaded = User::Mapper.load(dump)
175   -loaded.should == user

No commit comments for this range

Something went wrong with that request. Please try again.