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,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