rcap 0.1
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/CHANGELOG +2 -0
- data/README +151 -0
- data/lib/rcap.rb +21 -0
- data/lib/rcap/alert.rb +186 -0
- data/lib/rcap/area.rb +82 -0
- data/lib/rcap/circle.rb +62 -0
- data/lib/rcap/event_code.rb +20 -0
- data/lib/rcap/geocode.rb +20 -0
- data/lib/rcap/info.rb +239 -0
- data/lib/rcap/parameter.rb +54 -0
- data/lib/rcap/point.rb +39 -0
- data/lib/rcap/polygon.rb +50 -0
- data/lib/rcap/resource.rb +81 -0
- data/lib/rcap/utilities.rb +50 -0
- data/lib/rcap/validations.rb +116 -0
- data/spec/alert_spec.rb +132 -0
- data/spec/area_spec.rb +120 -0
- data/spec/circle_spec.rb +59 -0
- data/spec/geocode_spec.rb +26 -0
- data/spec/info_spec.rb +119 -0
- data/spec/point_spec.rb +34 -0
- data/spec/polygon_spec.rb +45 -0
- data/spec/resource_spec.rb +74 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/utilities_spec.rb +57 -0
- data/spec/validations_spec.rb +95 -0
- metadata +99 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
ALLOWED_CHARACTERS = /[^\s&<]+/ # :nodoc:
|
2
|
+
|
3
|
+
class Array # :nodoc:
|
4
|
+
def to_s_for_cap
|
5
|
+
self.map{ |element| element.to_s.for_cap_list }.join( ' ' )
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class String # :nodoc:
|
10
|
+
CAP_LIST_REGEX = /"([\w\s]+)"|(\S+)/
|
11
|
+
WHITESPACE_REGEX = /^\s+$/
|
12
|
+
|
13
|
+
def for_cap_list
|
14
|
+
if self =~ /\s/
|
15
|
+
'"'+self+'"'
|
16
|
+
else
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def unpack_cap_list
|
22
|
+
self.split( CAP_LIST_REGEX ).reject{ |match| match == "" || match =~ WHITESPACE_REGEX }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class DateTime # :nodoc:
|
27
|
+
alias inspect to_s
|
28
|
+
alias to_s_for_cap to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
class Time # :nodoc:
|
32
|
+
def to_s_for_cap
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module RCAP # :nodoc:
|
38
|
+
def self.xpath_text( xml_element, xpath )
|
39
|
+
element = self.xpath_first( xml_element, xpath )
|
40
|
+
element.text if element
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.xpath_first( xml_element, xpath )
|
44
|
+
REXML::XPath.first( xml_element, xpath, { 'cap' => RCAP::XMLNS })
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.xpath_match( xml_element, xpath )
|
48
|
+
REXML::XPath.match( xml_element, xpath, { 'cap' => RCAP::XMLNS })
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Validation # :nodoc:
|
2
|
+
module ClassMethods # :nodoc:
|
3
|
+
|
4
|
+
NUMBER_RE = /^-{0,1}\d*\.{0,1}\d+$/
|
5
|
+
INTEGER_RE = /\-{0,1}A[+-]?\d+\Z/
|
6
|
+
|
7
|
+
def validates_inclusion_of( *attributes )
|
8
|
+
options = {
|
9
|
+
:message => 'is not in the required range'
|
10
|
+
}.merge!( attributes.extract_options! )
|
11
|
+
|
12
|
+
validates_each( *attributes ) do |object, attribute, value|
|
13
|
+
next if ( value.nil? && options[ :allow_nil ]) || ( value.blank? && options[ :allow_blank ])
|
14
|
+
unless options[ :in ].include?( value )
|
15
|
+
object.errors[ attribute ] << options[ :message ]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def validates_inclusion_of_members_of( *attributes )
|
21
|
+
options = {
|
22
|
+
:message => 'contains members that are not valid'
|
23
|
+
}.merge!( attributes.extract_options! )
|
24
|
+
|
25
|
+
validates_each( *attributes ) do |object, attribute, collection|
|
26
|
+
next if ( collection.nil? && options[ :allow_nil ]) || (collection.blank? && options[ :allow_blank ])
|
27
|
+
unless collection.all?{ |member| options[ :in ].include?( member )}
|
28
|
+
object.errors[ attribute ] << options[ :message ]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def validates_length_of_members_of( *attributes )
|
34
|
+
options = {
|
35
|
+
:message => 'contains members with incorrect length'
|
36
|
+
}.merge!( attributes.extract_options! )
|
37
|
+
|
38
|
+
validates_each( *attributes ) do |object, attribute, collection|
|
39
|
+
next if ( collection.nil? && options[ :allow_nil ]) || (collection.blank? && options[ :allow_blank ])
|
40
|
+
unless options[ :minimum ] && collection.length >= options[ :minimum ]
|
41
|
+
object.errors[ attribute ] << options[ :message ]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def validates_validity_of( *attributes )
|
47
|
+
options = {
|
48
|
+
:message => 'is not valid'
|
49
|
+
}.merge!( attributes.extract_options! )
|
50
|
+
|
51
|
+
validates_each( *attributes ) do |object, attribute, value|
|
52
|
+
next if ( value.nil? && options[ :allow_nil ]) || ( value.blank? && options[ :allow_blank ])
|
53
|
+
unless value && value.valid?
|
54
|
+
object.errors[ attribute ] << options[ :message ]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def validates_collection_of( *attributes )
|
60
|
+
options = {
|
61
|
+
:message => 'contains an invalid element'
|
62
|
+
}.merge!( attributes.extract_options! )
|
63
|
+
|
64
|
+
validates_each( *attributes ) do |object, attribute, collection|
|
65
|
+
next if ( collection.nil? && options[ :allow_nil ]) || ( collection.blank? && options[ :allow_blank ])
|
66
|
+
unless collection.all?{ |element| element.valid? }
|
67
|
+
object.errors[ attribute ] << options[ :message ]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def validates_dependency_of( *attributes )
|
73
|
+
options = {
|
74
|
+
:message => 'is dependent on :attribute being defined'
|
75
|
+
}.merge!( attributes.extract_options! )
|
76
|
+
|
77
|
+
validates_each( *attributes ) do |object, attribute, value|
|
78
|
+
contingent_on_value = object.send( options[ :on ])
|
79
|
+
next if ( value.nil? && options[ :allow_nil ]) || ( value.blank? && options[ :allow_blank ])
|
80
|
+
unless value.blank? || !value.blank? && !contingent_on_value.blank? && ( options[ :with_value ].nil? || contingent_on_value == options[ :with_value ])
|
81
|
+
object.errors[ attribute ] << options[ :message ].gsub( /:attribute/, options[ :on ].to_s )
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def validates_numericality_of( *attributes )
|
87
|
+
options = {
|
88
|
+
:message => 'is not a number',
|
89
|
+
}.merge!(attributes.extract_options!)
|
90
|
+
|
91
|
+
re = options[:only_integer] ? INTEGER_RE : NUMBER_RE
|
92
|
+
|
93
|
+
validates_each( *attributes ) do |object, attribute, value|
|
94
|
+
next if (value.nil? && options[ :allow_nil ]) || (value.blank? && options[ :allow_blank ])
|
95
|
+
unless ( value.to_s =~ re ) &&
|
96
|
+
( options[ :greater_than ].nil? || value && value > options[ :greater_than ])
|
97
|
+
object.errors[ attribute ] << options[ :message ]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def validates_responsiveness_of( *attributes )
|
104
|
+
options = {
|
105
|
+
:message => 'does not respond to the given method'
|
106
|
+
}.merge!( attributes.extract_options! )
|
107
|
+
|
108
|
+
validates_each( *attributes ) do |object, attribute, value|
|
109
|
+
next if ( collection.nil? && options[ :allow_nil ]) || ( collection.blank? && options[ :allow_blank ])
|
110
|
+
unless options[ :to ].all?{ |method_name| object.respond_to?( method_name )}
|
111
|
+
object.errors[ attribute ] << options [ :message ]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/spec/alert_spec.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe( RCAP::Alert ) do
|
4
|
+
context( 'on initialisation' ) do
|
5
|
+
before( :each ) do
|
6
|
+
@alert = RCAP::Alert.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it( 'should have a default identifier' ){ @alert.identifier.should_not( be_nil )}
|
10
|
+
it( 'should not have a sender' ){ @alert.sender.should( be_nil )}
|
11
|
+
it( 'should have a default sent time' ){ @alert.sent.should_not( be_nil )}
|
12
|
+
it( 'should not have a status' ){ @alert.status.should( be_nil )}
|
13
|
+
it( 'should not have a scope' ){ @alert.scope.should( be_nil )}
|
14
|
+
it( 'should not have a source'){ @alert.source.should( be_nil )}
|
15
|
+
it( 'should not have a restriction'){ @alert.restriction.should( be_nil )}
|
16
|
+
it( 'should not have any addresses' ){ @alert.addresses.should( be_empty )}
|
17
|
+
it( 'should not have a code' ){ @alert.code.should( be_nil )}
|
18
|
+
it( 'should not have a note' ){ @alert.note.should( be_nil )}
|
19
|
+
it( 'should not have any references' ){ @alert.references.should( be_empty )}
|
20
|
+
it( 'should not have any incidents' ){ @alert.incidents.should( be_empty )}
|
21
|
+
it( 'should not have any infos' ){ @alert.infos.should( be_empty )}
|
22
|
+
|
23
|
+
context( 'from XML' ) do
|
24
|
+
before( :each ) do
|
25
|
+
@original_alert = RCAP::Alert.new( :sender => 'Sender',
|
26
|
+
:status => RCAP::Alert::STATUS_TEST,
|
27
|
+
:scope => RCAP::Alert::SCOPE_PUBLIC,
|
28
|
+
:source => 'Source',
|
29
|
+
:restriction => 'No Restriction',
|
30
|
+
:addresses => [ 'Address 1', 'Address 2'],
|
31
|
+
:code => 'Code',
|
32
|
+
:note => 'Note',
|
33
|
+
:references => [ RCAP::Alert.new( :sender => 'Sender1' ).to_reference, RCAP::Alert.new( :sender => 'Sender2' ).to_reference ],
|
34
|
+
:incidents => [ 'Incident1', 'Incident2' ],
|
35
|
+
:infos => [ RCAP::Info.new, RCAP::Info.new ])
|
36
|
+
@xml_string = @original_alert.to_xml
|
37
|
+
@xml_document = REXML::Document.new( @xml_string )
|
38
|
+
@alert_element = @xml_document.root
|
39
|
+
@alert = RCAP::Alert.from_xml_element( @alert_element )
|
40
|
+
end
|
41
|
+
|
42
|
+
it( 'should parse identifier correctly' ){ @alert.identifier.should == @original_alert.identifier }
|
43
|
+
it( 'should parse sender correctly' ){ @alert.sender.should == @original_alert.sender }
|
44
|
+
it( 'should parse sent correctly' ){ @alert.sent.should( be_close( @original_alert.sent, Rational( 1, 86400 )))}
|
45
|
+
it( 'should parse status correctly' ){ @alert.status.should == @original_alert.status }
|
46
|
+
it( 'should parse msg_type correctly' ){ @alert.msg_type.should == @original_alert.msg_type }
|
47
|
+
it( 'should parse source correctly' ){ @alert.source.should == @original_alert.source }
|
48
|
+
it( 'should parse scope correctly' ){ @alert.scope.should == @original_alert.scope }
|
49
|
+
it( 'should parse restriction correctly' ){ @alert.restriction.should == @original_alert.restriction }
|
50
|
+
it( 'should parse addresses correctly' ){ @alert.addresses.should == @original_alert.addresses }
|
51
|
+
it( 'should parse code correctly' ){ @alert.code.should == @original_alert.code }
|
52
|
+
it( 'should parse note correctly' ){ @alert.note.should == @original_alert.note }
|
53
|
+
it( 'should parse references correctly' ){ @alert.references.should == @original_alert.references }
|
54
|
+
it( 'should parse incidents correctly' ){ @alert.incidents.should == @original_alert.incidents }
|
55
|
+
it( 'should parse infos correctly' ) do
|
56
|
+
@alert.infos.size.should == @original_alert.infos.size
|
57
|
+
@alert.infos.each{ |info| info.class.should == RCAP::Info }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe( 'is not valid if it' ) do
|
63
|
+
before( :each ) do
|
64
|
+
@alert = RCAP::Alert.new( :sender => "cap@tempuri.org",
|
65
|
+
:status => RCAP::Alert::STATUS_TEST,
|
66
|
+
:msg_type => RCAP::Alert::MSG_TYPE_ALERT,
|
67
|
+
:scope => RCAP::Alert::SCOPE_PUBLIC )
|
68
|
+
@alert.should( be_valid )
|
69
|
+
end
|
70
|
+
|
71
|
+
it( 'does not have a identifier' ) do
|
72
|
+
@alert.identifier = nil
|
73
|
+
@alert.should_not( be_valid )
|
74
|
+
end
|
75
|
+
|
76
|
+
it( 'does not have a sender' ) do
|
77
|
+
@alert.sender = nil
|
78
|
+
@alert.should_not( be_valid )
|
79
|
+
end
|
80
|
+
|
81
|
+
it( 'does not have a sent time (sent)' ) do
|
82
|
+
@alert.sent = nil
|
83
|
+
@alert.should_not( be_valid )
|
84
|
+
end
|
85
|
+
|
86
|
+
it( 'does not have a status' ) do
|
87
|
+
@alert.status = nil
|
88
|
+
@alert.should_not( be_valid )
|
89
|
+
end
|
90
|
+
|
91
|
+
it( 'does not have a message type (msg_type)' ) do
|
92
|
+
@alert.msg_type = nil
|
93
|
+
@alert.should_not( be_valid )
|
94
|
+
end
|
95
|
+
|
96
|
+
it( 'does not have a scope' ) do
|
97
|
+
@alert.scope = nil
|
98
|
+
@alert.should_not( be_valid )
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
it( 'does not have a valid status' ) do
|
103
|
+
@alert.status = 'incorrect value'
|
104
|
+
@alert.should_not( be_valid )
|
105
|
+
end
|
106
|
+
|
107
|
+
it( 'does not have a valid message type msg_type' ) do
|
108
|
+
@alert.msg_type = 'incorrect value'
|
109
|
+
@alert.should_not( be_valid )
|
110
|
+
end
|
111
|
+
|
112
|
+
it( 'does not have a valid scope' ) do
|
113
|
+
@alert.scope = 'incorrect value'
|
114
|
+
@alert.should_not( be_valid )
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
context( 'has an info element and it' ) do
|
119
|
+
it( 'is not valid' ) do
|
120
|
+
@info = RCAP::Info.new( :event => 'Info Event',
|
121
|
+
:categories => RCAP::Info::CATEGORY_GEO,
|
122
|
+
:urgency => RCAP::Info::URGENCY_IMMEDIATE,
|
123
|
+
:severity => RCAP::Info::SEVERITY_EXTREME,
|
124
|
+
:certainty => RCAP::Info::CERTAINTY_OBSERVED )
|
125
|
+
@info.event = nil
|
126
|
+
@alert.infos << @info
|
127
|
+
@info.should_not( be_valid )
|
128
|
+
@alert.should_not( be_valid )
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
data/spec/area_spec.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe( RCAP::Area ) do
|
4
|
+
context( 'on initialisation' ) do
|
5
|
+
before( :each ) do
|
6
|
+
@area = RCAP::Area.new
|
7
|
+
end
|
8
|
+
|
9
|
+
# Atomic
|
10
|
+
it( 'should not have a area_desc' ){ @area.area_desc.should( be_nil )}
|
11
|
+
it( 'should not have a altitude' ){ @area.altitude.should( be_nil )}
|
12
|
+
it( 'should not have a ceiling' ){ @area.ceiling.should( be_nil )}
|
13
|
+
|
14
|
+
# Group
|
15
|
+
it( 'should have an empty polygons' ){ @area.polygons.should( be_empty )}
|
16
|
+
it( 'should have an empty circles' ){ @area.circles.should( be_empty )}
|
17
|
+
it( 'should have an empty geocodes' ){ @area.geocodes.should( be_empty )}
|
18
|
+
|
19
|
+
context( 'from XML' ) do
|
20
|
+
before( :each ) do
|
21
|
+
@original_area = RCAP::Area.new( :area_desc => 'Area Description',
|
22
|
+
:altitude => 100,
|
23
|
+
:ceiling => 200,
|
24
|
+
:circles => RCAP::Circle.new( :point => RCAP::Point.new( :lattitude => 0, :longitude => 0 ), :radius => 100 ),
|
25
|
+
:geocodes => RCAP::Geocode.new( :name => 'name', :value => 'value' ),
|
26
|
+
:polygons => RCAP::Polygon.new( :points => RCAP::Point.new( :lattitude =>1, :longitude => 1 )))
|
27
|
+
|
28
|
+
@alert = RCAP::Alert.new( :infos => RCAP::Info.new( :areas => @original_area ))
|
29
|
+
@xml_string = @alert.to_xml
|
30
|
+
@xml_document = REXML::Document.new( @xml_string )
|
31
|
+
@info_xml_element = RCAP.xpath_first( @xml_document.root, RCAP::Info::XPATH )
|
32
|
+
@area_xml_element = RCAP.xpath_first( @info_xml_element, RCAP::Area::XPATH )
|
33
|
+
@area = RCAP::Area.from_xml_element( @area_xml_element )
|
34
|
+
end
|
35
|
+
|
36
|
+
it( 'should parse the area_desc correctly' ) do
|
37
|
+
@area.area_desc.should == @original_area.area_desc
|
38
|
+
end
|
39
|
+
|
40
|
+
it( 'should parse the altitude correctly' ) do
|
41
|
+
@area.altitude.should == @original_area.altitude
|
42
|
+
end
|
43
|
+
|
44
|
+
it( 'should parse the ceiling correctly' ) do
|
45
|
+
@area.ceiling.should == @original_area.ceiling
|
46
|
+
end
|
47
|
+
|
48
|
+
it( 'should parse the circles correctly' ) do
|
49
|
+
@area.circles.should == @original_area.circles
|
50
|
+
end
|
51
|
+
|
52
|
+
it( 'should parse the geocodes correctly' ) do
|
53
|
+
@area.geocodes.should == @original_area.geocodes
|
54
|
+
end
|
55
|
+
|
56
|
+
it( 'should parse the polygons correctly' ) do
|
57
|
+
@area.polygons.should == @original_area.polygons
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context( 'is not valid if' ) do
|
63
|
+
before( :each ) do
|
64
|
+
@area = RCAP::Area.new( :area_desc => "Cape Town Metropole" )
|
65
|
+
@area.should( be_valid )
|
66
|
+
end
|
67
|
+
|
68
|
+
it( 'does not have an area descrtiption (area_desc)') do
|
69
|
+
@area.area_desc = nil
|
70
|
+
@area.should_not( be_valid )
|
71
|
+
end
|
72
|
+
|
73
|
+
it( 'has a ceiling defined but no altitude' ) do
|
74
|
+
@area.ceiling = 1
|
75
|
+
@area.altitude = nil
|
76
|
+
@area.should_not( be_valid )
|
77
|
+
end
|
78
|
+
|
79
|
+
context( 'it contains circles and it' ) do
|
80
|
+
before( :each ) do
|
81
|
+
@area.circles << RCAP::Circle.new( :point => RCAP::Point.new( :lattitude => 0, :longitude => 0 ), :radius => 1)
|
82
|
+
@area.should( be_valid )
|
83
|
+
end
|
84
|
+
|
85
|
+
it( 'has an invalid circle' ) do
|
86
|
+
@area.circles.first.point.lattitude = nil
|
87
|
+
@area.should_not( be_valid )
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context( 'it contains polygons and it' ) do
|
92
|
+
before( :each ) do
|
93
|
+
@polygon = RCAP::Polygon.new
|
94
|
+
@polygon.points.push( RCAP::Point.new( :lattitude => 0, :longitude => 0 ),
|
95
|
+
RCAP::Point.new( :lattitude => 0, :longitude => 1 ),
|
96
|
+
RCAP::Point.new( :lattitude => 1, :longitude => 0 ))
|
97
|
+
@area.polygons << @polygon
|
98
|
+
@area.should( be_valid )
|
99
|
+
end
|
100
|
+
|
101
|
+
it( 'has an invalid polygon' ) do
|
102
|
+
@polygon.points.first.lattitude = nil
|
103
|
+
@area.should_not( be_valid )
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context( 'it contains geocodes and it' ) do
|
108
|
+
before( :each ) do
|
109
|
+
@geocode = RCAP::Geocode.new( :name => 'foo', :value => 'bar' )
|
110
|
+
@area.geocodes << @geocode
|
111
|
+
@area.should( be_valid )
|
112
|
+
end
|
113
|
+
|
114
|
+
it( 'has an invalid geocode' ) do
|
115
|
+
@geocode.value = nil
|
116
|
+
@area.should_not( be_valid )
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/spec/circle_spec.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe( RCAP::Circle ) do
|
4
|
+
describe( 'should not be valid if' ) do
|
5
|
+
before( :each ) do
|
6
|
+
@circle = RCAP::Circle.new( :point => RCAP::Point.new( :lattitude => 0, :longitude => 0 ), :radius => 1 )
|
7
|
+
@circle.should( be_valid )
|
8
|
+
end
|
9
|
+
|
10
|
+
it( 'does not have a point defined' ) do
|
11
|
+
@circle.point = nil
|
12
|
+
@circle.should_not( be_valid )
|
13
|
+
end
|
14
|
+
|
15
|
+
it( 'does not have a valid point' ) do
|
16
|
+
@circle.point.longitude = nil
|
17
|
+
@circle.should_not( be_valid )
|
18
|
+
end
|
19
|
+
it( 'does not have a radius defined' ) do
|
20
|
+
@circle.radius = nil
|
21
|
+
@circle.should_not( be_valid )
|
22
|
+
end
|
23
|
+
|
24
|
+
it( 'does not have a numeric radius' ) do
|
25
|
+
@circle.radius = "not a number"
|
26
|
+
@circle.should_not( be_valid )
|
27
|
+
end
|
28
|
+
|
29
|
+
it( 'does not have a positive radius' ) do
|
30
|
+
@circle.radius = -1
|
31
|
+
@circle.should_not( be_valid )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context( 'on initialisation' ) do
|
36
|
+
context( 'from XML' ) do
|
37
|
+
before( :each ) do
|
38
|
+
@original_circle = RCAP::Circle.new( :radius => 10.5,
|
39
|
+
:point => RCAP::Point.new( :lattitude => 30, :longitude => 60 ))
|
40
|
+
@alert = RCAP::Alert.new( :infos => RCAP::Info.new( :areas => RCAP::Area.new( :circles => @original_circle )))
|
41
|
+
@xml_string = @alert.to_xml
|
42
|
+
@xml_document = REXML::Document.new( @xml_string )
|
43
|
+
@info_element = RCAP.xpath_first( @xml_document.root, RCAP::Info::XPATH )
|
44
|
+
@area_element = RCAP.xpath_first( @info_element, RCAP::Area::XPATH )
|
45
|
+
@circle_element = RCAP.xpath_first( @area_element, RCAP::Circle::XPATH )
|
46
|
+
@circle = RCAP::Circle.from_xml_element( @circle_element )
|
47
|
+
end
|
48
|
+
|
49
|
+
it( 'should parse the radius correctly' ) do
|
50
|
+
@circle.radius.should == @original_circle.radius
|
51
|
+
end
|
52
|
+
|
53
|
+
it( 'should parse the point correctly' ) do
|
54
|
+
@circle.point.lattitude.should == @original_circle.point.lattitude
|
55
|
+
@circle.point.longitude.should == @original_circle.point.longitude
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|