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,110 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default datastream csv parser" do
4
+ describe "csv" do
5
+ it "should convert Pachube CSV into attributes hash" do
6
+ csv = datastream_as_(:csv)
7
+ datastream = Xively::Datastream.new(csv, :v2)
8
+ datastream.should fully_represent_datastream(:csv, csv)
9
+ end
10
+
11
+ it "should capture timestamp if present" do
12
+ csv = datastream_as_(:csv, :version => "timestamped")
13
+ datastream = Xively::Datastream.new(csv, :v2, :csv)
14
+ datastream.updated.should == "2011-02-16T16:21:01.834174Z"
15
+ datastream.current_value.should == "14"
16
+ end
17
+
18
+ it "should raise error if passed more than a single row" do
19
+ csv = "12\n13"
20
+ expect {
21
+ Xively::Datastream.new(csv)
22
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
23
+ end
24
+
25
+ it "should raise error passed more than three values in a row" do
26
+ csv = "#{Time.now.iso8601(6)},123,456"
27
+ expect {
28
+ Xively::Datastream.new(csv)
29
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
30
+ end
31
+
32
+ it "should raise error if passed more than a single value as v1" do
33
+ csv = "192,2"
34
+ expect {
35
+ Xively::Datastream.new(csv, :v1)
36
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
37
+ end
38
+
39
+ it "should raise exception if passed garbage csv" do
40
+ expect {
41
+ Xively::Datastream.new("badly, \"quoted", :csv)
42
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
43
+ end
44
+
45
+ it "should not raise exception if passed data with nil value" do
46
+ expect {
47
+ datastream = Xively::Datastream.new("2012-08-12T00:00:00Z,", :v2)
48
+ datastream.current_value.should be_empty
49
+ }.to_not raise_error
50
+ end
51
+
52
+ it "should parse multiline csv" do
53
+ csv = <<-CSV
54
+ 2012-02-08T00:00:00Z,123
55
+ 2012-02-08T00:00:10Z,124
56
+ 2012-02-08T00:00:20Z,125
57
+ 2012-02-08T00:00:30Z,126
58
+ CSV
59
+ datastream = Xively::Datastream.new(csv, :v2)
60
+ datastream.updated.should be_nil
61
+ datastream.current_value.should be_nil
62
+ datastream.datapoints.size.should == 4
63
+ datastream.datapoints.collect { |d| [d.at, d.value].join(",") }.join("\n").should == csv.strip
64
+ end
65
+
66
+ it "should not parse multiline csv passed to the v1 api" do
67
+ csv = <<-CSV
68
+ 2012-02-08T00:00:00Z,123
69
+ 2012-02-08T00:00:10Z,124
70
+ 2012-02-08T00:00:20Z,125
71
+ 2012-02-08T00:00:30Z,126
72
+ CSV
73
+ expect {
74
+ datastream = Xively::Datastream.new(csv, :v1)
75
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
76
+ end
77
+
78
+ it "should not accept multiline csv with just single values" do
79
+ csv = <<-CSV
80
+ 123
81
+ 124
82
+ 125
83
+ 126
84
+ CSV
85
+
86
+ expect {
87
+ datastream = Xively::Datastream.new(csv, :v2)
88
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
89
+ end
90
+
91
+ it "should strip whitespace from multiline values" do
92
+ csv = <<-CSV
93
+ 2012-02-08T00:00:00Z , 123
94
+ 2012-02-08T00:00:10Z , 124
95
+ 2012-02-08T00:00:20Z , 125
96
+ 2012-02-08T00:00:30Z , 126
97
+ CSV
98
+
99
+ datastream = Xively::Datastream.new(csv, :v2)
100
+ datastream.updated.should be_nil
101
+ datastream.current_value.should be_nil
102
+ datastream.datapoints.size.should == 4
103
+ datastream.datapoints.sort { |a, b| a.at <=> b.at }.collect { |d| [d.at, d.value] }.should == [["2012-02-08T00:00:00Z","123"],
104
+ ["2012-02-08T00:00:10Z","124"],
105
+ ["2012-02-08T00:00:20Z","125"],
106
+ ["2012-02-08T00:00:30Z","126"]]
107
+ end
108
+ end
109
+ end
110
+
@@ -0,0 +1,234 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default feed csv parser" do
4
+ describe "csv" do
5
+ it "should convert Pachube CSV v2 into attributes hash" do
6
+ csv = feed_as_(:csv, :version => 'v2')
7
+ feed = Xively::Feed.new(csv)
8
+ feed.should fully_represent_feed(:csv_v2, csv)
9
+ end
10
+
11
+ it "should convert no timestamp v2 CSV into attributes hash" do
12
+ csv = feed_as_(:csv, :version => 'v2_notimestamp')
13
+ feed = Xively::Feed.new(csv)
14
+ feed.should fully_represent_feed(:csv_v2, csv)
15
+ end
16
+
17
+ it "should convert Pachube CSV v1 into attributes hash" do
18
+ csv = feed_as_(:csv, :version => 'v1')
19
+ feed = Xively::Feed.new(csv)
20
+ feed.should fully_represent_feed(:csv_v1, csv)
21
+ end
22
+
23
+ it "should raise an exception if Pachube CSV cannot be detected" do
24
+ csv = feed_as_(:csv, :version => 'unknown')
25
+ lambda {Xively::Feed.new(csv)}.should raise_exception(Xively::Parsers::CSV::UnknownVersionError)
26
+ end
27
+
28
+ it "should accept manually determining csv version to be v2" do
29
+ csv = feed_as_(:csv, :version => 'unknown')
30
+ feed = Xively::Feed.new(csv, :v2)
31
+ feed.should fully_represent_feed(:csv_v2, csv)
32
+ end
33
+
34
+ it "should accept manually determining csv version to be v1" do
35
+ csv = feed_as_(:csv, :version => 'unknown')
36
+ feed = Xively::Feed.new(csv, :v1)
37
+ feed.should fully_represent_feed(:csv_v1, csv)
38
+ end
39
+
40
+ it "should accept explicit blank values for v2 csv" do
41
+ expect {
42
+ Xively::Feed.new("stream_id,''", :v2)
43
+ }.to_not raise_error(Xively::Parsers::CSV::InvalidCSVError)
44
+ end
45
+
46
+ it "should raise an error if passed some v2 csv that does not contain a value" do
47
+ expect {
48
+ Xively::Feed.new("stream_id", :v2)
49
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
50
+ end
51
+
52
+ it "should raise an error if passed empty content as v2" do
53
+ expect {
54
+ Xively::Feed.new("", :v2)
55
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
56
+ end
57
+
58
+ it "should raise an error if passed empty content as v1" do
59
+ expect {
60
+ Xively::Feed.new("", :v1)
61
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
62
+ end
63
+
64
+ it "should raise an error if passed some wild csv with more than max permitted three columns" do
65
+ csv =<<-CSV
66
+ Date-Time, System HOA,Jockey Pump HOA,VFD Pump HOA,Lag Pump HOA,Lag Pump 2 HOA,Power Monitor,Water Level Relay,High Discharge Pressure,Reset Function,Jockey Running,VFD Run,Lag Pump Run,VFD Fault,Filter In Auto,Filter In Hand,Differential Press 1,Filter 1 Running,High Limit Switch,Low Limit Switch,Lag Pump Running,VFD Run Output Auto,VFD Pump On,Lag Pump,Lag Pump 1 On,System Auto Mode,Fault,Lag Pump 2 Run,Jockey On,Jockey Pump Run,Lag Pump 2,Filter Forward,Filter Reverse,Filter Solenoid,Pressure,Flow,Unknown?,VFD Input,VFD Output,
67
+ 2009;Apr;19;12;44;15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
68
+ 2009;Apr;19;12;44;30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
69
+ 2009;Apr;19;12;48;52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
70
+ CSV
71
+ expect {
72
+ Xively::Feed.new(csv)
73
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
74
+ end
75
+
76
+ it "should raise an error if passed more than one row when we state it's v1" do
77
+ csv =<<-CSV
78
+ This,2
79
+ Wrong,3
80
+ Is,4
81
+ CSV
82
+
83
+ expect {
84
+ Xively::Feed.new(csv, :v1)
85
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError, /3 rows/)
86
+ end
87
+
88
+ context "nil attribute csv" do
89
+ before(:each) do
90
+ @csv = "0,,"
91
+ end
92
+
93
+ it "should not raise exception if csv has nil values as v1" do
94
+ expect {
95
+ feed = Xively::Feed.new(@csv, :v1)
96
+ feed.datastreams.size.should == 3
97
+ }.to_not raise_error
98
+ end
99
+
100
+ it "should not raise exception if csv has nil attributes as v2" do
101
+ expect {
102
+ feed = Xively::Feed.new(@csv, :v2)
103
+ feed.datastreams.size.should == 1
104
+ }.to_not raise_error
105
+ end
106
+ end
107
+
108
+ context "unwanted whitespace" do
109
+ it "should strip whitespace from v2" do
110
+ dodgy_csv = <<-CSV
111
+ 0, 00035
112
+ stream1, 0012
113
+ 2, 2012-08-02T14:11:14Z ," red car "
114
+ CSV
115
+ good_csv = <<-CSV
116
+ 0,00035
117
+ stream1,0012
118
+ 2,2012-08-02T14:11:14Z,red car
119
+ CSV
120
+ feed = Xively::Feed.new(dodgy_csv)
121
+ feed.should fully_represent_feed(:csv_v2, good_csv)
122
+ end
123
+
124
+ it "should strip whitespace from v1" do
125
+ dodgy_csv = %Q{ 00035 , 0012," red car"}
126
+ good_csv = "00035,0012,red car"
127
+ feed = Xively::Feed.new(dodgy_csv)
128
+ feed.should fully_represent_feed(:csv_v1, good_csv)
129
+ end
130
+ end
131
+
132
+ context "multivalue csv" do
133
+ def check_multiline_csv(csv)
134
+ feed = Xively::Feed.new(csv)
135
+
136
+ feed.datastreams.size.should == 2
137
+ feed.datastreams.each do |datastream|
138
+ datastream.updated.should be_nil
139
+ datastream.current_value.should be_nil
140
+ datastream.datapoints.size.should == 3
141
+ datastream.datapoints.sort { |a,b| a.at <=> b.at }.collect { |d| [d.at, d.value] }.should == [["2012-08-12T00:00:00Z", "1"],
142
+ ["2012-08-12T00:00:05Z", "2"],
143
+ ["2012-08-12T00:00:10Z", "3"]]
144
+ end
145
+ end
146
+
147
+ it "should capture multivalue csv with timestamps" do
148
+ csv = <<-CSV
149
+ stream0,2012-08-12T00:00:00Z,1
150
+ stream1,2012-08-12T00:00:00Z,1
151
+ stream0,2012-08-12T00:00:05Z,2
152
+ stream1,2012-08-12T00:00:05Z,2
153
+ stream0,2012-08-12T00:00:10Z,3
154
+ stream1,2012-08-12T00:00:10Z,3
155
+ CSV
156
+
157
+ check_multiline_csv(csv)
158
+ end
159
+
160
+ it "should capture multivalue csv with timestamps no matter the grouping" do
161
+ csv = <<-CSV
162
+ stream0,2012-08-12T00:00:00Z,1
163
+ stream0,2012-08-12T00:00:05Z,2
164
+ stream0,2012-08-12T00:00:10Z,3
165
+ stream1,2012-08-12T00:00:00Z,1
166
+ stream1,2012-08-12T00:00:05Z,2
167
+ stream1,2012-08-12T00:00:10Z,3
168
+ CSV
169
+
170
+ check_multiline_csv(csv)
171
+ end
172
+
173
+ it "should strip whitespace from multiline csv" do
174
+ csv = <<-CSV
175
+ stream0, 2012-08-12T00:00:00Z, 1
176
+ stream0, 2012-08-12T00:00:05Z, 2
177
+ stream0, 2012-08-12T00:00:10Z, 3
178
+ stream1, 2012-08-12T00:00:00Z, 1
179
+ stream1, 2012-08-12T00:00:05Z, 2
180
+ stream1, 2012-08-12T00:00:10Z, 3
181
+ CSV
182
+
183
+ check_multiline_csv(csv)
184
+ end
185
+
186
+ it "should reject multivalue csv without timestamps" do
187
+ csv = <<-CSV
188
+ stream0,1
189
+ stream1,1
190
+ stream0,2
191
+ stream1,2
192
+ stream0,3
193
+ stream1,3
194
+ CSV
195
+ expect {
196
+ Xively::Feed.new(csv)
197
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
198
+ end
199
+
200
+ it "should reject multivalue csv if we tell it its v1" do
201
+ csv = <<-CSV
202
+ stream0,2012-08-12T00:00:00Z,1
203
+ stream1,2012-08-12T00:00:00Z,1
204
+ CSV
205
+
206
+ expect {
207
+ Xively::Feed.new(csv, :v1)
208
+ }.to raise_error(Xively::Parsers::CSV::InvalidCSVError)
209
+ end
210
+
211
+ it "should permit an individual value within a larger update to not have a timestamp" do
212
+ csv = <<-CSV
213
+ stream0,2012-08-12T00:00:00Z,1
214
+ stream1,2012-08-12T00:00:00Z,1
215
+ stream0,2012-08-12T00:00:05Z,2
216
+ stream1,2012-08-12T00:00:05Z,2
217
+ stream0,2012-08-12T00:00:10Z,3
218
+ stream1,2012-08-12T00:00:10Z,3
219
+ stream2,4
220
+ CSV
221
+ feed = Xively::Feed.new(csv)
222
+ feed.datastreams.size.should == 3
223
+ sorted_datastreams = feed.datastreams.sort { |a, b| a.id <=> b.id }
224
+ [0,1].each do |i|
225
+ sorted_datastreams[i].current_value.should be_nil
226
+ sorted_datastreams[i].updated.should be_nil
227
+ sorted_datastreams[i].datapoints.size.should == 3
228
+ end
229
+ sorted_datastreams[2].current_value.should == "4"
230
+ end
231
+ end
232
+ end
233
+ end
234
+
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default datapoint json parser" do
4
+ before(:each) do
5
+ @datapoint = Xively::Datapoint.new(datapoint_as_(:json))
6
+ end
7
+
8
+ it "should convert into attributes hash" do
9
+ @json = datapoint_as_(:json)
10
+ attributes = @datapoint.from_json(@json)
11
+ json = MultiJson.load(@json)
12
+ attributes["at"].should == json["at"]
13
+ attributes["value"].should == json["value"]
14
+ end
15
+
16
+ it "should raise known exeception if passed garbage as json" do
17
+ expect {
18
+ Xively::Datapoint.new("This is not\nJSON", :json)
19
+ }.to raise_error(Xively::Parsers::JSON::InvalidJSONError)
20
+ end
21
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe "default datastream json parser" do
4
+ include Xively::Helpers
5
+
6
+ before(:each) do
7
+ @datastream = Xively::Datastream.new(datastream_as_(:json))
8
+ end
9
+
10
+ it "should default to v2 if no version is present" do
11
+ @json = datastream_as_(:json, :version => "1.0.0", :except => [:version])
12
+ attributes = @datastream.from_json(@json)
13
+ json = MultiJson.load(@json)
14
+ attributes["id"].should == json["id"]
15
+ attributes["updated"].should == json["at"]
16
+ attributes["current_value"].should == json["current_value"]
17
+ attributes["max_value"].should == json["max_value"]
18
+ attributes["min_value"].should == json["min_value"]
19
+ attributes["tags"].should == join_tags(json["tags"])
20
+ attributes["unit_type"].should == json["unit"]["type"]
21
+ attributes["unit_label"].should == json["unit"]["label"]
22
+ attributes["unit_symbol"].should == json["unit"]["symbol"]
23
+ at_least_one_datapoint = false
24
+ attributes["datapoints"].each do |point|
25
+ at_least_one_datapoint = true
26
+ dp = json["datapoints"].detect {|dp| dp["at"] == point["at"]}
27
+ point["value"].should == dp["value"]
28
+ point["at"].should == dp["at"]
29
+ end
30
+ at_least_one_datapoint.should be_true
31
+ end
32
+
33
+ it "should raise known exception if passed garbage as JSON" do
34
+ expect {
35
+ Xively::Datastream.new("This is not json", :v2, :json)
36
+ }.to raise_error(Xively::Parsers::JSON::InvalidJSONError)
37
+ end
38
+
39
+ context "1.0.0 (used by API v2)" do
40
+ it "should convert into attributes hash" do
41
+ @json = datastream_as_(:json)
42
+ attributes = @datastream.from_json(@json)
43
+ json = MultiJson.load(@json)
44
+ attributes["id"].should == json["id"]
45
+ attributes["updated"].should == json["at"]
46
+ attributes["current_value"].should == json["current_value"]
47
+ attributes["max_value"].should == json["max_value"]
48
+ attributes["min_value"].should == json["min_value"]
49
+ attributes["tags"].should == join_tags(json["tags"])
50
+ attributes["unit_type"].should == json["unit"]["type"]
51
+ attributes["unit_label"].should == json["unit"]["label"]
52
+ attributes["unit_symbol"].should == json["unit"]["symbol"]
53
+ at_least_one_datapoint = false
54
+ attributes["datapoints"].each do |point|
55
+ at_least_one_datapoint = true
56
+ dp = json["datapoints"].detect {|dp| dp["at"] == point["at"]}
57
+ point["value"].should == dp["value"]
58
+ point["at"].should == dp["at"]
59
+ end
60
+ at_least_one_datapoint.should be_true
61
+ end
62
+
63
+ it "should handle blank tags" do
64
+ @json = datastream_as_(:json, :except => [:tags])
65
+ lambda {@datastream.from_json(@json)}.should_not raise_error
66
+ end
67
+
68
+ it "should capture timestamp" do
69
+ @json = datastream_as_(:json, :version => "1.0.0-minimal_timestamp")
70
+ attributes = @datastream.from_json(@json)
71
+ json = MultiJson.load(@json)
72
+ attributes["updated"].should_not be_nil
73
+ attributes["updated"].should == json["at"]
74
+ end
75
+ end
76
+
77
+ context "0.6-alpha (used by API v1)" do
78
+
79
+ it "should convert into attributes hash" do
80
+ @json = datastream_as_(:json, :version => "0.6-alpha")
81
+ attributes = @datastream.from_json(@json)
82
+ json = MultiJson.load(@json)
83
+ attributes["id"].should == json["id"]
84
+ attributes["updated"].should == json["values"].first["recorded_at"]
85
+ attributes["current_value"].should == json["values"].first["value"]
86
+ attributes["max_value"].should == json["values"].first["max_value"]
87
+ attributes["min_value"].should == json["values"].first["min_value"]
88
+ attributes["tags"].should == json["tags"].join(',')
89
+ attributes["unit_type"].should == json["unit"]["type"]
90
+ attributes["unit_label"].should == json["unit"]["label"]
91
+ attributes["unit_symbol"].should == json["unit"]["symbol"]
92
+ end
93
+
94
+ it "should handle blank tags" do
95
+ @json = datastream_as_(:json, :version => "0.6-alpha", :except => [:tags])
96
+ lambda {@datastream.from_json(@json)}.should_not raise_error
97
+ end
98
+
99
+ it "should handle blank values" do
100
+ @json = datastream_as_(:json, :version => "0.6-alpha", :except => [:values])
101
+ lambda {@datastream.from_json(@json)}.should_not raise_error
102
+ end
103
+ end
104
+
105
+ end