xively-rb 0.2.09

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. data/.gitignore +13 -0
  2. data/.rbenv-version +1 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +7 -0
  6. data/CHANGELOG.md +91 -0
  7. data/CONTRIBUTING.md +95 -0
  8. data/Gemfile +15 -0
  9. data/LICENSE.md +13 -0
  10. data/README.md +10 -0
  11. data/Rakefile +25 -0
  12. data/ci/build_hudson.sh +24 -0
  13. data/init.rb +2 -0
  14. data/lib/xively-rb.rb +44 -0
  15. data/lib/xively-rb/array_extensions.rb +6 -0
  16. data/lib/xively-rb/base.rb +52 -0
  17. data/lib/xively-rb/base/instance_methods.rb +28 -0
  18. data/lib/xively-rb/client.rb +43 -0
  19. data/lib/xively-rb/datapoint.rb +72 -0
  20. data/lib/xively-rb/datastream.rb +127 -0
  21. data/lib/xively-rb/exceptions.rb +5 -0
  22. data/lib/xively-rb/feed.rb +109 -0
  23. data/lib/xively-rb/hash_extensions.rb +16 -0
  24. data/lib/xively-rb/helpers.rb +41 -0
  25. data/lib/xively-rb/key.rb +99 -0
  26. data/lib/xively-rb/nil_content.rb +15 -0
  27. data/lib/xively-rb/object_extensions.rb +6 -0
  28. data/lib/xively-rb/parsers/csv/datastream_defaults.rb +50 -0
  29. data/lib/xively-rb/parsers/csv/feed_defaults.rb +97 -0
  30. data/lib/xively-rb/parsers/defaults.rb +15 -0
  31. data/lib/xively-rb/parsers/json/datapoint_defaults.rb +16 -0
  32. data/lib/xively-rb/parsers/json/datastream_defaults.rb +58 -0
  33. data/lib/xively-rb/parsers/json/feed_defaults.rb +114 -0
  34. data/lib/xively-rb/parsers/json/key_defaults.rb +20 -0
  35. data/lib/xively-rb/parsers/json/search_result_defaults.rb +24 -0
  36. data/lib/xively-rb/parsers/json/trigger_defaults.rb +16 -0
  37. data/lib/xively-rb/parsers/xml/datapoint_defaults.rb +27 -0
  38. data/lib/xively-rb/parsers/xml/datastream_defaults.rb +53 -0
  39. data/lib/xively-rb/parsers/xml/errors.rb +7 -0
  40. data/lib/xively-rb/parsers/xml/feed_defaults.rb +83 -0
  41. data/lib/xively-rb/parsers/xml/helpers.rb +116 -0
  42. data/lib/xively-rb/parsers/xml/key_defaults.rb +46 -0
  43. data/lib/xively-rb/parsers/xml/trigger_defaults.rb +28 -0
  44. data/lib/xively-rb/permission.rb +67 -0
  45. data/lib/xively-rb/resource.rb +43 -0
  46. data/lib/xively-rb/search_result.rb +68 -0
  47. data/lib/xively-rb/string_extensions.rb +6 -0
  48. data/lib/xively-rb/templates/csv/datapoint_defaults.rb +22 -0
  49. data/lib/xively-rb/templates/csv/datastream_defaults.rb +43 -0
  50. data/lib/xively-rb/templates/csv/feed_defaults.rb +47 -0
  51. data/lib/xively-rb/templates/defaults.rb +14 -0
  52. data/lib/xively-rb/templates/json/datapoint_defaults.rb +15 -0
  53. data/lib/xively-rb/templates/json/datastream_defaults.rb +61 -0
  54. data/lib/xively-rb/templates/json/feed_defaults.rb +90 -0
  55. data/lib/xively-rb/templates/json/key_defaults.rb +39 -0
  56. data/lib/xively-rb/templates/json/search_result_defaults.rb +42 -0
  57. data/lib/xively-rb/templates/json/trigger_defaults.rb +21 -0
  58. data/lib/xively-rb/templates/xml/datapoint_defaults.rb +25 -0
  59. data/lib/xively-rb/templates/xml/datastream_defaults.rb +66 -0
  60. data/lib/xively-rb/templates/xml/feed_defaults.rb +112 -0
  61. data/lib/xively-rb/templates/xml/search_result_defaults.rb +118 -0
  62. data/lib/xively-rb/templates/xml_headers.rb +17 -0
  63. data/lib/xively-rb/trigger.rb +66 -0
  64. data/lib/xively-rb/validations.rb +9 -0
  65. data/lib/xively-rb/version.rb +3 -0
  66. data/spec/fixtures/models.rb +81 -0
  67. data/spec/spec_helper.rb +29 -0
  68. data/spec/support/contain_datapoint_eeml_matcher.rb +16 -0
  69. data/spec/support/contain_datastream_eeml_matcher.rb +60 -0
  70. data/spec/support/contain_feed_eeml_matcher.rb +98 -0
  71. data/spec/support/datapoint_helper.rb +53 -0
  72. data/spec/support/datastream_helper.rb +324 -0
  73. data/spec/support/describe_eeml_matcher.rb +23 -0
  74. data/spec/support/feed_helper.rb +783 -0
  75. data/spec/support/fully_represent_datapoint_matcher.rb +30 -0
  76. data/spec/support/fully_represent_datastream_matcher.rb +96 -0
  77. data/spec/support/fully_represent_feed_matcher.rb +234 -0
  78. data/spec/support/fully_represent_key_matcher.rb +74 -0
  79. data/spec/support/fully_represent_search_result_matcher.rb +67 -0
  80. data/spec/support/fully_represent_trigger_matcher.rb +29 -0
  81. data/spec/support/key_helper.rb +74 -0
  82. data/spec/support/search_result_helper.rb +252 -0
  83. data/spec/support/trigger_helper.rb +51 -0
  84. data/spec/xively-rb/array_extensions_spec.rb +9 -0
  85. data/spec/xively-rb/base/instance_methods_spec.rb +109 -0
  86. data/spec/xively-rb/base_spec.rb +56 -0
  87. data/spec/xively-rb/client_spec.rb +51 -0
  88. data/spec/xively-rb/datapoint_spec.rb +187 -0
  89. data/spec/xively-rb/datastream_spec.rb +344 -0
  90. data/spec/xively-rb/feed_spec.rb +341 -0
  91. data/spec/xively-rb/hash_extensions_spec.rb +20 -0
  92. data/spec/xively-rb/helpers_spec.rb +56 -0
  93. data/spec/xively-rb/key_spec.rb +198 -0
  94. data/spec/xively-rb/parsers/csv/datastream_defaults_spec.rb +110 -0
  95. data/spec/xively-rb/parsers/csv/feed_defaults_spec.rb +234 -0
  96. data/spec/xively-rb/parsers/json/datapoint_defaults_spec.rb +21 -0
  97. data/spec/xively-rb/parsers/json/datastream_defaults_spec.rb +105 -0
  98. data/spec/xively-rb/parsers/json/feed_defaults_spec.rb +45 -0
  99. data/spec/xively-rb/parsers/json/key_defaults_spec.rb +14 -0
  100. data/spec/xively-rb/parsers/json/search_result_defaults_spec.rb +18 -0
  101. data/spec/xively-rb/parsers/json/trigger_defaults_spec.rb +22 -0
  102. data/spec/xively-rb/parsers/xml/datapoint_defaults_spec.rb +19 -0
  103. data/spec/xively-rb/parsers/xml/datastream_defaults_spec.rb +148 -0
  104. data/spec/xively-rb/parsers/xml/feed_defaults_spec.rb +254 -0
  105. data/spec/xively-rb/parsers/xml/key_defaults_spec.rb +22 -0
  106. data/spec/xively-rb/parsers/xml/trigger_defaults_spec.rb +22 -0
  107. data/spec/xively-rb/search_result_spec.rb +257 -0
  108. data/spec/xively-rb/string_extensions_spec.rb +12 -0
  109. data/spec/xively-rb/templates/csv/datapoint_defaults_spec.rb +41 -0
  110. data/spec/xively-rb/templates/csv/datastream_defaults_spec.rb +131 -0
  111. data/spec/xively-rb/templates/csv/feed_defaults_spec.rb +78 -0
  112. data/spec/xively-rb/templates/json/datapoint_defaults_spec.rb +14 -0
  113. data/spec/xively-rb/templates/json/datastream_defaults_spec.rb +170 -0
  114. data/spec/xively-rb/templates/json/feed_defaults_spec.rb +399 -0
  115. data/spec/xively-rb/templates/json/key_defaults_spec.rb +29 -0
  116. data/spec/xively-rb/templates/json/search_result_defaults_spec.rb +37 -0
  117. data/spec/xively-rb/templates/json/trigger_defaults_spec.rb +19 -0
  118. data/spec/xively-rb/templates/xml/datapoint_defaults_spec.rb +14 -0
  119. data/spec/xively-rb/templates/xml/datastream_defaults_spec.rb +113 -0
  120. data/spec/xively-rb/templates/xml/feed_defaults_spec.rb +131 -0
  121. data/spec/xively-rb/templates/xml/search_result_defaults_spec.rb +44 -0
  122. data/spec/xively-rb/trigger_spec.rb +157 -0
  123. data/xively-rb.gemspec +41 -0
  124. metadata +333 -0
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default feed json parser" do
4
+ describe "json" do
5
+ it "should convert Pachube JSON 1.0.0 (used by API v2) into attributes hash" do
6
+ json = feed_as_(:json)
7
+ feed = Xively::Feed.new(json)
8
+ feed.should fully_represent_feed(:json, json)
9
+ end
10
+
11
+ it "should convert Pachube JSON 0.6-alpha (used by API v1) into attributes hash" do
12
+ json = feed_as_(:json, :version => "0.6-alpha")
13
+ feed = Xively::Feed.new(json)
14
+ feed.should fully_represent_feed(:json, json)
15
+ end
16
+
17
+ it "should convert Pachube JSON 0.6-alpha (used by API v1) into attributes hash" do
18
+ json = feed_as_(:json, :version => "0.6")
19
+ feed = Xively::Feed.new(json)
20
+ feed.should fully_represent_feed(:json, json)
21
+ end
22
+
23
+ it "should handle json if no value present" do
24
+ json = "{\"version\":\"0.6-alpha\",\"datastreams\":[{\"unit\":{\"label\":\"Tmax\",\"symbol\":\"C\"},\"values\":{},\"id\":\"1\"}]}"
25
+ expect {
26
+ feed = Xively::Feed.new(json)
27
+ feed.datastreams.size.should == 1
28
+ }.to_not raise_error
29
+ end
30
+
31
+ it "should capture empty fields if present" do
32
+ json = "{\"version\":\"1.0.0\",\"description\":\"\",\"feed\":\"\",\"location\":{\"name\":\"\"},\"tags\":[],\"datastreams\":[{\"unit\":{\"label\":\"\",\"symbol\":\"\"},\"tags\":[]}]}"
33
+ feed = Xively::Feed.new(json)
34
+ feed.description.should == ""
35
+ feed.feed.should == ""
36
+ feed.location_name.should == ""
37
+ feed.tags.should == ""
38
+ feed.datastreams.size.should == 1
39
+ feed.datastreams[0].unit_label.should == ""
40
+ feed.datastreams[0].unit_symbol.should == ""
41
+ feed.datastreams[0].tags.should == ""
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default key json parser" do
4
+ it "should convert into attributes hash" do
5
+ @json = key_as_(:json)
6
+ Xively::Key.new(@json).should fully_represent_key(:json, @json)
7
+ end
8
+
9
+ it "should raise known exception if passed garbage as json" do
10
+ expect {
11
+ Xively::Key.new("this ain't json", :json)
12
+ }.to raise_error(Xively::Parsers::JSON::InvalidJSONError)
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default search result json parser" do
4
+ describe "json" do
5
+ it "should convert Pachube JSON 1.0.0 (used by API v2) into attributes hash" do
6
+ json = search_result_as_(:json)
7
+ search_result = Xively::SearchResult.new(json)
8
+ search_result.should fully_represent_search_result(:json, json)
9
+ end
10
+
11
+ it "should raise known exception if passed garbage as json" do
12
+ expect {
13
+ Xively::SearchResult.new("Guess what, not JSON!")
14
+ }.to raise_error(Xively::Parsers::JSON::InvalidJSONError)
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default trigger json parser" do
4
+ before(:each) do
5
+ @trigger = Xively::Trigger.new(trigger_as_(:json))
6
+ end
7
+
8
+ it "should convert into attributes hash" do
9
+ @json = trigger_as_(:json)
10
+ attributes = @trigger.from_json(@json)
11
+ json = MultiJson.load(@json)
12
+ Xively::Trigger::ALLOWED_KEYS.each do |key|
13
+ attributes[key].should == json[key]
14
+ end
15
+ end
16
+
17
+ it "should raise known exception if passed garbage as json" do
18
+ expect {
19
+ Xively::Trigger.new("This is not JSON", :json)
20
+ }.to raise_error(Xively::Parsers::JSON::InvalidJSONError)
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default datapoint xml parser" do
4
+ it "should convert into attributes hash" do
5
+ @xml = datapoint_as_(:xml)
6
+ Xively::Datapoint.new(@xml).should fully_represent_datapoint(:xml, @xml)
7
+ end
8
+
9
+ it "should handle blank at" do
10
+ @xml = datapoint_as_(:xml, :except_node => :at)
11
+ Xively::Datapoint.new(@xml).should fully_represent_datapoint(:xml, @xml)
12
+ end
13
+
14
+ it "should handle blank value" do
15
+ @xml = datapoint_as_(:xml, :except_node => :value)
16
+ Xively::Datapoint.new(@xml).should fully_represent_datapoint(:xml, @xml)
17
+ end
18
+ end
19
+
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default datastream xml parser" do
4
+ context "0.5.1 (used by API v2)" do
5
+ it "should convert into attributes hash" do
6
+ xml = datastream_as_(:xml)
7
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
8
+ end
9
+
10
+ it "should convert into attributes hash when no version string but correct xmlns" do
11
+ xml = datastream_as_(:xml, :omit_version => true)
12
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, datastream_as_(:xml))
13
+ end
14
+
15
+ it "should handle blank tags" do
16
+ xml = datastream_as_(:xml, :except_node => :tag)
17
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
18
+ end
19
+
20
+ it "should handle blank units" do
21
+ xml = datastream_as_(:xml, :except_node => :unit)
22
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
23
+ end
24
+
25
+ it "should handle missing unit attributes" do
26
+ xml = datastream_as_(:xml, :except_node => :unit_attributes)
27
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
28
+ end
29
+
30
+ it "should handle missing timestamps" do
31
+ xml = datastream_as_(:xml, :except_node => :timestamps)
32
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
33
+ end
34
+
35
+ it "should capture all datapoints" do
36
+ xml = datastream_as_(:xml)
37
+ datastream = Xively::Datastream.new(xml)
38
+ datastream.datapoints.size.should == 3
39
+ end
40
+
41
+ it "should raise exception if passed xml containing more than one datastream" do
42
+ xml = feed_as_(:xml)
43
+ expect {
44
+ Xively::Datastream.new(xml)
45
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
46
+ end
47
+
48
+ it "should raise exception if passed xml without any datastreams" do
49
+ xml = <<-XML
50
+ <?xml version="1.0" encoding="UTF-8"?>
51
+ <eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/0.5.1 http://www.eeml.org/xsd/0.5.1/0.5.1.xsd">
52
+ <environment id="504" creator="http://appdev.loc:3000/users/occaecati">
53
+ </environment>
54
+ </eeml>
55
+ XML
56
+
57
+ expect {
58
+ Xively::Datastream.new(xml)
59
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
60
+ end
61
+ end
62
+
63
+ context "5 (used by API v1)" do
64
+ it "should convert into attributes hash" do
65
+ xml = datastream_as_(:xml, :version => "5")
66
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
67
+ end
68
+
69
+ it "should convert into attributes hash even when no version attribute if correct xmlns" do
70
+ xml = datastream_as_(:xml, :version => "5", :omit_version => true)
71
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, datastream_as_(:xml, :version => "5"))
72
+ end
73
+
74
+ it "should handle blank tags" do
75
+ xml = datastream_as_(:xml, :version => "5", :except_node => :tag)
76
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
77
+ end
78
+
79
+ it "should handle blank units" do
80
+ xml = datastream_as_(:xml, :version => "5", :except_node => :unit)
81
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
82
+ end
83
+
84
+ it "should handle missing unit attributes" do
85
+ xml = datastream_as_(:xml, :version => "5", :except_node => :unit_attributes)
86
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
87
+ end
88
+
89
+ it "should handle missing value attributes" do
90
+ xml = datastream_as_(:xml, :version => "5", :except_node => :value_attributes)
91
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
92
+ end
93
+
94
+ it "should handle missing timestamps" do
95
+ xml = datastream_as_(:xml, :version => "5", :except_node => :timestamps)
96
+ Xively::Datastream.new(xml).should fully_represent_datastream(:xml, xml)
97
+ end
98
+
99
+ it "should raise exception if passed xml containing more than one datastream" do
100
+ xml = feed_as_(:xml, :version => "5")
101
+ expect {
102
+ Xively::Datastream.new(xml)
103
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
104
+ end
105
+
106
+ it "should raise exception if passed xml without any datastreams" do
107
+ xml = <<-XML
108
+ <?xml version="1.0" encoding="UTF-8"?>
109
+ <eeml xmlns="http://www.eeml.org/xsd/005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
110
+ <environment updated="2011-02-16T16:21:01.834174Z" id="504" creator="http://appdev.loc:3000/users/occaecati">
111
+ </environment>
112
+ </eeml>
113
+ XML
114
+
115
+ expect {
116
+ Xively::Datastream.new(xml)
117
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
118
+ end
119
+ end
120
+
121
+ it "should raise exception if passed garbage as XML" do
122
+ expect {
123
+ Xively::Datastream.new("This is not xml", :v2, :xml)
124
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
125
+ end
126
+
127
+ it "should handle being passed xml containing datapoints with no timestamp" do
128
+ xml = <<-XML
129
+ <eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/0.5.1 http://www.eeml.org/xsd/0.5.1/0.5.1.xsd">
130
+ <environment>
131
+ <data>
132
+ <datapoints>
133
+ <value at="2010-05-20T11:01:43Z">294</value>
134
+ <value>295</value>
135
+ <value at="2010-05-20T11:01:45Z">296</value>
136
+ <value at="2010-05-20T11:01:46Z">297</value>
137
+ </datapoints>
138
+ </data>
139
+ </environment>
140
+ </eeml>
141
+ XML
142
+
143
+ expect {
144
+ Xively::Datastream.new(xml)
145
+ }.to_not raise_error
146
+ end
147
+ end
148
+
@@ -0,0 +1,254 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default feed xml parser" do
4
+ context "0.5.1 (used by API v2)" do
5
+ it "should convert into attributes hash" do
6
+ @xml = feed_as_(:xml)
7
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
8
+ end
9
+
10
+ it "should handle blank location" do
11
+ @xml = feed_as_(:xml, :except_node => :location)
12
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
13
+ end
14
+
15
+ it "should handle blank units" do
16
+ @xml = feed_as_(:xml, :except_node => :unit)
17
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
18
+ end
19
+
20
+ it "should handle missing unit attributes" do
21
+ @xml = feed_as_(:xml, :except_node => :unit_attributes)
22
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
23
+ end
24
+
25
+ it "should handle blank tags" do
26
+ @xml = feed_as_(:xml, :except_node => :tag)
27
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
28
+ end
29
+
30
+ it "should handle present but empty tags" do
31
+ xml = <<-EOXML
32
+ <?xml version="1.0" encoding="UTF-8"?>
33
+ <eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
34
+ <environment>
35
+ <title>ohai</title>
36
+ <tag></tag>
37
+ <data id="123">
38
+ <tag></tag>
39
+ </data>
40
+ </environment>
41
+ </eeml>
42
+ EOXML
43
+
44
+ feed = Xively::Feed.new(xml)
45
+ feed.tags.should == ""
46
+ feed.datastreams.first.tags.should == ""
47
+ end
48
+
49
+ it "should gracefully handle 0.5.1 xml missing the base environment node" do
50
+ xml = <<-EOXML
51
+ <?xml version="1.0" encoding="UTF-8"?>
52
+ <eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
53
+ <title>ohai</title>
54
+ </eeml>
55
+ EOXML
56
+ expect {
57
+ Xively::Feed.new(xml)
58
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
59
+ end
60
+
61
+ it "should handle datastream with no current_value" do
62
+ xml = <<-EOXML
63
+ <?xml version="1.0" encoding="UTF-8"?>
64
+ <eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/0.5.1 http://www.eeml.org/xsd/0.5.1/0.5.1.xsd">
65
+ <environment updated="2011-02-16T16:21:01.834174Z" id="504" creator="http://test.host/users/fred">
66
+ <title>Xively Office environment</title>
67
+ <data id="0">
68
+ <tag>freakin lasers</tag>
69
+ <tag>humidity</tag>
70
+ <tag>Temperature</tag>
71
+ </data>
72
+ </environment>
73
+ </eeml>
74
+ EOXML
75
+
76
+ feed = Xively::Feed.new(xml)
77
+ feed.datastreams.size.should == 1
78
+ feed.datastreams.first.tags.should == "freakin lasers,humidity,Temperature"
79
+ end
80
+
81
+ it "should parse xml missing the version attribute, but with the correct 0.5.1 xmlns" do
82
+ xml = feed_as_(:xml, :omit_version => true)
83
+ Xively::Feed.new(xml).should fully_represent_feed(:xml, feed_as_(:xml))
84
+ end
85
+ end
86
+
87
+ context "5 (used by API v1)" do
88
+ it "should convert into attributes hash" do
89
+ @xml = feed_as_(:xml, :version => "5")
90
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
91
+ end
92
+
93
+ it "should convert into attributes hash if missing version attribute, but with correct xmlns" do
94
+ xml = feed_as_(:xml, :version => "5", :omit_version => true)
95
+ Xively::Feed.new(xml).should fully_represent_feed(:xml, feed_as_(:xml, :version => "5"))
96
+ end
97
+
98
+ it "should handle blank tags" do
99
+ @xml = feed_as_(:xml, :version => "5", :except_node => :tag)
100
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
101
+ end
102
+
103
+ it "should handle blank location" do
104
+ @xml = feed_as_(:xml, :version => "5", :except_node => :location)
105
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
106
+ end
107
+
108
+ it "should handle blank units" do
109
+ @xml = feed_as_(:xml, :version => "5", :except_node => :unit)
110
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
111
+ end
112
+
113
+ it "should handle missing unit attributes" do
114
+ @xml = feed_as_(:xml, :version => "5", :except_node => :unit_attributes)
115
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
116
+ end
117
+
118
+ it "should handle missing value attributes" do
119
+ @xml = feed_as_(:xml, :version => "5", :except_node => :value_attributes)
120
+ feed = Xively::Feed.new(@xml)
121
+ Xively::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
122
+ end
123
+
124
+ it "should handle present but empty tags" do
125
+ xml = <<-EOXML
126
+ <?xml version="1.0" encoding="UTF-8"?>
127
+ <eeml xmlns="http://www.eeml.org/xsd/005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
128
+ <environment>
129
+ <title>ohai</title>
130
+ <data id="123">
131
+ <tag></tag>
132
+ </data>
133
+ </environment>
134
+ </eeml>
135
+ EOXML
136
+
137
+ feed = Xively::Feed.new(xml)
138
+ feed.datastreams.first.tags.should == ""
139
+ end
140
+
141
+ it "should gracefully handle 5 xml missing the base environment node" do
142
+ xml = <<-EOXML
143
+ <?xml version="1.0" encoding="UTF-8"?>
144
+ <eeml xmlns="http://www.eeml.org/xsd/005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
145
+ <title>ohai</title>
146
+ </eeml>
147
+ EOXML
148
+ expect {
149
+ Xively::Feed.new(xml)
150
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
151
+ end
152
+
153
+ it "should gracefully handle our oddly whitespaced real example" do
154
+ xml = <<-EOXML
155
+ <?xml version="1.0" encoding="UTF-8"?>
156
+ <eeml version="5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.eeml.org/xsd/005" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
157
+ <environment>
158
+ <data id="4773635294300160">
159
+ <tag>
160
+ 10.F59894010800</tag>
161
+ <tag>
162
+ Living Room, S wall</tag>
163
+ <value>
164
+ 24.1875</value>
165
+ <unit type="derivedSI">
166
+ celsius</unit>
167
+ </data>
168
+ </environment>
169
+ </eeml>
170
+ EOXML
171
+ feed = Xively::Feed.new(xml)
172
+
173
+ datastream = feed.datastreams.first
174
+ datastream.tags.should == "10.F59894010800,\"Living Room, S wall\""
175
+ datastream.current_value.should == "24.1875"
176
+ datastream.unit_label.should == "celsius"
177
+ end
178
+ end
179
+
180
+ context "garbage input" do
181
+ it "should not propogate nokogiri error for invalid xml" do
182
+ xml = <<-EOXML
183
+ <?xml version="1.0" encoding="UTF-8"?>
184
+ <rss version="2.0">
185
+ <channel>
186
+ <title>Skype Statistics</title>
187
+ <description>Statistics From Skype</description>
188
+ <link>http://www.skype.com/</link>
189
+ <lastBuildDate>Thu, 02 Aug 2012 13:50:01 +0000</lastBuildDate>
190
+ <image>
191
+ <url>http://www.skype.com/i/logos/skype.png</url>
192
+ <title>Skype</title>
193
+ <link>http://www.skype.com/</link>
194
+ <description>Statistics From Skype</description>
195
+ </image>
196
+ <ttl>60</ttl>
197
+ <item>
198
+ <title>Total Skype Downloads</title>
199
+ <link>http://www.skype.com/</link>
200
+ <description>2992280145</description>
201
+ <pubDate>Thu, 02 Aug 2012 13:50:01 +0000</pubDate>
202
+ <guid>Total Skype Downloads Thu, 02 Aug 2012 13:50:01 +0000</guid>
203
+ </item>
204
+ <item>
205
+ <title>Users Online Now</title>
206
+ <link>http://www.skype.com/</link>
207
+ <description>39393244</description>
208
+ <pubDate>Thu, 02 Aug 2012 13:50:01 +0000</pubDate>
209
+ <guid>Users Online Now Thu, 02 Aug 2012 13:50:01 +0000</guid>
210
+ </item>
211
+ </channel>
212
+ </rss>
213
+ EOXML
214
+ expect {
215
+ Xively::Feed.new(xml)
216
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
217
+ end
218
+ end
219
+
220
+ context "feeds with datapoints" do
221
+ it "should grab all datapoints present in valid xml" do
222
+ xml = <<-XML
223
+ <eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/0.5.1 http://www.eeml.org/xsd/0.5.1/0.5.1.xsd">
224
+ <environment>
225
+ <data id="0">
226
+ <datapoints>
227
+ <value at="2010-05-20T11:01:43Z">294</value>
228
+ <value at="2010-05-20T11:01:44Z">295</value>
229
+ <value at="2010-05-20T11:01:45Z">296</value>
230
+ <value at="2010-05-20T11:01:46Z">297</value>
231
+ </datapoints>
232
+ </data>
233
+ <data id="1">
234
+ <current_value at="2010-05-20T11:01:47Z">23</current_value>
235
+ <datapoints>
236
+ <value at="2010-05-20T11:01:43Z">24</value>
237
+ <value at="2010-05-20T11:01:44Z">25</value>
238
+ </datapoints>
239
+ </data>
240
+ </environment>
241
+ </eeml>
242
+ XML
243
+ feed = Xively::Feed.new(xml)
244
+ feed.datastreams.size.should == 2
245
+ feed.datastreams[0].current_value.should == nil
246
+ feed.datastreams[0].datapoints.size.should == 4
247
+ feed.datastreams[0].datapoints.collect { |d| d.value }.should == ["294", "295", "296", "297"]
248
+ feed.datastreams[1].current_value.should == "23"
249
+ feed.datastreams[1].datapoints.size.should == 2
250
+ feed.datastreams[1].datapoints.collect { |d| d.value }.should == ["24", "25"]
251
+ end
252
+ end
253
+ end
254
+