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,30 @@
1
+ RSpec::Matchers.define :fully_represent_datapoint do |format, formatted_datapoint|
2
+ match do |datapoint|
3
+ if format.to_sym == :xml
4
+ match_xml_datapoint(datapoint, formatted_datapoint)
5
+ end
6
+ end
7
+
8
+ failure_message_for_should do |datapoint|
9
+ "expected #{datapoint} to fully represent #{formatted_datapoint}"
10
+ end
11
+
12
+ description do
13
+ "expected #{formatted_datapoint.class} to be fully represented"
14
+ end
15
+
16
+ def match_xml_datapoint(datapoint, formatted_datapoint)
17
+ xml = Nokogiri.parse(formatted_datapoint)
18
+ case xml.root.attributes["version"].value
19
+ when "0.5.1"
20
+ environment = xml.at_xpath("//xmlns:environment")
21
+ data = environment.at_xpath("xmlns:data")
22
+ datapoint.value.should == data.at_xpath("xmlns:datapoints").at_xpath("xmlns:value").content
23
+ datapoint.at.should == data.at_xpath("xmlns:datapoints").at_xpath("xmlns:value").attributes["at"].value
24
+ else
25
+ false
26
+ end
27
+ end
28
+ end
29
+
30
+
@@ -0,0 +1,96 @@
1
+ RSpec::Matchers.define :fully_represent_datastream do |format, formatted_datastream|
2
+ match do |datastream|
3
+ case format.to_sym
4
+ when :xml
5
+ match_xml_datastream(datastream, formatted_datastream)
6
+ when :json
7
+ match_json_datastream(datastream, formatted_datastream)
8
+ when :csv
9
+ match_csv_datastream(datastream, formatted_datastream)
10
+ else
11
+ raise "Unknown Datastream format: '#{format}'"
12
+ end
13
+ end
14
+
15
+ failure_message_for_should do |datastream|
16
+ "expected #{datastream} to fully represent #{formatted_datastream}"
17
+ end
18
+
19
+ description do
20
+ "expected #{formatted_datastream.class} to be fully represented"
21
+ end
22
+
23
+ def match_xml_datastream(datastream, formatted_datastream)
24
+ xml = Nokogiri.parse(formatted_datastream)
25
+ case xml.root.attributes["version"].value
26
+ when "0.5.1"
27
+ environment = xml.at_xpath("//xmlns:environment")
28
+ data = environment.at_xpath("xmlns:data")
29
+ datastream.feed_id.should == environment.attributes["id"].value
30
+ datastream.feed_creator.should == environment.attributes["creator"].value
31
+ datastream.id.should == data.attributes["id"].value
32
+ if (tags = data.xpath("xmlns:tag")).any?
33
+ datastream.tags.should == tags.map(&:content).sort{|a,b| a.downcase<=>b.downcase}.join(',')
34
+ end
35
+ current_value = data.at_xpath("xmlns:current_value")
36
+ datastream.current_value.should == current_value.content
37
+ datastream.updated.should == current_value.attributes["at"].value if current_value.attributes["at"]
38
+ datastream.min_value.should == data.at_xpath("xmlns:min_value").content
39
+ datastream.max_value.should == data.at_xpath("xmlns:max_value").content
40
+ unit = data.at_xpath("xmlns:unit")
41
+ if unit
42
+ datastream.unit_label.should == unit.content
43
+ datastream.unit_type.should == unit.attributes["type"].value if unit.attributes["type"]
44
+ datastream.unit_symbol.should == unit.attributes["symbol"].value if unit.attributes["symbol"]
45
+ end
46
+ datastream.datapoints.each do |point|
47
+ dp = data.at_xpath("xmlns:datapoints").at_xpath("xmlns:value[@at=\"#{point.at}\"]")
48
+ point.value.should == dp.content
49
+ end
50
+ true
51
+ when "5"
52
+ environment = xml.at_xpath("//xmlns:environment")
53
+ data = environment.at_xpath("xmlns:data")
54
+ datastream.feed_id.should == environment.attributes["id"].value
55
+ datastream.feed_creator.should == "http://www.haque.co.uk"
56
+ datastream.id.should == data.attributes["id"].value
57
+ if (tags = data.xpath("xmlns:tag")).any?
58
+ datastream.tags.should == tags.map(&:content).sort{|a,b| a.downcase<=>b.downcase}.join(',')
59
+ end
60
+ current_value = data.at_xpath("xmlns:value")
61
+ datastream.current_value.should == current_value.content
62
+ datastream.updated.should == xml.at_xpath("//xmlns:environment").attributes["updated"].value if xml.at_xpath("//xmlns:environment").attributes["updated"]
63
+ datastream.min_value.should == current_value.attributes["minValue"].value if current_value.attributes["minValue"]
64
+ datastream.max_value.should == current_value.attributes["maxValue"].value if current_value.attributes["maxValue"]
65
+ unit = data.at_xpath("xmlns:unit")
66
+ if unit
67
+ datastream.unit_label.should == unit.content
68
+ datastream.unit_type.should == unit.attributes["type"].value if unit.attributes["type"]
69
+ datastream.unit_symbol.should == unit.attributes["symbol"].value if unit.attributes["symbol"]
70
+ end
71
+ true
72
+ else
73
+ false
74
+ end
75
+ end
76
+
77
+ def match_json_datastream(datastream, formatted_datastream)
78
+ json = MultiJson.load(formatted_datastream)
79
+ case json['version']
80
+ when '0.6-alpha'
81
+ raise "Not implemented"
82
+ else
83
+ datastream.current_value.should == json["current_value"]
84
+ datastream.id.should == json["id"]
85
+ datastream.updated.should == json["at"]
86
+ datastream.min_value.should == json["min_value"]
87
+ datastream.max_value.should == json["max_value"]
88
+ end
89
+ end
90
+
91
+ def match_csv_datastream(datastream, formatted_datastream)
92
+ datastream.current_value.to_s.should == formatted_datastream.strip
93
+ end
94
+ end
95
+
96
+
@@ -0,0 +1,234 @@
1
+ RSpec::Matchers.define :fully_represent_feed do |format, formatted_feed|
2
+ match do |feed|
3
+ if format.to_sym == :xml
4
+ match_xml_feed(feed, formatted_feed)
5
+ elsif format.to_sym == :json
6
+ match_json_feed(feed, formatted_feed)
7
+ elsif format.to_sym == :csv_v2
8
+ match_csv_v2_feed(feed, formatted_feed)
9
+ elsif format.to_sym == :csv_v1
10
+ match_csv_v1_feed(feed, formatted_feed)
11
+ else
12
+ raise "No matcher for #{format}"
13
+ end
14
+ end
15
+
16
+ failure_message_for_should do |feed|
17
+ "expected #{feed.attributes.inspect} to fully represent #{formatted_feed}"
18
+ end
19
+
20
+ description do
21
+ "expected #{formatted_feed.class} to be fully represented"
22
+ end
23
+
24
+ def match_csv_v1_feed(feed, formatted_feed)
25
+ csv = Xively::CSV.parse(formatted_feed.strip)
26
+ csv.length.should == 1
27
+ csv = csv.first
28
+ feed.datastreams.length.should == csv.length
29
+ feed.datastreams.each_with_index do |datastream, stream_id|
30
+ csv.detect {|d| d == datastream.current_value}.should_not be_nil
31
+ datastream.id.should == stream_id.to_s
32
+ end
33
+ end
34
+
35
+ def match_csv_v2_feed(feed, formatted_feed)
36
+ csv = Xively::CSV.parse(formatted_feed.strip)
37
+ feed.datastreams.length.should == csv.length
38
+ feed.datastreams.each do |datastream|
39
+ row = csv.detect {|d| d.first == datastream.id}
40
+ datastream.current_value.should == row.last
41
+ if row.size == 3
42
+ datastream.updated.iso8601.should == row[1]
43
+ end
44
+ end
45
+ end
46
+
47
+ def match_xml_feed(feed, formatted_feed)
48
+ xml = Nokogiri.parse(formatted_feed)
49
+ case xml.root.attributes["version"].value
50
+ when "0.5.1"
51
+ environment = xml.at_xpath("//xmlns:environment")
52
+ feed.title.should == environment.at_xpath("xmlns:title").content
53
+ feed.updated.should == environment.attributes["updated"].value
54
+ feed.created.should == environment.attributes["created"].value
55
+ feed.creator.should == environment.attributes["creator"].value
56
+ feed.feed.should == environment.at_xpath("xmlns:feed").content
57
+ if auto_feed_url = environment.at_xpath("xmlns:auto_feed_url")
58
+ feed.auto_feed_url.should == auto_feed_url.content
59
+ end
60
+ feed.status.should == environment.at_xpath("xmlns:status").content
61
+ feed.description.should == environment.at_xpath("xmlns:description").content
62
+ feed.icon.should == environment.at_xpath("xmlns:icon").content
63
+ feed.website.should == environment.at_xpath("xmlns:website").content
64
+ feed.email.should == environment.at_xpath("xmlns:email").content
65
+ feed.private.should == environment.at_xpath("xmlns:private").content
66
+ if feed.tags
67
+ feed.tags.should == environment.xpath("xmlns:tag").map(&:content).sort{|a,b| a.downcase<=>b.downcase}.join(',')
68
+ end
69
+ owner = environment.at_xpath("xmlns:user")
70
+ if owner
71
+ feed.owner_login.should == owner.at_xpath("xmlns:login").content
72
+ end
73
+ location = environment.at_xpath("xmlns:location")
74
+ if location
75
+ feed.location_name.should == location.at_xpath("xmlns:name").content
76
+ feed.location_lat.should == location.at_xpath("xmlns:lat").content
77
+ feed.location_lon.should == location.at_xpath("xmlns:lon").content
78
+ feed.location_ele.should == location.at_xpath("xmlns:ele").content
79
+ feed.location_domain.should == location.attributes["domain"].value
80
+ feed.location_exposure.should == location.attributes["exposure"].value
81
+ feed.location_disposition.should == location.attributes["disposition"].value
82
+ end
83
+ feed.datastreams.each do |ds|
84
+ data = environment.at_xpath("xmlns:data[@id=\"#{ds.id}\"]")
85
+ ds.id.should == data.attributes["id"].value
86
+ if (tags = data.xpath("xmlns:tag").collect { |t| t.content.strip }).any?
87
+ ds.tags.should == tags.sort{|a,b| a.downcase<=>b.downcase}.join(',')
88
+ end
89
+ current_value = data.at_xpath("xmlns:current_value")
90
+ ds.current_value.should == current_value.content
91
+ ds.updated.should == current_value.attributes["at"].value
92
+ ds.min_value.should == data.at_xpath("xmlns:min_value").content
93
+ ds.max_value.should == data.at_xpath("xmlns:max_value").content
94
+ unit = data.at_xpath("xmlns:unit")
95
+ if unit
96
+ ds.unit_label.should == unit.content
97
+ ds.unit_type.should == unit.attributes["type"].value if unit.attributes["type"]
98
+ ds.unit_symbol.should == unit.attributes["symbol"].value if unit.attributes["symbol"]
99
+ end
100
+ ds.datapoints.each do |point|
101
+ dp = data.at_xpath("xmlns:datapoints").at_xpath("xmlns:value[@at=\"#{point.at}\"]")
102
+ point.value.should == dp.content
103
+ end
104
+ end
105
+ true
106
+ when "5"
107
+ environment = xml.at_xpath("//xmlns:environment")
108
+ feed.title.should == environment.at_xpath("xmlns:title").content
109
+ feed.updated.should == environment.attributes["updated"].value
110
+ feed.creator.should == "http://www.haque.co.uk"
111
+ feed.feed.should == environment.at_xpath("xmlns:feed").content
112
+ feed.status.should == environment.at_xpath("xmlns:status").content
113
+ feed.description.should == environment.at_xpath("xmlns:description").content
114
+ feed.icon.should == environment.at_xpath("xmlns:icon").content
115
+ feed.website.should == environment.at_xpath("xmlns:website").content
116
+ feed.email.should == environment.at_xpath("xmlns:email").content
117
+ location = environment.at_xpath("xmlns:location")
118
+ if location
119
+ feed.location_name.should == location.at_xpath("xmlns:name").content
120
+ feed.location_lat.should == location.at_xpath("xmlns:lat").content
121
+ feed.location_lon.should == location.at_xpath("xmlns:lon").content
122
+ feed.location_ele.should == location.at_xpath("xmlns:ele").content
123
+ feed.location_domain.should == location.attributes["domain"].value
124
+ feed.location_exposure.should == location.attributes["exposure"].value
125
+ feed.location_disposition.should == location.attributes["disposition"].value
126
+ end
127
+ feed.datastreams.each do |ds|
128
+ data = environment.at_xpath("xmlns:data[@id=\"#{ds.id}\"]")
129
+ ds.id.should == data.attributes["id"].value
130
+ if (tags = data.xpath("xmlns:tag").collect { |t| t.content.strip }).any?
131
+ ds.tags.should == tags.sort{ |a,b| a.downcase <=> b.downcase }.join(',')
132
+ end
133
+ current_value = data.at_xpath("xmlns:value")
134
+ ds.current_value.should == current_value.content
135
+ ds.min_value.should == current_value.attributes["minValue"].value
136
+ ds.max_value.should == current_value.attributes["maxValue"].value
137
+ unit = data.at_xpath("xmlns:unit")
138
+ if unit
139
+ ds.unit_label.should == unit.content
140
+ ds.unit_type.should == unit.attributes["type"].value if unit.attributes["type"]
141
+ ds.unit_symbol.should == unit.attributes["symbol"].value if unit.attributes["symbol"]
142
+ end
143
+ end
144
+ true
145
+ else
146
+ false
147
+ end
148
+ end
149
+
150
+ def match_json_feed(feed, formatted_feed)
151
+ json = MultiJson.load(formatted_feed)
152
+ case json['version']
153
+ when '1.0.0'
154
+ feed.title.should == json["title"]
155
+ feed.status.should == json["status"]
156
+ feed.creator.should == json["creator"]
157
+ feed.updated.should == json["updated"]
158
+ feed.created.should == json["created"]
159
+ feed.website.should == json["website"]
160
+ feed.private.should == json["private"]
161
+ feed.feed.should == json["feed"]
162
+ feed.auto_feed_url.should == json["auto_feed_url"]
163
+ no_units = true
164
+ feed.datastreams.should_not be_empty
165
+ feed.datastreams.each do |datastream|
166
+ ds = json['datastreams'].detect{|s| s["id"] == datastream.id}
167
+ datastream.current_value.should == ds["current_value"]
168
+ datastream.min_value.should == ds["min_value"]
169
+ datastream.max_value.should == ds["max_value"]
170
+ datastream.updated.should == ds["at"]
171
+ datastream.tags.should == ds["tags"].join(',')
172
+ if ds["unit"]
173
+ no_units = false
174
+ datastream.unit_label.should == ds["unit"]["label"]
175
+ datastream.unit_symbol.should == ds["unit"]["symbol"]
176
+ datastream.unit_type.should == ds["unit"]["type"]
177
+ end
178
+ datastream.datapoints.each do |datapoint|
179
+ dp = ds['datapoints'].detect{|s| s["at"] == datapoint.at}
180
+ datapoint.value.should == dp["value"]
181
+ end
182
+ end
183
+ raise "This test is testing a feed with no datastream units" if no_units
184
+ feed.id.should == json["id"]
185
+ json["location"].should_not be_empty
186
+ feed.location_disposition.should == json["location"]["disposition"]
187
+ feed.location_domain.should == json["location"]["domain"]
188
+ feed.location_ele.should == json["location"]["ele"]
189
+ feed.location_exposure.should == json["location"]["exposure"]
190
+ feed.location_lat.should == json["location"]["lat"]
191
+ feed.location_lon.should == json["location"]["lon"]
192
+ feed.location_name.should == json["location"]["name"]
193
+ feed.owner_login.should == json["user"]["login"]
194
+ when '0.6-alpha'
195
+ feed.title.should == json["title"]
196
+ feed.status.should == json["status"]
197
+ feed.updated.should == json["updated"]
198
+ feed.website.should == json["website"]
199
+ feed.private.should be_nil
200
+ feed.feed.should == json["feed"]
201
+ no_units = true
202
+ feed.datastreams.should_not be_empty
203
+ feed.datastreams.each do |datastream|
204
+ ds = json['datastreams'].detect{|s| s["id"] == datastream.id}
205
+ datastream.current_value.should == ds["values"].first["value"]
206
+ datastream.min_value.should == ds["values"].first["min_value"]
207
+ datastream.max_value.should == ds["values"].first["max_value"]
208
+ datastream.updated.should == ds["values"].first["recorded_at"]
209
+ datastream.tags.should == ds["tags"].join(',')
210
+ if ds["unit"]
211
+ no_units = false
212
+ datastream.unit_label.should == ds["unit"]["label"]
213
+ datastream.unit_symbol.should == ds["unit"]["symbol"]
214
+ datastream.unit_type.should == ds["unit"]["type"]
215
+ end
216
+ end
217
+ raise "This test is testing a feed with no datastream units" if no_units
218
+ feed.id.should == json["id"]
219
+ json["location"].should_not be_empty
220
+ feed.location_disposition.should == json["location"]["disposition"]
221
+ feed.location_domain.should == json["location"]["domain"]
222
+ feed.location_ele.should == json["location"]["ele"]
223
+ feed.location_exposure.should == json["location"]["exposure"]
224
+ feed.location_lat.should == json["location"]["lat"]
225
+ feed.location_lon.should == json["location"]["lon"]
226
+ feed.location_name.should == json["location"]["name"]
227
+ else
228
+ false
229
+ end
230
+ end
231
+
232
+ end
233
+
234
+
@@ -0,0 +1,74 @@
1
+ RSpec::Matchers.define :fully_represent_key do |format, formatted_key|
2
+ match do |key|
3
+ case format.to_sym
4
+ when :xml
5
+ match_xml_key(key, formatted_key)
6
+ when :json
7
+ match_json_key(key, formatted_key)
8
+ end
9
+ end
10
+
11
+ failure_message_for_should do |key|
12
+ "expected #{key.attributes.inspect} to fully represent #{formatted_key}"
13
+ end
14
+
15
+ description do
16
+ "expected #{formatted_key.class} to be fully represented"
17
+ end
18
+
19
+ def match_xml_key(key, formatted_key)
20
+ xml = Nokogiri.parse(formatted_key)
21
+ key.id.should == xml.at_xpath("//id").content
22
+ key.expires_at.should == xml.at_xpath("//expires-at").content
23
+ key.key.should == xml.at_xpath("//api-key").content
24
+ key.user.should == xml.at_xpath("//user").content
25
+ key.label.should == xml.at_xpath("//label").content
26
+ key.private_access.should == xml.at_xpath("//private-access").content
27
+
28
+ # TODO: fix this
29
+ key.permissions.each_index do |permission_index|
30
+ permission = key.permissions[permission_index]
31
+ permission_node = xml.xpath("//permissions/permission")[permission_index]
32
+
33
+ permission.label.should == permission_node.at_xpath("label").content
34
+ permission.referer.should == permission_node.at_xpath("referer").content
35
+ permission.source_ip.should == permission_node.at_xpath("source-ip").content
36
+ permission.access_methods.should == permission_node.xpath("access-methods/access-method").collect { |a| a.content.downcase }
37
+
38
+ permission.resources.each_index do |res_index|
39
+ resource = permission.resources[res_index]
40
+ resource_node = permission_node.xpath("resources/resource")[res_index]
41
+
42
+ resource.feed_id.should == resource_node.at_xpath("feed-id").content
43
+ resource.datastream_id.should == resource_node.at_xpath("datastream-id").content
44
+ resource.datastream_trigger_id.should == resource_node.at_xpath("datastream-trigger-id").content
45
+ end
46
+ end
47
+ end
48
+
49
+ def match_json_key(key, formatted_key)
50
+ json = MultiJson.load(formatted_key)["key"]
51
+ key.id.should == json["id"]
52
+ key.expires_at.should == json["expires_at"]
53
+ key.key.should == json["api_key"]
54
+ key.user.should == json["user"]
55
+ key.label.should == json["label"]
56
+ key.private_access.should == json["private_access"]
57
+ key.permissions.each_index do |index|
58
+ permission = key.permissions[index]
59
+
60
+ permission.referer.should == json["permissions"][index]["referer"]
61
+ permission.source_ip.should == json["permissions"][index]["source_ip"]
62
+ permission.label.should == json["permissions"][index]["label"]
63
+ permission.access_methods.should == json["permissions"][index]["access_methods"]
64
+
65
+ permission.resources.each_index do |res_index|
66
+ resource = permission.resources[res_index]
67
+
68
+ resource.feed_id.should == json["permissions"][index]["resources"][res_index]["feed_id"]
69
+ resource.datastream_id.should == json["permissions"][index]["resources"][res_index]["datastream_id"]
70
+ resource.datastream_trigger_id.should == json["permissions"][index]["resources"][res_index]["datastream_trigger_id"]
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,67 @@
1
+ RSpec::Matchers.define :fully_represent_search_result do |format, formatted_search_result|
2
+ match do |search_result|
3
+ match_json_search_result(search_result, formatted_search_result)
4
+ end
5
+
6
+ failure_message_for_should do |search_result|
7
+ "expected #{search_result} to fully represent #{formatted_search_result}"
8
+ end
9
+
10
+ description do
11
+ "expected #{formatted_search_result.class} to be fully represented"
12
+ end
13
+
14
+ def match_json_search_result(search_result, formatted_search_result)
15
+ json = MultiJson.load(formatted_search_result)
16
+ search_result.totalResults.should == json['totalResults']
17
+ search_result.startIndex.should == json['startIndex']
18
+ search_result.itemsPerPage.should == json['itemsPerPage']
19
+ json = json['results'].first
20
+ feed = search_result.results.first
21
+ case json['version']
22
+ when '1.0.0'
23
+ feed.title.should == json["title"]
24
+ feed.status.should == json["status"]
25
+ feed.creator.should == json["creator"]
26
+ feed.updated.should == json["updated"]
27
+ feed.website.should == json["website"]
28
+ feed.private.should == json["private"]
29
+ feed.feed.should == json["feed"]
30
+ no_units = true
31
+ feed.datastreams.should_not be_empty
32
+ feed.datastreams.each do |datastream|
33
+ ds = json['datastreams'].detect{|s| s["id"] == datastream.id}
34
+ datastream.current_value.should == ds["current_value"]
35
+ datastream.min_value.should == ds["min_value"]
36
+ datastream.max_value.should == ds["max_value"]
37
+ datastream.updated.should == ds["at"]
38
+ datastream.tags.should == ds["tags"].join(',')
39
+ if ds["unit"]
40
+ no_units = false
41
+ datastream.unit_label.should == ds["unit"]["label"]
42
+ datastream.unit_symbol.should == ds["unit"]["symbol"]
43
+ datastream.unit_type.should == ds["unit"]["type"]
44
+ end
45
+ datastream.datapoints.each do |datapoint|
46
+ dp = ds['datapoints'].detect{|s| s["at"] == datapoint.at}
47
+ datapoint.value.should == dp["value"]
48
+ end
49
+ end
50
+ raise "This test is testing a feed with no datastream units" if no_units
51
+ feed.id.should == json["id"]
52
+ json["location"].should_not be_empty
53
+ feed.location_disposition.should == json["location"]["disposition"]
54
+ feed.location_domain.should == json["location"]["domain"]
55
+ feed.location_ele.should == json["location"]["ele"]
56
+ feed.location_exposure.should == json["location"]["exposure"]
57
+ feed.location_lat.should == json["location"]["lat"]
58
+ feed.location_lon.should == json["location"]["lon"]
59
+ feed.location_name.should == json["location"]["name"]
60
+ else
61
+ false
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+