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