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,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default key xml parser" do
4
+ it "should convert into attributes hash" do
5
+ @xml = key_as_(:xml)
6
+ Xively::Key.new(@xml).should fully_represent_key(:xml, @xml)
7
+ end
8
+
9
+ Xively::Key::ALLOWED_KEYS.each do |key|
10
+ it "should handle blank '#{key}'" do
11
+ @xml = key_as_(:xml, :except_node => :referer)
12
+ Xively::Key.new(@xml).should fully_represent_key(:xml, @xml)
13
+ end
14
+ end
15
+
16
+ it "should raise known exception if passed garbage as xml" do
17
+ expect {
18
+ Xively::Key.new("This is not XML", :xml)
19
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
20
+ end
21
+ end
22
+
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default trigger xml parser" do
4
+ it "should convert into attributes hash" do
5
+ @xml = trigger_as_(:xml)
6
+ Xively::Trigger.new(@xml).should fully_represent_trigger(:xml, @xml)
7
+ end
8
+
9
+ Xively::Trigger::ALLOWED_KEYS.each do |key|
10
+ it "should handle blank '#{key}'" do
11
+ @xml = trigger_as_(:xml, :except_node => :at)
12
+ Xively::Trigger.new(@xml).should fully_represent_trigger(:xml, @xml)
13
+ end
14
+ end
15
+
16
+ it "should raise known exception if passed garbage as xml" do
17
+ expect {
18
+ Xively::Trigger.new("This is not XML", :xml)
19
+ }.to raise_error(Xively::Parsers::XML::InvalidXMLError)
20
+ end
21
+ end
22
+
@@ -0,0 +1,257 @@
1
+ require 'spec_helper'
2
+
3
+ class CustomPachubeFeed < Xively::Feed
4
+ end
5
+
6
+ describe Xively::SearchResult do
7
+
8
+ it "should have a constant that defines the allowed keys" do
9
+ Xively::SearchResult::ALLOWED_KEYS.should == %w(totalResults startIndex itemsPerPage results)
10
+ end
11
+
12
+
13
+ context "attr accessors" do
14
+ before(:each) do
15
+ @search_result = Xively::SearchResult.new(:results => [feed_as_(:json), feed_as_(:hash)])
16
+ end
17
+
18
+ describe "setting whitelisted fields" do
19
+ Xively::SearchResult::ALLOWED_KEYS.each do |key|
20
+ it "##{key}=" do
21
+ lambda {
22
+ @search_result.send("#{key}=", key)
23
+ }.should_not raise_error
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "getting whitelisted fields" do
29
+ Xively::SearchResult::ALLOWED_KEYS.each do |key|
30
+ it "##{key}" do
31
+ lambda {
32
+ @search_result.send(key)
33
+ }.should_not raise_error
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "setting non-whitelisted keys" do
39
+ it "should not be possible to set non-whitelisted fields" do
40
+ lambda {
41
+ @search_result.something_bogus = 'whatevs'
42
+ }.should raise_error
43
+ end
44
+
45
+ it "should not be possible to get non-whitelisted fields" do
46
+ lambda {
47
+ @search_result.something_bogus
48
+ }.should raise_error
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "#initialize" do
54
+ it "should create a blank slate when passed no arguments" do
55
+ search_result = Xively::SearchResult.new
56
+ Xively::SearchResult::ALLOWED_KEYS.each do |attr|
57
+ search_result.attributes[attr.to_sym].should be_nil
58
+ end
59
+ end
60
+
61
+ it "should accept a hash of attributes" do
62
+ search_result = Xively::SearchResult.new("totalResults" => 1000, "results" => [feed_as_(:hash)])
63
+ search_result.totalResults.should == 1000
64
+ search_result.results.length.should == 1
65
+ end
66
+
67
+ it "should accept json" do
68
+ search_result = Xively::SearchResult.new(search_result_as_(:json))
69
+ search_result.totalResults.should == "10000"
70
+ search_result.itemsPerPage.should == "100"
71
+ search_result.startIndex.should == "0"
72
+ search_result.results.length.should == 1
73
+ end
74
+
75
+ it "should accept json with no datastreams within the feeds" do
76
+ json = %Q(
77
+ {\"totalResults\":33,\"startIndex\":0,\"results\":[{\"status\":\"frozen\",\"version\":\"1.0.0\",\"updated\":\"2011-05-19T09:50:39.940513Z\",\"title\":\"No map\",\"private\":\"false\",\"feed\":\"http://api.appdev.loc/v2/feeds/79.json\",\"id\":79,\"creator\":\"http://appdev.loc/users/lebreeze\"},{\"status\":\"frozen\",\"location\":{\"lon\":18.28125,\"lat\":28.3043806829628,\"domain\":\"physical\"},\"version\":\"1.0.0\",\"description\":\"Description\",\"updated\":\"2011-05-18T13:25:02.112395Z\",\"title\":\"Title\",\"private\":\"false\",\"feed\":\"http://api.appdev.loc/v2/feeds/78.json\",\"id\":78,\"creator\":\"http://appdev.loc/users/lebreeze\"},{\"status\":\"frozen\",\"location\":{\"exposure\":\"outdoor\",\"domain\":\"physical\",\"disposition\":\"mobile\"},\"version\":\"1.0.0\",\"updated\":\"2011-05-04T12:12:07.352590Z\",\"title\":\"nope\",\"private\":\"false\",\"feed\":\"http://api.appdev.loc/v2/feeds/77.json\",\"id\":77,\"creator\":\"http://appdev.loc/users/lebreeze\"}],\"itemsPerPage\":3}
78
+ )
79
+ search_result = Xively::SearchResult.new(json)
80
+ search_result.results.length.should == 3
81
+ end
82
+ end
83
+
84
+ describe "#attributes" do
85
+ it "should return a hash of search result properties" do
86
+ attrs = {}
87
+ Xively::SearchResult::ALLOWED_KEYS.each do |key|
88
+ attrs[key] = "key #{rand(1000)}"
89
+ end
90
+ attrs["results"] = [Xively::Feed.new({"id" => "ein"})]
91
+ search_result = Xively::SearchResult.new(attrs)
92
+
93
+ search_result.attributes.should == attrs
94
+ end
95
+
96
+ it "should not return nil values" do
97
+ attrs = {}
98
+ Xively::SearchResult::ALLOWED_KEYS.each do |key|
99
+ attrs[key] = "key #{rand(1000)}"
100
+ end
101
+ attrs["totalResults"] = nil
102
+ search_result = Xively::Feed.new(attrs)
103
+
104
+ search_result.attributes.should_not include("totalResults")
105
+ end
106
+ end
107
+
108
+ describe "#attributes=" do
109
+ it "should accept and save a hash of feed properties" do
110
+ search_result = Xively::SearchResult.new({})
111
+
112
+ attrs = {}
113
+ Xively::SearchResult::ALLOWED_KEYS.each do |key|
114
+ value = "key #{rand(1000)}"
115
+ attrs[key] = value
116
+ search_result.should_receive("#{key}=").with(value)
117
+ end
118
+ search_result.attributes=(attrs)
119
+ end
120
+ end
121
+
122
+ context "associated feeds" do
123
+
124
+ describe "#results" do
125
+ it "should return an array of feeds" do
126
+ feeds = [Xively::Feed.new(feed_as_(:hash))]
127
+ attrs = {"results" => feeds}
128
+ search_result = Xively::SearchResult.new(attrs)
129
+ search_result.results.each do |env|
130
+ env.should be_kind_of(Xively::Feed)
131
+ end
132
+ end
133
+
134
+
135
+ it "should allow overriding the feed class to use" do
136
+ Xively::SearchResult.class_eval("@@feed_class = CustomPachubeFeed")
137
+ feeds = [feed_as_(:hash)]
138
+ attrs = {"results" => feeds}
139
+ search_result = Xively::SearchResult.new(attrs)
140
+ search_result.results.each do |env|
141
+ env.should be_kind_of(CustomPachubeFeed)
142
+ end
143
+ Xively::SearchResult.class_eval("@@feed_class = Xively::Feed")
144
+ end
145
+ end
146
+
147
+ describe "#results=" do
148
+ before(:each) do
149
+ @search_result = Xively::SearchResult.new({})
150
+ end
151
+
152
+ it "should return [] if not an array" do
153
+ @search_result.results = "kittens"
154
+ @search_result.results.should be_empty
155
+ end
156
+
157
+ it "should accept an array of feeds and hashes and store an array of datastreams" do
158
+ new_feed1 = Xively::Feed.new(feed_as_(:hash))
159
+ new_feed2 = Xively::Feed.new(feed_as_(:hash))
160
+ Xively::Feed.should_receive(:new).with(feed_as_(:hash)).and_return(new_feed2)
161
+
162
+ feeds = [new_feed1, feed_as_(:hash)]
163
+ @search_result.results = feeds
164
+ @search_result.results.length.should == 2
165
+ @search_result.results.should include(new_feed1)
166
+ @search_result.results.should include(new_feed2)
167
+ end
168
+
169
+ it "should accept an array of feeds and store an array of feeds" do
170
+ feeds = [Xively::Feed.new(feed_as_(:hash))]
171
+ @search_result.results = feeds
172
+ @search_result.results.should == feeds
173
+ end
174
+
175
+ it "should accept an array of hashes and store an array of feeds" do
176
+ new_feed = Xively::Feed.new(feed_as_(:hash))
177
+ Xively::Feed.should_receive(:new).with(feed_as_(:hash)).and_return(new_feed)
178
+
179
+ feeds_hash = [feed_as_(:hash)]
180
+ @search_result.results = feeds_hash
181
+ @search_result.results.should == [new_feed]
182
+ end
183
+ end
184
+
185
+ end
186
+
187
+ # Provided by Xively::Templates::SearchResultDefaults
188
+ describe "#generate_json" do
189
+ it "should take a version and generate the appropriate template" do
190
+ search_result = Xively::SearchResult.new({"totalResults" => 100, "itemsPerPage" => 12, :results => []})
191
+ search_result.generate_json("1.0.0").should == {:totalResults => 100, :itemsPerPage => 12}
192
+ end
193
+ end
194
+
195
+ describe "#to_xml" do
196
+ it "should call the xml generator with default version" do
197
+ search_result = Xively::SearchResult.new({})
198
+ search_result.should_receive(:generate_xml).with("0.5.1").and_return("<xml></xml>")
199
+ search_result.to_xml.should == "<xml></xml>"
200
+ end
201
+
202
+ it "should accept optional xml version" do
203
+ version = "5"
204
+ search_result = Xively::SearchResult.new({})
205
+ search_result.should_receive(:generate_xml).with(version).and_return("<xml></xml>")
206
+ search_result.to_xml(:version => version).should == "<xml></xml>"
207
+ end
208
+ end
209
+
210
+ describe "#as_json" do
211
+ it "should call the json generator with default version" do
212
+ search_result = Xively::SearchResult.new({})
213
+ search_result.should_receive(:generate_json).with("1.0.0").and_return({"title" => "Feed"})
214
+ search_result.as_json.should == {"title" => "Feed"}
215
+ end
216
+
217
+ it "should accept optional json version" do
218
+ version = "0.6-alpha"
219
+ search_result = Xively::SearchResult.new({})
220
+ search_result.should_receive(:generate_json).with(version).and_return({"title" => "Feed"})
221
+ search_result.as_json(:version => version).should == {"title" => "Feed"}
222
+ end
223
+ end
224
+
225
+ describe "#to_json" do
226
+ it "should call #as_json" do
227
+ search_result_hash = {"totalResults" => 100}
228
+ search_result = Xively::SearchResult.new(search_result_hash)
229
+ search_result.should_receive(:as_json).with({})
230
+ search_result.to_json
231
+ end
232
+
233
+ it "should pass options through to #as_json" do
234
+ search_result_hash = {"totalResults" => 100}
235
+ search_result = Xively::SearchResult.new(search_result_hash)
236
+ search_result.should_receive(:as_json).with({:crazy => "options"})
237
+ search_result.to_json({:crazy => "options"})
238
+ end
239
+
240
+ it "should generate feeds" do
241
+ search_result = Xively::SearchResult.new("results" => [feed_as_('hash')])
242
+ search_result.results = feed_as_(:hash)
243
+ MultiJson.load(search_result.to_json)["results"].should_not be_nil
244
+ end
245
+
246
+ it "should pass the output of #as_json to yajl" do
247
+ search_result_hash = {"totalResults" => 100}
248
+ search_result = Xively::SearchResult.new(search_result_hash)
249
+ search_result.should_receive(:as_json).and_return({:awesome => "hash"})
250
+ MultiJson.should_receive(:dump).with({:awesome => "hash"})
251
+ search_result.to_json
252
+ end
253
+ end
254
+
255
+
256
+ end
257
+
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe "String extensions" do
4
+
5
+ # HACK!!!!
6
+ it "should fail silently if iso8601 called on a non-time object" do
7
+ time_string = "2011-02-16T16:21:01.834174Z"
8
+ time_string.iso8601.should == time_string
9
+ time_string.iso8601(6).should == time_string
10
+ end
11
+ end
12
+
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default datapoint json templates" do
4
+ before(:each) do
5
+ @datapoint = Xively::Datapoint.new(datapoint_as_(:hash).merge("feed_id" => 6545, "datastream_id" => 0))
6
+ end
7
+
8
+ it "should represent Pachube datapoints (only used by API v2)" do
9
+ csv = @datapoint.generate_csv("2")
10
+ csv.should == @datapoint.value
11
+ end
12
+
13
+ it "should accept a depth option" do
14
+ csv = @datapoint.generate_csv("2", :depth => 1)
15
+ csv.should == @datapoint.value
16
+ csv = @datapoint.generate_csv("2", :depth => 2)
17
+ csv.should == [@datapoint.at.iso8601(6),@datapoint.value].join(',')
18
+ csv = @datapoint.generate_csv("2", :depth => 3)
19
+ csv.should == [@datapoint.datastream_id, @datapoint.at.iso8601(6),@datapoint.value].join(',')
20
+ csv = @datapoint.generate_csv("2", :depth => 4)
21
+ csv.should == [@datapoint.feed_id, @datapoint.datastream_id, @datapoint.at.iso8601(6), @datapoint.value].join(',')
22
+ end
23
+
24
+ it "should have an optional full representation" do
25
+ csv = @datapoint.generate_csv("2", :full => true)
26
+ csv.should == [@datapoint.feed_id, @datapoint.datastream_id, @datapoint.at.iso8601(6), @datapoint.value].join(',')
27
+ end
28
+
29
+ it "should escape stuff that could upset csv parsers" do
30
+ @datapoint.value = "I \n , am not a csv"
31
+ csv = @datapoint.generate_csv("2")
32
+ csv.should == Xively::CSV.generate_line([@datapoint.value]).strip
33
+ end
34
+
35
+ it "should escape characters that could upset csv parsers via full" do
36
+ @datapoint.value = "I \n , am not a csv"
37
+ csv = @datapoint.generate_csv("2", :full => true)
38
+ csv.should == Xively::CSV.generate_line([@datapoint.feed_id, @datapoint.datastream_id, @datapoint.at.iso8601(6), @datapoint.value]).strip
39
+ end
40
+ end
41
+
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default datastream json templates" do
4
+ before(:each) do
5
+ @datastream = Xively::Datastream.new(datastream_as_(:hash))
6
+ end
7
+
8
+ context "version 2 (used by API V2)" do
9
+
10
+ it "should default to 2" do
11
+ @datastream.generate_csv("2").should == @datastream.to_csv
12
+ end
13
+
14
+ it "should only show datapoints if there are any" do
15
+ csv = @datastream.generate_csv("2")
16
+ csv.should == @datastream.datapoints.collect {|dp| "#{dp.at.iso8601(6)},#{dp.value}"}.join("\n")
17
+ end
18
+
19
+ it "should represent datastream in Pachube CSV v2 if no datapoints" do
20
+ @datastream.datapoints = []
21
+ csv = @datastream.generate_csv("2")
22
+ csv.should == "#{@datastream.updated.iso8601(6)},#{@datastream.current_value}"
23
+ end
24
+
25
+ context "depth" do
26
+ it "should allow representation of datastream at depth 4" do
27
+ @datastream.datapoints = []
28
+ csv = @datastream.generate_csv("2", :depth => 4)
29
+ csv.should == "#{@datastream.feed_id},#{@datastream.id},#{@datastream.updated.iso8601(6)},#{@datastream.current_value}"
30
+ end
31
+
32
+ it "should allow representation of datapoints at depth 4" do
33
+ csv = @datastream.generate_csv("2", :depth => 4)
34
+ csv.should == @datastream.datapoints.collect {|dp| "#{@datastream.feed_id},#{@datastream.id},#{dp.at.iso8601(6)},#{dp.value}"}.join("\n")
35
+ end
36
+
37
+ it "should allow representation of datastream at depth 4" do
38
+ @datastream.datapoints = []
39
+ csv = @datastream.generate_csv("2", :depth => 3)
40
+ csv.should == "#{@datastream.id},#{@datastream.updated.iso8601(6)},#{@datastream.current_value}"
41
+ end
42
+
43
+ it "should allow representation of datapoints at depth 4" do
44
+ csv = @datastream.generate_csv("2", :depth => 3)
45
+ csv.should == @datastream.datapoints.collect {|dp| "#{@datastream.id},#{dp.at.iso8601(6)},#{dp.value}"}.join("\n")
46
+ end
47
+
48
+ it "should allow representation of datastream at depth 4" do
49
+ @datastream.datapoints = []
50
+ csv = @datastream.generate_csv("2", :depth => 2)
51
+ csv.should == "#{@datastream.updated.iso8601(6)},#{@datastream.current_value}"
52
+ end
53
+
54
+ it "should allow representation of datapoints at depth 4" do
55
+ csv = @datastream.generate_csv("2", :depth => 2)
56
+ csv.should == @datastream.datapoints.collect {|dp| "#{dp.at.iso8601(6)},#{dp.value}"}.join("\n")
57
+ end
58
+
59
+ it "should allow representation of datastream at depth 4" do
60
+ @datastream.datapoints = []
61
+ csv = @datastream.generate_csv("2", :depth => 1)
62
+ csv.should == "#{@datastream.current_value}"
63
+ end
64
+
65
+ it "should allow representation of datapoints at depth 4" do
66
+ csv = @datastream.generate_csv("2", :depth => 1)
67
+ csv.should == @datastream.datapoints.collect {|dp| "#{dp.value}"}.join("\n")
68
+ end
69
+
70
+ end
71
+
72
+
73
+ it "should allow a full representation of datastream" do
74
+ @datastream.datapoints = []
75
+ csv = @datastream.generate_csv("2", :full => true)
76
+ csv.should == "#{@datastream.feed_id},#{@datastream.id},#{@datastream.updated.iso8601(6)},#{@datastream.current_value}"
77
+ end
78
+
79
+ it "should allow a full representation of datapoints" do
80
+ csv = @datastream.generate_csv("2", :full => true)
81
+ csv.should == @datastream.datapoints.collect {|dp| "#{@datastream.feed_id},#{@datastream.id},#{dp.at.iso8601(6)},#{dp.value}"}.join("\n")
82
+ end
83
+
84
+ it "should escape characters that could upset csv parsers without datapoints" do
85
+ @datastream.current_value = "one,field"
86
+ @datastream.datapoints = []
87
+ csv = @datastream.generate_csv("2")
88
+ csv.should == Xively::CSV.generate_line([@datastream.updated.iso8601(6),@datastream.current_value]).strip
89
+ end
90
+
91
+ it "should escape characters that could upset csv parsers with datapoints" do
92
+ @datastream.current_value = "one,field"
93
+ @datastream.datapoints.each do |dp|
94
+ dp.value = "1,field"
95
+ end
96
+ csv = @datastream.generate_csv("2")
97
+ csv.should == @datastream.datapoints.collect {|dp| Xively::CSV.generate_line([dp.at.iso8601(6),dp.value]).strip }.join("\n")
98
+ end
99
+
100
+ it "should escape characters that could upset csv parsers without datapoints via full" do
101
+ @datastream.current_value = "one,field"
102
+ @datastream.datapoints = []
103
+ csv = @datastream.generate_csv("2", :full => true)
104
+ csv.should == Xively::CSV.generate_line([@datastream.feed_id,@datastream.id,@datastream.updated.iso8601(6),@datastream.current_value]).strip
105
+ end
106
+
107
+ it "should escape characters that could upset csv parsers with datapoints via full" do
108
+ @datastream.current_value = "one,field"
109
+ @datastream.datapoints.each do |dp|
110
+ dp.value = "1,field"
111
+ end
112
+ csv = @datastream.generate_csv("2", :full => true)
113
+ csv.should == @datastream.datapoints.collect {|dp| Xively::CSV.generate_line([@datastream.feed_id,@datastream.id,dp.at.iso8601(6),dp.value]).strip }.join("\n")
114
+ end
115
+ end
116
+
117
+ context "version 1 (used by API V1)" do
118
+
119
+ it "should represent Pachube CSV v1" do
120
+ csv = @datastream.generate_csv("1")
121
+ csv.should == @datastream.current_value
122
+ end
123
+
124
+ it "should escape characters that could upset csv parsers" do
125
+ @datastream.current_value = "I \n am full of c,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, evil"
126
+ csv = @datastream.generate_csv("1")
127
+ csv.should == Xively::CSV.generate_line([@datastream.current_value]).strip
128
+ end
129
+ end
130
+ end
131
+