icss 0.1.3 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.watchr +35 -3
- data/CHANGELOG.md +38 -0
- data/Gemfile +19 -14
- data/README.md +296 -0
- data/Rakefile +2 -6
- data/TODO.md +13 -0
- data/VERSION +1 -1
- data/examples/avro_examples/complicated.icss.yaml +14 -13
- data/examples/bnc.icss.yaml +70 -0
- data/examples/chronic.icss.yaml +3 -3
- data/examples/license.icss.yaml +7 -0
- data/examples/source1.icss.yaml +4 -0
- data/examples/source2.icss.yaml +4 -0
- data/examples/test_icss.yaml +67 -0
- data/icss.gemspec +103 -43
- data/lib/icss.rb +37 -15
- data/lib/icss/core_types.rb +19 -0
- data/lib/icss/error.rb +4 -0
- data/{init.rb → lib/icss/init.rb} +0 -0
- data/lib/icss/message.rb +124 -66
- data/lib/icss/message/message_sample.rb +144 -0
- data/lib/icss/protocol.rb +184 -131
- data/lib/icss/protocol/code_asset.rb +18 -0
- data/lib/icss/protocol/data_asset.rb +23 -0
- data/lib/icss/protocol/license.rb +41 -0
- data/lib/icss/protocol/source.rb +37 -0
- data/lib/icss/protocol/target.rb +68 -0
- data/lib/icss/receiver_model.rb +24 -0
- data/lib/icss/receiver_model/active_model_shim.rb +36 -0
- data/lib/icss/receiver_model/acts_as_catalog.rb +170 -0
- data/lib/icss/receiver_model/acts_as_hash.rb +177 -0
- data/lib/icss/receiver_model/acts_as_loadable.rb +47 -0
- data/lib/icss/receiver_model/acts_as_tuple.rb +100 -0
- data/lib/icss/receiver_model/locale/en.yml +27 -0
- data/lib/icss/receiver_model/to_geo_json.rb +19 -0
- data/lib/icss/receiver_model/tree_merge.rb +34 -0
- data/lib/icss/receiver_model/validations.rb +31 -0
- data/lib/icss/serialization.rb +51 -0
- data/lib/icss/serialization/zaml.rb +443 -0
- data/lib/icss/type.rb +148 -501
- data/lib/icss/type/base_type.rb +0 -0
- data/lib/icss/type/named_type.rb +184 -0
- data/lib/icss/type/record_field.rb +77 -0
- data/lib/icss/type/record_model.rb +49 -0
- data/lib/icss/type/record_schema.rb +54 -0
- data/lib/icss/type/record_type.rb +325 -0
- data/lib/icss/type/simple_types.rb +72 -0
- data/lib/icss/type/structured_schema.rb +288 -0
- data/lib/icss/type/type_factory.rb +144 -0
- data/lib/icss/type/union_schema.rb +41 -0
- data/lib/icss/view_helper.rb +56 -19
- data/notes/named_array.md +32 -0
- data/notes/on_include_vs_extend_etc.rb +176 -0
- data/notes/technical_details.md +278 -0
- data/spec/core_types_spec.rb +119 -0
- data/spec/fixtures/zaml_complex_hash.yaml +35 -0
- data/spec/icss_spec.rb +86 -23
- data/spec/message/message_sample_spec.rb +4 -0
- data/spec/message_spec.rb +139 -0
- data/spec/protocol/license_spec.rb +67 -0
- data/spec/protocol/protocol_catalog_spec.rb +48 -0
- data/spec/protocol/protocol_validations_spec.rb +176 -0
- data/spec/protocol/source_spec.rb +65 -0
- data/spec/protocol_spec.rb +91 -37
- data/spec/receiver_model_spec.rb +111 -0
- data/spec/serialization/zaml_spec.rb +81 -0
- data/spec/serialization/zaml_test.rb +473 -0
- data/spec/serialization_spec.rb +63 -0
- data/spec/spec_helper.rb +24 -7
- data/spec/support/icss_test_helper.rb +67 -0
- data/spec/support/load_example_protocols.rb +17 -0
- data/spec/type/base_type_spec.rb +0 -0
- data/spec/type/named_type_spec.rb +75 -0
- data/spec/type/record_field_spec.rb +44 -0
- data/spec/type/record_model_spec.rb +206 -0
- data/spec/type/record_schema_spec.rb +161 -0
- data/spec/type/record_type_spec.rb +155 -0
- data/spec/type/simple_types_spec.rb +121 -0
- data/spec/type/structured_schema_spec.rb +300 -0
- data/spec/type/type_catalog_spec.rb +44 -0
- data/spec/type/type_factory_spec.rb +93 -0
- data/spec/type/union_schema_spec.rb +0 -0
- data/spec/type_spec.rb +63 -0
- metadata +205 -144
- data/CHANGELOG.textile +0 -9
- data/Gemfile.lock +0 -40
- data/README.textile +0 -29
- data/lib/icss/brevity.rb +0 -136
- data/lib/icss/code_asset.rb +0 -16
- data/lib/icss/core_ext.rb +0 -9
- data/lib/icss/data_asset.rb +0 -22
- data/lib/icss/old.rb +0 -96
- data/lib/icss/protocol_set.rb +0 -48
- data/lib/icss/sample_message_call.rb +0 -142
- data/lib/icss/target.rb +0 -72
- data/lib/icss/type/factory.rb +0 -196
- data/lib/icss/validations.rb +0 -16
- data/spec/validations_spec.rb +0 -171
@@ -0,0 +1,161 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'yaml'
|
3
|
+
require 'gorillib/object/try_dup'
|
4
|
+
require 'icss/receiver_model/acts_as_hash'
|
5
|
+
require 'icss/receiver_model/active_model_shim'
|
6
|
+
require 'icss/type' #
|
7
|
+
require 'icss/type/simple_types' # Boolean, Integer, ...
|
8
|
+
require 'icss/type/named_type' # class methods for a named type: .metamodel .doc, .fullname, &c
|
9
|
+
require 'icss/type/record_type' # class methods for a record model: .field, .receive,
|
10
|
+
require 'icss/type/record_model' # instance methods for a record model
|
11
|
+
require 'icss/type/type_factory' # factory for instances based on type
|
12
|
+
require 'icss/type/structured_schema' # generate type from array, hash, &c schema
|
13
|
+
require 'icss/type/record_schema'
|
14
|
+
require 'icss/type/record_field'
|
15
|
+
|
16
|
+
require ENV.root_path('spec/support/icss_test_helper')
|
17
|
+
include IcssTestHelper
|
18
|
+
|
19
|
+
module Icss
|
20
|
+
module This
|
21
|
+
module That
|
22
|
+
class TheOther
|
23
|
+
def bob
|
24
|
+
'hi bob'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
module Right
|
29
|
+
class Here
|
30
|
+
include Icss::Meta::RecordModel
|
31
|
+
end
|
32
|
+
class OverThere < Here
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
class ::Icss::Numeric < ::Numeric ; end
|
37
|
+
end
|
38
|
+
|
39
|
+
include IcssTestHelper
|
40
|
+
|
41
|
+
describe Icss::Meta::RecordSchema do
|
42
|
+
|
43
|
+
BASIC_RECORD_SCHEMA = {:type => :record, :name => 'business.restaurant',
|
44
|
+
:doc => "y'know, for food and stuff",
|
45
|
+
:fields => [ { :name => 'menu', :type => 'string' } ] }
|
46
|
+
before(:each) do
|
47
|
+
remove_icss_constants('Business::Restaurant')
|
48
|
+
remove_icss_constants(:LabExperiment, :DayOfWeek, :GeoCoordinates)
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "With basic schema" do
|
52
|
+
before(:each) do
|
53
|
+
@model_klass = Icss::Meta::RecordSchema.receive(BASIC_RECORD_SCHEMA)
|
54
|
+
@schema_writer = @model_klass._schema
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'has schema_writer' do
|
58
|
+
@schema_writer.type.should == :record
|
59
|
+
@schema_writer.fullname.should == 'business.restaurant'
|
60
|
+
@schema_writer.fields.length.should == 1
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'creates a named class' do
|
64
|
+
@model_klass.name.to_s.should == 'Icss::Business::Restaurant'
|
65
|
+
Icss::Business::Restaurant.fullname.should == "business.restaurant"
|
66
|
+
Icss::Business::Restaurant.doc.should == "y'know, for food and stuff"
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'has accessors and receivers for the fields' do
|
70
|
+
blank_model = Class.new{ include Icss::Meta::RecordModel }
|
71
|
+
(@model_klass.public_methods - blank_model.public_methods).sort.should == [
|
72
|
+
:_domain_id_field, :_schema, :is_a, :_doc_hints,
|
73
|
+
].sort.uniq
|
74
|
+
(@model_klass.public_instance_methods - Object.public_instance_methods).sort.should == [
|
75
|
+
:attr_set?, :menu, :menu=, :receive!, :receive_menu
|
76
|
+
].sort.uniq
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#is_a' do
|
81
|
+
[
|
82
|
+
[ [Icss::This::That::TheOther], ['Icss::This::That::TheOther']],
|
83
|
+
[ ['this.that.the_other'], ['Icss::This::That::TheOther'] ],
|
84
|
+
[ ['this.right.here'], ['Icss::This::Right::Here', 'Icss::Meta::This::Right::HereModel'] ],
|
85
|
+
[ ['this.that.the_other', 'this.right.here'], ['Icss::This::That::TheOther', 'Icss::Meta::This::Right::HereModel'] ],
|
86
|
+
].each do |given_is_a, expected_superklasses|
|
87
|
+
it "sets a superclass from #{given_is_a}" do
|
88
|
+
schema_hsh = BASIC_RECORD_SCHEMA.merge(:is_a => given_is_a)
|
89
|
+
@model_klass = Icss::Meta::RecordSchema.receive(schema_hsh)
|
90
|
+
expected_superklasses.each do |superklass|
|
91
|
+
@model_klass.should < superklass.constantize
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'does NOT follow superclasses of multiple inheritance parents' do
|
97
|
+
schema_hsh = BASIC_RECORD_SCHEMA.merge(:is_a => ['this.that.the_other', 'this.right.over_there'])
|
98
|
+
@model_klass = Icss::Meta::RecordSchema.receive(schema_hsh)
|
99
|
+
@model_klass.should < Icss::This::That::TheOther
|
100
|
+
@model_klass.should_not < Icss::This::Right::OverThere
|
101
|
+
@model_klass.should < Icss::This::Right::OverThere.metamodel
|
102
|
+
@model_klass.should_not < Icss::This::Right::Here
|
103
|
+
@model_klass.should_not < Icss::This::Right::Here.metamodel
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'does allow explicitly-listed superclasses of multiple inheritance parents' do
|
107
|
+
schema_hsh = BASIC_RECORD_SCHEMA.merge(:is_a => ['this.that.the_other', 'this.right.over_there', 'this.right.here'])
|
108
|
+
@model_klass = Icss::Meta::RecordSchema.receive(schema_hsh)
|
109
|
+
@model_klass.should < Icss::This::That::TheOther
|
110
|
+
@model_klass.should_not < Icss::This::Right::OverThere
|
111
|
+
@model_klass.should < Icss::This::Right::OverThere.metamodel
|
112
|
+
@model_klass.should_not < Icss::This::Right::Here
|
113
|
+
@model_klass.should < Icss::This::Right::Here.metamodel
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe Icss::Meta::RecordModel do
|
119
|
+
context 'record schema' do
|
120
|
+
before do
|
121
|
+
@klass = Icss::Meta::TypeFactory.receive({
|
122
|
+
'type' => 'record',
|
123
|
+
'name' => 'lab_experiment',
|
124
|
+
'is_a' => ['this.that.the_other', 'this.right.here'],
|
125
|
+
'fields' => [
|
126
|
+
{ 'name' => 'temperature', 'type' => 'float' },
|
127
|
+
{ 'name' => 'day', 'type' => {
|
128
|
+
'name' => 'day_of_week', :type => 'enum',
|
129
|
+
'symbols' => [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday] }},
|
130
|
+
{ 'name' => 'geo', 'type' => {
|
131
|
+
:type => 'record', 'name' => 'geo_coordinates',
|
132
|
+
'fields' => [
|
133
|
+
{ 'name' => 'latitude', 'type' => 'float' },
|
134
|
+
{ 'name' => 'longitude', 'type' => 'float' },
|
135
|
+
{ 'name' => 'spatial_extent', 'type' =>
|
136
|
+
{ 'type' => 'array', 'items' => {
|
137
|
+
'type' => 'array', 'items' => 'float' }}},
|
138
|
+
]}},
|
139
|
+
] })
|
140
|
+
@obj = @klass.receive({ :temperature => 97.4, :day => 'tuesday',
|
141
|
+
:geo => {
|
142
|
+
'longitude' => '-97.75', :latitude => "30.03",
|
143
|
+
'spatial_extent' => [ ['-97.75', '30.03'], ['-97.70', '30.1'], ['-97.90', '30.1'] ]
|
144
|
+
} })
|
145
|
+
end
|
146
|
+
it 'handles array of record of ...' do
|
147
|
+
@klass.to_s.should == 'Icss::LabExperiment'
|
148
|
+
@obj.should be_a(@klass)
|
149
|
+
@obj.should be_a(Icss::This::That::TheOther)
|
150
|
+
@obj.should be_a(Icss::This::Right::Here.metamodel)
|
151
|
+
end
|
152
|
+
it 'receives data' do
|
153
|
+
@obj.temperature.should == 97.4
|
154
|
+
@obj.day.should == :tuesday
|
155
|
+
@obj.geo.latitude.should == 30.03
|
156
|
+
@obj.geo.longitude.should == -97.75
|
157
|
+
@obj.geo.should be_a(Icss::GeoCoordinates)
|
158
|
+
@obj.geo.spatial_extent.should == [ [-97.75, 30.03], [-97.70, 30.1], [-97.90, 30.1] ]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'gorillib/object/try_dup'
|
3
|
+
require 'icss/receiver_model/acts_as_hash'
|
4
|
+
require 'icss/receiver_model/acts_as_loadable'
|
5
|
+
require 'icss/receiver_model/acts_as_catalog'
|
6
|
+
require 'icss/type'
|
7
|
+
require 'icss/type/simple_types'
|
8
|
+
require 'icss/type/named_type'
|
9
|
+
require 'icss/type/record_type'
|
10
|
+
require 'icss/type/record_model' # instance methods for a record model
|
11
|
+
require 'icss/type/type_factory' #
|
12
|
+
require 'icss/type/structured_schema'
|
13
|
+
#
|
14
|
+
require 'icss'
|
15
|
+
#
|
16
|
+
require ENV.root_path('spec/support/icss_test_helper')
|
17
|
+
include IcssTestHelper
|
18
|
+
|
19
|
+
describe Icss::Meta::RecordType do
|
20
|
+
|
21
|
+
before(:each) do
|
22
|
+
IcssTestHelper.remove_icss_constants('Smurf::Poppa', 'Smurf::Brainy', 'Smurf::Smurfette')
|
23
|
+
module Icss
|
24
|
+
module Smurf
|
25
|
+
class Poppa < Icss::SmurfRecord
|
26
|
+
field :smurfiness, :int
|
27
|
+
end
|
28
|
+
module Brainy
|
29
|
+
include Icss::Meta::RecordModel
|
30
|
+
field :has_glasses, Boolean
|
31
|
+
end
|
32
|
+
class Smurfette < Poppa
|
33
|
+
include Brainy
|
34
|
+
field :blondness, Integer
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:new_smurf_klass){ k = Class.new(Icss::Smurf::Poppa) }
|
41
|
+
let(:module_smurf ){ m = Module.new; m.send(:extend, Icss::Meta::RecordType) ; m }
|
42
|
+
let(:poppa ){ Icss::Smurf::Poppa.new() }
|
43
|
+
let(:smurfette ){ Icss::Smurf::Smurfette.new() }
|
44
|
+
|
45
|
+
it 'adds few class methods' do
|
46
|
+
(Icss::Smurf::Smurfette.public_methods - Class.public_methods).sort.should == [
|
47
|
+
:after_receive, :after_receivers,
|
48
|
+
:field, :field_names, :fields, :has_field?, :field_named,
|
49
|
+
:metamodel, :to_schema, :is_core?,
|
50
|
+
:fullname, :namespace, :basename, :doc, :doc=,
|
51
|
+
:rcvr, :rcvr_alias, :rcvr_remaining, :receive, :pathname
|
52
|
+
].sort
|
53
|
+
end
|
54
|
+
it 'adds few methods' do
|
55
|
+
(Icss::Smurf::Smurfette.new.public_methods -
|
56
|
+
Object.public_methods -
|
57
|
+
[ :attr_set?, :receive!, ] # maybe added later by record_model, they're OK
|
58
|
+
).sort.should == [
|
59
|
+
:blondness, :blondness=, :has_glasses, :has_glasses=,
|
60
|
+
:receive_blondness,:receive_has_glasses,
|
61
|
+
:receive_smurfiness, :smurfiness, :smurfiness=
|
62
|
+
].sort
|
63
|
+
end
|
64
|
+
|
65
|
+
context '.field' do
|
66
|
+
it 'adds field names' do
|
67
|
+
Icss::Smurf::Poppa.field_names.should == [:smurfiness]
|
68
|
+
end
|
69
|
+
it 'adds field info' do
|
70
|
+
Icss::Smurf::Poppa.field_named(:smurfiness).to_hash.should == {:name => :smurfiness, :type => :int}
|
71
|
+
end
|
72
|
+
it 'inherits parent fields' do
|
73
|
+
new_smurf_klass.field(:birthday, :time)
|
74
|
+
Icss::Smurf::Poppa.field_names.should == [:smurfiness]
|
75
|
+
Icss::Smurf::Poppa.field_named(:smurfiness).to_hash.should == {:name => :smurfiness, :type => :int}
|
76
|
+
new_smurf_klass.field_names.should == [:smurfiness, :birthday]
|
77
|
+
new_smurf_klass.field_named(:smurfiness).to_hash.should == {:name => :smurfiness, :type => :int}
|
78
|
+
new_smurf_klass.field_named(:birthday ).to_hash.should == {:name => :birthday, :type => :time}
|
79
|
+
end
|
80
|
+
it 'sets accessor visibility' do
|
81
|
+
new_smurf_klass.field(:field_1, Integer, :accessor => :none)
|
82
|
+
new_smurf_klass.field(:field_2, Integer, :accessor => :private)
|
83
|
+
new_smurf_klass.field(:field_3, Integer, :accessor => :protected)
|
84
|
+
new_smurf = new_smurf_klass.new
|
85
|
+
new_smurf.should_not respond_to('field_1=')
|
86
|
+
new_smurf.should_not respond_to('field_1')
|
87
|
+
lambda{ new_smurf.field_2 = :hi }.should raise_error(NoMethodError, /private method \`field_2=/)
|
88
|
+
lambda{ new_smurf.field_2 }.should raise_error(NoMethodError, /private method \`field_2/)
|
89
|
+
lambda{ new_smurf.field_3 = :yo }.should raise_error(NoMethodError, /protected method \`field_3=/)
|
90
|
+
lambda{ new_smurf.field_3 }.should raise_error(NoMethodError, /protected method \`field_3/)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context '.fields' do
|
95
|
+
it 'inheritance works without weirdness' do
|
96
|
+
Icss::Smurf::Poppa.field_names.should == [:smurfiness]
|
97
|
+
Icss::Smurf::Smurfette.field_names.should == [:smurfiness, :has_glasses, :blondness]
|
98
|
+
Icss::Smurf::Brainy.field_names.should == [:has_glasses]
|
99
|
+
end
|
100
|
+
#
|
101
|
+
it 'fields dynamically added to superclasses appear, in order of ancestry' do
|
102
|
+
new_smurf_klass.send(:include, module_smurf)
|
103
|
+
module_smurf.field_names.should == []
|
104
|
+
new_smurf_klass.field_names.should == [:smurfiness]
|
105
|
+
#
|
106
|
+
module_smurf.field(:smurfberries, :integer)
|
107
|
+
new_smurf_klass.field_names.should == [:smurfiness, :smurfberries]
|
108
|
+
#
|
109
|
+
new_smurf_klass.field(:singing, :boolean)
|
110
|
+
module_smurf.field(:smurfberry_crunch, :integer)
|
111
|
+
new_smurf_klass.field_names.should == [:smurfiness, :smurfberries, :smurfberry_crunch, :singing]
|
112
|
+
end
|
113
|
+
#
|
114
|
+
it 're-announcing a field modifies its info hash downstream without rearranging' do
|
115
|
+
uncle_smurf = Class.new(Icss::Smurf::Poppa)
|
116
|
+
baby_smurf = Class.new(uncle_smurf)
|
117
|
+
baby_smurf.field_names.should == [:smurfiness]
|
118
|
+
uncle_smurf.field_named(:smurfiness).to_hash.should == {:name => :smurfiness, :type => :int}
|
119
|
+
baby_smurf.field_named( :smurfiness).to_hash.should == {:name => :smurfiness, :type => :int}
|
120
|
+
#
|
121
|
+
uncle_smurf.field(:smurfiness, :float, :validates => { :numericality => true })
|
122
|
+
Icss::Smurf::Poppa.field_named(:smurfiness).to_hash.should == {:name => :smurfiness, :type => :int}
|
123
|
+
uncle_smurf.field_named(:smurfiness).to_hash.should == {:name => :smurfiness, :type => :float, :validates => { :numericality => true }}
|
124
|
+
baby_smurf.field_named(:smurfiness ).to_hash.should == {:name => :smurfiness, :type => :float, :validates => { :numericality => true }}
|
125
|
+
end
|
126
|
+
it 'does not override an existing method' do
|
127
|
+
new_smurf_klass.class_eval{ def foo() "hello!" end }
|
128
|
+
new_smurf_klass.field :foo, String
|
129
|
+
new_smurf_klass.new.foo.should == "hello!"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'class schema' do
|
134
|
+
it "has .fullname, .namespace, .basename, and .doc" do
|
135
|
+
[:fullname, :namespace, :basename, :doc].each do |meth|
|
136
|
+
Icss::Smurf::Smurfette.should respond_to(meth)
|
137
|
+
Icss::Smurf::Smurfette.new.should_not respond_to(meth)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
it "name corresponds to its class & module scope" do
|
141
|
+
Icss::Smurf::Smurfette.basename.should == 'smurfette'
|
142
|
+
Icss::Smurf::Smurfette.namespace.should == 'smurf'
|
143
|
+
Icss::Smurf::Smurfette.fullname.should == 'smurf.smurfette'
|
144
|
+
end
|
145
|
+
it "has a settable doc string" do
|
146
|
+
Icss::Smurf::Poppa.doc = "Poppa Doc: be cool with them Haitians"
|
147
|
+
Icss::Smurf::Poppa.doc.should == "Poppa Doc: be cool with them Haitians"
|
148
|
+
Icss::Smurf::Smurfette.doc.should == "Poppa Doc: be cool with them Haitians"
|
149
|
+
Icss::Smurf::Smurfette.doc = "Gentlesmurfs prefer blondes"
|
150
|
+
Icss::Smurf::Smurfette.doc.should == "Gentlesmurfs prefer blondes"
|
151
|
+
Icss::Smurf::Poppa.doc.should == "Poppa Doc: be cool with them Haitians"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'time'
|
3
|
+
require 'icss/type'
|
4
|
+
require 'icss/type/simple_types'
|
5
|
+
require ENV.root_path('spec/support/icss_test_helper')
|
6
|
+
include IcssTestHelper
|
7
|
+
|
8
|
+
describe 'Icss::SIMPLE_TYPES' do
|
9
|
+
it('tests all of them'){ SIMPLE_TYPES_TO_TEST.values.map(&:first).map(&:to_s).sort.should == Icss::SIMPLE_TYPES.values.map(&:to_s).sort }
|
10
|
+
it('tests all of them'){ SIMPLE_TYPES_TO_TEST.keys.map(&:to_s).sort.should == Icss::SIMPLE_TYPES.keys.map(&:to_s).sort }
|
11
|
+
|
12
|
+
SIMPLE_TYPES_TO_TEST.each do |basename, (type_klass, parent_base_class, parent_instance)|
|
13
|
+
context type_klass do
|
14
|
+
it 'is named in Icss::SIMPLE_TYPES' do
|
15
|
+
basename = Icss::SIMPLE_TYPES.key(type_klass)
|
16
|
+
type_klass.to_schema == basename
|
17
|
+
end
|
18
|
+
it 'is named in Icss::SIMPLE_TYPES' do
|
19
|
+
basename = Icss::SIMPLE_TYPES.key(type_klass)
|
20
|
+
type_klass.to_schema == basename
|
21
|
+
end
|
22
|
+
it 'returns its type name as its schema' do
|
23
|
+
schema = type_klass.to_schema
|
24
|
+
schema.should be_a(Symbol)
|
25
|
+
Icss::SIMPLE_TYPES[schema].should == type_klass
|
26
|
+
end
|
27
|
+
it 'is simple? and simple?, but not record? or union?' do
|
28
|
+
Icss::Meta::Type.simple?( type_klass).should be_true
|
29
|
+
Icss::Meta::Type.simple?( type_klass).should be_true
|
30
|
+
Icss::Meta::Type.union?( type_klass).should be_false
|
31
|
+
Icss::Meta::Type.record?( type_klass).should be_false
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'descends from a base type' do
|
35
|
+
type_klass.should be <= parent_base_class unless type_klass == Boolean
|
36
|
+
type_klass.receive(parent_instance).should be_a(parent_base_class)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'has .receive' do
|
40
|
+
obj = type_klass.receive(parent_instance)
|
41
|
+
if FALSE_PARENTS.include?(type_klass.to_s)
|
42
|
+
obj.should be_a(parent_base_class)
|
43
|
+
else
|
44
|
+
obj.should be_a(type_klass)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.receive' do
|
51
|
+
def self.it_correctly_converts(type, orig, desired)
|
52
|
+
it "for #{type} converts #{orig.inspect} to #{desired.inspect}" do
|
53
|
+
type.receive(orig).should == desired
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'type coercion' do
|
58
|
+
[
|
59
|
+
[Symbol, 'foo', :foo], [Symbol, :foo, :foo], [Symbol, nil, nil], [Symbol, '', nil],
|
60
|
+
[Integer, '5', 5], [Integer, 5, 5], [Integer, nil, nil], [Integer, '', nil],
|
61
|
+
[Integer, '5', 5], [Integer, 5, 5], [Integer, nil, nil], [Integer, '', nil],
|
62
|
+
[Long, '5', 5], [Long, 5, 5], [Long, nil, nil], [Long, '', nil],
|
63
|
+
[Float, '5.2', 5.2], [Float, 5.2, 5.2], [Float, nil, nil], [Float, '', nil],
|
64
|
+
[Double, '5.2', 5.2], [Double, 5.2, 5.2], [Double,nil, nil], [Double,'', nil],
|
65
|
+
[String, 'foo', 'foo'], [String, :foo, 'foo'], [String, nil, ""], [String, '', ""],
|
66
|
+
[String, 5.2, "5.2"], [String, [1], "[1]"], [String, 1, "1"],
|
67
|
+
[Binary, 'foo', 'foo'], [Binary, :foo, 'foo'], [Binary, nil, ""], [Binary, '', ""],
|
68
|
+
[Binary, 5.2, "5.2"], [Binary, [1], "[1]"], [Binary, 1, "1"],
|
69
|
+
[Time, '1985-11-05T04:03:02Z', Time.parse('1985-11-05T04:03:02Z')],
|
70
|
+
[Time, '1985-11-05T04:03:02+06:00', Time.parse('1985-11-04T22:03:02Z')],
|
71
|
+
[Time, Time.parse('1985-11-05T04:03:02Z'), Time.parse('1985-11-05T04:03:02Z')],
|
72
|
+
[Time, nil, nil], [Time, '', nil], [Time, 'blah', nil],
|
73
|
+
[Boolean, '0', true], [Boolean, 0, true], [Boolean, '', false], [Boolean, [], true], [Boolean, nil, nil],
|
74
|
+
[Boolean, '1', true], [Boolean, 1, true], [Boolean, '5', true], [Boolean, 'true', true],
|
75
|
+
[NilClass, nil, nil],
|
76
|
+
].each do |type, orig, desired|
|
77
|
+
it_correctly_converts type, orig, desired
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'NilClass' do
|
81
|
+
it 'only accepts nil' do
|
82
|
+
lambda{ NilClass.receive('hello') }.should raise_error(ArgumentError, /must be initialized with nil, but \[hello\] was given/)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
describe '::Boolean' do
|
91
|
+
let(:true_bool ){ ::Boolean.new(true) }
|
92
|
+
let(:false_bool){ ::Boolean.new(false) }
|
93
|
+
it("has #class Boolean" ){ (true_bool.class).should == ::Boolean ; (false_bool.class).should == ::Boolean }
|
94
|
+
describe 'mimicking true/false' do
|
95
|
+
it(":!" ){ (! true_bool).should == (! true) ; (! false_bool).should == (! false) }
|
96
|
+
it(":nil?" ){ (true_bool.nil?).should == (true.nil?) ; (false_bool.nil?).should == (false.nil?) }
|
97
|
+
it(":to_s" ){ (true_bool.to_s).should == (true.to_s) ; (false_bool.to_s).should == (false.to_s) }
|
98
|
+
{ :!= => [true, false, nil],
|
99
|
+
:!~ => [true, false, nil],
|
100
|
+
:& => [true, false, nil],
|
101
|
+
:<=> => [true, false, nil],
|
102
|
+
:== => [true, false, nil],
|
103
|
+
:=== => [true, false, nil],
|
104
|
+
:=~ => [true, false, nil],
|
105
|
+
:^ => [true, false, nil],
|
106
|
+
:eql? => [true, false, nil],
|
107
|
+
:| => [true, false, nil],
|
108
|
+
:instance_of? => [::TrueClass, ::FalseClass, ::Object],
|
109
|
+
:is_a? => [::TrueClass, ::FalseClass, ::Object],
|
110
|
+
:kind_of? => [::TrueClass, ::FalseClass, ::Object],
|
111
|
+
}.each do |meth, meth_args|
|
112
|
+
it meth do
|
113
|
+
meth_args.each do |meth_arg|
|
114
|
+
true_bool.send( meth, meth_arg).should equal(true.send( meth, meth_arg))
|
115
|
+
false_bool.send(meth, meth_arg).should equal(false.send(meth, meth_arg))
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
@@ -0,0 +1,300 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'gorillib/object/try_dup'
|
3
|
+
require 'icss/receiver_model/acts_as_hash'
|
4
|
+
require 'icss/type' #
|
5
|
+
require 'icss/type/simple_types' # Boolean, Integer, ...
|
6
|
+
require 'icss/type/named_type' # class methods for a named type: .metamodel .doc, .fullname, &c
|
7
|
+
require 'icss/type/record_type' # class methods for a record model: .field, .receive,
|
8
|
+
require 'icss/type/record_model' # instance methods for a record model
|
9
|
+
require 'icss/type/type_factory' # turn schema into types
|
10
|
+
require 'icss/type/structured_schema' # loads array, hash, enum, fixed and simple schema
|
11
|
+
#
|
12
|
+
require ENV.root_path('spec/support/icss_test_helper')
|
13
|
+
include IcssTestHelper
|
14
|
+
|
15
|
+
|
16
|
+
module Icss
|
17
|
+
module Test
|
18
|
+
module Foo ; class Bar ; end ; end
|
19
|
+
end
|
20
|
+
class Top ; end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'complex types' do
|
24
|
+
before(:each) do
|
25
|
+
IcssTestHelper.remove_icss_constants('Test::Foo::Bar', 'Test::Foo', 'St::Bob')
|
26
|
+
module Icss
|
27
|
+
module Test
|
28
|
+
module Foo ; class Bar ; end ; end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe Icss::Meta::SimpleSchema do
|
34
|
+
let(:bob){ Icss::Meta::SimpleSchema.receive({ :name => 'st.bob', :type => :simple, :is_a => [Binary], :doc => "hi, bob" }) }
|
35
|
+
it 'loads types that inherit from simple base types' do
|
36
|
+
bob.should < Binary
|
37
|
+
bob.should < String
|
38
|
+
bob.should < Icss::Meta::St::BobModel
|
39
|
+
bob.metamodel.should == Icss::Meta::St::BobModel
|
40
|
+
end
|
41
|
+
it 'has doc and all that' do
|
42
|
+
bob.fullname.should == 'st.bob'
|
43
|
+
bob.basename.should == :'bob'
|
44
|
+
bob.doc.should == 'hi, bob'
|
45
|
+
bob.is_a.should == [Binary]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe Icss::Meta::ArraySchema do
|
50
|
+
[
|
51
|
+
[{:type => :array, :items => :'test.foo.bar'}, 'Icss::Test::Foo::Bar', ],
|
52
|
+
[{:type => :array, :items => :'int' }, 'Integer', ],
|
53
|
+
[{:type => :array, :items => :'top'}, 'Icss::Top', ],
|
54
|
+
].each do |schema, expected_item_factory|
|
55
|
+
describe "With #{schema}" do
|
56
|
+
before do
|
57
|
+
@model_klass = Icss::Meta::ArraySchema.receive(schema)
|
58
|
+
@schema_writer = @model_klass._schema
|
59
|
+
end
|
60
|
+
it 'is a descendent of Array and its metatype' do
|
61
|
+
@model_klass.should < Array
|
62
|
+
@model_klass.should be_a Icss::Meta::ArrayType
|
63
|
+
@model_klass.should be_a Icss::Meta::NamedType
|
64
|
+
end
|
65
|
+
it 'has items and an item_factory' do
|
66
|
+
@model_klass.should respond_to(:items)
|
67
|
+
@model_klass.items.should == expected_item_factory.constantize
|
68
|
+
end
|
69
|
+
it 'has schema_writer' do
|
70
|
+
@schema_writer.type.should == :array
|
71
|
+
@schema_writer.to_hash.should == schema
|
72
|
+
# @schema_writer.should be_valid
|
73
|
+
@schema_writer.items = nil
|
74
|
+
# @schema_writer.should_not be_valid
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "klass name" do
|
80
|
+
[
|
81
|
+
[ 'ArrayOfSymbol', :symbol ],
|
82
|
+
[ 'ArrayOfArrayOfInteger', { :type => :array, :items => :int } ],
|
83
|
+
[ 'ArrayOfHashOfArrayOfString', { :type => :map, :values => { :type => :array, :items => :string } } ],
|
84
|
+
[ 'ArrayOfTestDotFooDotBar', 'test.foo.bar' ],
|
85
|
+
[ 'ArrayOfHashOfArrayOfTestDotFooDotBar', { :type => :map, :values => { :type => :array, :items => 'test.foo.bar' } } ],
|
86
|
+
].each do |expected_name, items_schema|
|
87
|
+
it "is #{expected_name} for #{items_schema}" do
|
88
|
+
schema = {:type => :array, :items => items_schema }
|
89
|
+
kl = Icss::Meta::ArraySchema.receive(schema)
|
90
|
+
kl.fullname.should == expected_name
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe Icss::Meta::ArrayType do
|
97
|
+
context '.receive' do
|
98
|
+
it 'generates an instance of the type' do
|
99
|
+
Icss::Meta::ArraySchema.receive({:type => :array, :items => :'int' })
|
100
|
+
inst = Icss::ArrayOfInteger.receive([1, 2.0, nil, "4.5", "8", "fnord"])
|
101
|
+
inst.should be_a(Array)
|
102
|
+
inst.should be_a(Icss::ArrayOfInteger)
|
103
|
+
end
|
104
|
+
it 'with nil or "" gives nil; with [] gives []' do
|
105
|
+
Icss::Meta::ArraySchema.receive({:type => :array, :items => :'int' })
|
106
|
+
inst = Icss::ArrayOfInteger.receive(nil)
|
107
|
+
inst.should be_nil
|
108
|
+
inst = Icss::ArrayOfInteger.receive('')
|
109
|
+
inst.should be_nil
|
110
|
+
inst = Icss::ArrayOfInteger.receive([])
|
111
|
+
inst.should == []
|
112
|
+
inst = Icss::ArrayOfInteger.receive({})
|
113
|
+
inst.should == []
|
114
|
+
inst.should be_a(Icss::ArrayOfInteger)
|
115
|
+
end
|
116
|
+
it 'applies the item_factory' do
|
117
|
+
Icss::Meta::ArraySchema.receive({:type => :array, :items => :'int' })
|
118
|
+
inst = Icss::ArrayOfInteger.receive([1, 2.0, nil, "4.5", "8", "fnord"])
|
119
|
+
inst.should eql([1, 2, nil, 4, 8, 0]) # (1 == 1.0) is true but 1.eql?(1.0) is false
|
120
|
+
end
|
121
|
+
it 'passes items through if they already is_a? the item factory type'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe Icss::Meta::HashSchema do
|
126
|
+
[
|
127
|
+
[{:type => :map, :values => :'test.foo.bar'}, 'Icss::Test::Foo::Bar', ],
|
128
|
+
[{:type => :map, :values => :'int' }, 'Integer', ],
|
129
|
+
[{:type => :map, :values => :'top'}, 'Icss::Top', ],
|
130
|
+
].each do |schema, expected_value_factory|
|
131
|
+
describe "With #{schema}" do
|
132
|
+
before do
|
133
|
+
@model_klass = Icss::Meta::HashSchema.receive(schema)
|
134
|
+
@schema_writer = @model_klass._schema
|
135
|
+
end
|
136
|
+
it 'is a descendent of Hash and of its metatype' do
|
137
|
+
@model_klass.should < Hash
|
138
|
+
@model_klass.should be_a Icss::Meta::HashType
|
139
|
+
@model_klass.should be_a Icss::Meta::NamedType
|
140
|
+
end
|
141
|
+
it 'has values and an value_factory' do
|
142
|
+
@model_klass.should respond_to(:values)
|
143
|
+
@model_klass.values.should == expected_value_factory.constantize
|
144
|
+
end
|
145
|
+
it 'has schema_writer' do
|
146
|
+
@schema_writer.type.should == :map
|
147
|
+
@schema_writer.to_hash.should == schema
|
148
|
+
# @schema_writer.should be_valid
|
149
|
+
@schema_writer.values = nil
|
150
|
+
# @schema_writer.should_not be_valid
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
context "klass name" do
|
155
|
+
[
|
156
|
+
[ 'HashOfSymbol', :symbol ],
|
157
|
+
[ 'HashOfHashOfInteger', { :type => :map, :values => :int } ],
|
158
|
+
[ 'HashOfHashOfArrayOfString', { :type => :map, :values => { :type => :array, :items => :string } } ],
|
159
|
+
[ 'HashOfTestDotFooDotBar', 'test.foo.bar' ],
|
160
|
+
[ 'HashOfHashOfArrayOfTestDotFooDotBar', { :type => :map, :values => { :type => :array, :items => 'test.foo.bar' } } ],
|
161
|
+
].each do |expected_name, values_schema|
|
162
|
+
it "is #{expected_name} for #{values_schema}" do
|
163
|
+
schema = {:type => :map, :values => values_schema }
|
164
|
+
kl = Icss::Meta::HashSchema.receive(schema)
|
165
|
+
kl.fullname.should == expected_name
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe Icss::Meta::HashType do
|
172
|
+
context '.receive' do
|
173
|
+
it 'generates an instance of the type' do
|
174
|
+
Icss::Meta::HashSchema.receive({:type => :map, :values => :'int' })
|
175
|
+
inst = Icss::HashOfInteger.receive([1, 2.0, nil, "4.5", "8", "fnord"])
|
176
|
+
inst.should be_a(Hash)
|
177
|
+
inst.should be_a(Icss::HashOfInteger)
|
178
|
+
end
|
179
|
+
it 'with nil or "" gives nil; with [] gives []' do
|
180
|
+
Icss::Meta::HashSchema.receive({:type => :map, :values => :'int' })
|
181
|
+
inst = Icss::HashOfInteger.receive(nil)
|
182
|
+
inst.should be_nil
|
183
|
+
inst = Icss::HashOfInteger.receive('')
|
184
|
+
inst.should be_nil
|
185
|
+
inst = Icss::HashOfInteger.receive([])
|
186
|
+
inst.should == {}
|
187
|
+
inst = Icss::HashOfInteger.receive({})
|
188
|
+
inst.should == {}
|
189
|
+
inst.should be_a(Icss::HashOfInteger)
|
190
|
+
end
|
191
|
+
it 'applies the value_factory' do
|
192
|
+
Icss::Meta::HashSchema.receive({:type => :map, :values => :'int' })
|
193
|
+
inst = Icss::HashOfInteger.receive({ :a => 1, 'b' => 2.0, :c => nil, 'd' => "4.5", :e => "8", 99 => "fnord"})
|
194
|
+
inst.should eql({ :a => 1, 'b' => 2, :c => nil, 'd' => 4, :e => 8, 99 => 0})
|
195
|
+
end
|
196
|
+
it 'passes items through if they already is_a? the values factory type'
|
197
|
+
it 'warns when I supply "items" not "values"' do
|
198
|
+
lambda{
|
199
|
+
Icss::Meta::HashSchema.receive({:type => :map, :items => :int })
|
200
|
+
}.should raise_error(ArgumentError)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe Icss::Meta::EnumSchema do
|
206
|
+
[
|
207
|
+
{:type => :enum, :name => 'games.coin_outcomes', :symbols => %w[heads tails sideways]},
|
208
|
+
{:type => :enum, :name => 'always_awesome', :symbols => %w[AWESOME]},
|
209
|
+
{:type => :enum, :name => 'jackson.five', :symbols => [:a, :b, :c]},
|
210
|
+
].each do |schema|
|
211
|
+
describe "With #{schema}" do
|
212
|
+
before do
|
213
|
+
@model_klass = Icss::Meta::EnumSchema.receive(schema)
|
214
|
+
@schema_writer = @model_klass._schema
|
215
|
+
end
|
216
|
+
it 'is a descendent of Enum and of its metatype' do
|
217
|
+
@model_klass.should < Symbol
|
218
|
+
@model_klass.should be_a Icss::Meta::EnumType
|
219
|
+
@model_klass.should be_a Icss::Meta::NamedType
|
220
|
+
end
|
221
|
+
it 'has symbols' do
|
222
|
+
@model_klass.should respond_to(:symbols)
|
223
|
+
@schema_writer.symbols.should == schema[:symbols].map(&:to_sym)
|
224
|
+
end
|
225
|
+
it 'has schema_writer' do
|
226
|
+
@schema_writer.type.should == :enum
|
227
|
+
# @schema_writer.should be_valid
|
228
|
+
@schema_writer.symbols = []
|
229
|
+
# @schema_writer.should_not be_valid
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
context '.receive' do
|
235
|
+
it 'applies the value_factory' do
|
236
|
+
Icss::Meta::EnumSchema.receive({:type => :enum, :name => 'games.coin_outcomes', :symbols => %w[heads tails sideways]})
|
237
|
+
inst = Icss::Games::CoinOutcomes.receive('heads')
|
238
|
+
inst.should == :heads ; inst.should be_a(Symbol)
|
239
|
+
inst = Icss::Games::CoinOutcomes.receive(:heads)
|
240
|
+
inst.should == :heads ; inst.should be_a(Symbol)
|
241
|
+
inst = Icss::Games::CoinOutcomes.receive('sideways')
|
242
|
+
inst.should == :sideways ; inst.should be_a(Symbol)
|
243
|
+
end
|
244
|
+
it 'raises an error on non-included value' do
|
245
|
+
Icss::Meta::EnumSchema.receive({:type => :enum, :name => 'games.coin_outcomes', :symbols => %w[heads tails sideways]})
|
246
|
+
lambda{ Icss::Games::CoinOutcomes.receive('ace_of_spades') }.should raise_error(ArgumentError, /Cannot receive ace_of_spades: must be one of heads,tails,sideways/)
|
247
|
+
Icss::Meta::EnumSchema.receive({:type => :enum, :name => 'herb.caen', :symbols => %w[parseley sage rosemary thyme]})
|
248
|
+
lambda{ Icss::Herb::Caen.receive('weed') }.should raise_error(ArgumentError, /Cannot receive weed: must be one of parseley,sage,rosemary,.../)
|
249
|
+
end
|
250
|
+
it 'raises an error on non-symbolizable value' do
|
251
|
+
Icss::Meta::EnumSchema.receive({:type => :enum, :name => 'games.coin_outcomes', :symbols => %w[heads tails sideways]})
|
252
|
+
lambda{ Icss::Games::CoinOutcomes.receive(77) }.should raise_error(NoMethodError, /undefined method .to_sym/)
|
253
|
+
end
|
254
|
+
it 'returns nil on nil/empty string value' do
|
255
|
+
Icss::Meta::EnumSchema.receive({:type => :enum, :name => 'games.coin_outcomes', :symbols => %w[heads tails sideways]})
|
256
|
+
Icss::Games::CoinOutcomes.receive(nil).should be_nil
|
257
|
+
Icss::Games::CoinOutcomes.receive('').should be_nil
|
258
|
+
Icss::Games::CoinOutcomes.receive(:"").should be_nil
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe Icss::Meta::FixedSchema do
|
264
|
+
[
|
265
|
+
{:type => :fixed, :name => 'geo_feature_category', :size => 1 },
|
266
|
+
{:type => :fixed, :name => 'sixteen_bytes_long', :size => 16 },
|
267
|
+
].each do |schema|
|
268
|
+
describe "With #{schema}" do
|
269
|
+
before do
|
270
|
+
@model_klass = Icss::Meta::FixedSchema.receive(schema)
|
271
|
+
@schema_writer = @model_klass._schema
|
272
|
+
end
|
273
|
+
it 'has schema_writer' do
|
274
|
+
@schema_writer.type.should == :fixed
|
275
|
+
# @schema_writer.should be_valid
|
276
|
+
@schema_writer.size = nil
|
277
|
+
# @schema_writer.should_not be_valid
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
context '.receive' do
|
283
|
+
it 'applies the value_factory' do
|
284
|
+
Icss::Meta::FixedSchema.receive({:type => :fixed, :name => 'sixteen_bytes_long', :size => 16})
|
285
|
+
Icss::SixteenBytesLong.receive('123456789_123456').should == '123456789_123456'
|
286
|
+
end
|
287
|
+
it 'raises an error on too-long value' do
|
288
|
+
Icss::Meta::FixedSchema.receive({:type => :fixed, :name => 'sixteen_bytes_long', :size => 16})
|
289
|
+
lambda{ Icss::SixteenBytesLong.receive('123456789_1234567') }.should raise_error(ArgumentError, /Wrong size for a fixed-length type sixteen_bytes_long: got 17, not 16/)
|
290
|
+
end
|
291
|
+
it 'returns nil on nil/empty string value' do
|
292
|
+
Icss::Meta::FixedSchema.receive({:type => :fixed, :name => 'sixteen_bytes_long', :size => 16})
|
293
|
+
Icss::SixteenBytesLong.receive(nil).should be_nil
|
294
|
+
Icss::SixteenBytesLong.receive('').should be_nil
|
295
|
+
Icss::SixteenBytesLong.receive(:"").should be_nil
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|