xively-rb 0.2.09

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.
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
+