cosm-rb 0.0.1

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 (122) hide show
  1. data/.gitignore +12 -0
  2. data/.rbenv-version +1 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +10 -0
  6. data/CHANGELOG.md +91 -0
  7. data/Gemfile +4 -0
  8. data/MIT-LICENSE +20 -0
  9. data/README.md +195 -0
  10. data/Rakefile +35 -0
  11. data/ci/build_hudson.sh +24 -0
  12. data/cosm-rb.gemspec +40 -0
  13. data/init.rb +2 -0
  14. data/lib/cosm-rb/array_extensions.rb +6 -0
  15. data/lib/cosm-rb/base/instance_methods.rb +28 -0
  16. data/lib/cosm-rb/base.rb +52 -0
  17. data/lib/cosm-rb/client.rb +7 -0
  18. data/lib/cosm-rb/datapoint.rb +71 -0
  19. data/lib/cosm-rb/datastream.rb +136 -0
  20. data/lib/cosm-rb/feed.rb +108 -0
  21. data/lib/cosm-rb/hash_extensions.rb +16 -0
  22. data/lib/cosm-rb/helpers.rb +42 -0
  23. data/lib/cosm-rb/key.rb +98 -0
  24. data/lib/cosm-rb/nil_content.rb +15 -0
  25. data/lib/cosm-rb/object_extensions.rb +6 -0
  26. data/lib/cosm-rb/parsers/csv/datastream_defaults.rb +12 -0
  27. data/lib/cosm-rb/parsers/csv/feed_defaults.rb +38 -0
  28. data/lib/cosm-rb/parsers/defaults.rb +13 -0
  29. data/lib/cosm-rb/parsers/json/datapoint_defaults.rb +12 -0
  30. data/lib/cosm-rb/parsers/json/datastream_defaults.rb +53 -0
  31. data/lib/cosm-rb/parsers/json/feed_defaults.rb +103 -0
  32. data/lib/cosm-rb/parsers/json/key_defaults.rb +15 -0
  33. data/lib/cosm-rb/parsers/json/search_result_defaults.rb +18 -0
  34. data/lib/cosm-rb/parsers/json/trigger_defaults.rb +12 -0
  35. data/lib/cosm-rb/parsers/xml/datapoint_defaults.rb +20 -0
  36. data/lib/cosm-rb/parsers/xml/datastream_defaults.rb +77 -0
  37. data/lib/cosm-rb/parsers/xml/feed_defaults.rb +127 -0
  38. data/lib/cosm-rb/parsers/xml/key_defaults.rb +40 -0
  39. data/lib/cosm-rb/parsers/xml/trigger_defaults.rb +22 -0
  40. data/lib/cosm-rb/permission.rb +67 -0
  41. data/lib/cosm-rb/resource.rb +43 -0
  42. data/lib/cosm-rb/search_result.rb +63 -0
  43. data/lib/cosm-rb/string_extensions.rb +6 -0
  44. data/lib/cosm-rb/template.rb +32 -0
  45. data/lib/cosm-rb/templates/csv/datapoint_defaults.rb +22 -0
  46. data/lib/cosm-rb/templates/csv/datastream_defaults.rb +43 -0
  47. data/lib/cosm-rb/templates/csv/feed_defaults.rb +47 -0
  48. data/lib/cosm-rb/templates/defaults.rb +14 -0
  49. data/lib/cosm-rb/templates/json/datapoint_defaults.rb +15 -0
  50. data/lib/cosm-rb/templates/json/datastream_defaults.rb +66 -0
  51. data/lib/cosm-rb/templates/json/feed_defaults.rb +134 -0
  52. data/lib/cosm-rb/templates/json/key_defaults.rb +41 -0
  53. data/lib/cosm-rb/templates/json/search_result_defaults.rb +47 -0
  54. data/lib/cosm-rb/templates/json/trigger_defaults.rb +21 -0
  55. data/lib/cosm-rb/templates/xml/datapoint_defaults.rb +25 -0
  56. data/lib/cosm-rb/templates/xml/datastream_defaults.rb +66 -0
  57. data/lib/cosm-rb/templates/xml/feed_defaults.rb +110 -0
  58. data/lib/cosm-rb/templates/xml/search_result_defaults.rb +116 -0
  59. data/lib/cosm-rb/templates/xml_headers.rb +17 -0
  60. data/lib/cosm-rb/trigger.rb +65 -0
  61. data/lib/cosm-rb/validations.rb +9 -0
  62. data/lib/cosm-rb/version.rb +3 -0
  63. data/lib/cosm-rb.rb +29 -0
  64. data/spec/cosm-rb/array_extensions_spec.rb +9 -0
  65. data/spec/cosm-rb/base/instance_methods_spec.rb +109 -0
  66. data/spec/cosm-rb/base_spec.rb +56 -0
  67. data/spec/cosm-rb/client_spec.rb +7 -0
  68. data/spec/cosm-rb/datapoint_spec.rb +169 -0
  69. data/spec/cosm-rb/datastream_spec.rb +301 -0
  70. data/spec/cosm-rb/feed_spec.rb +298 -0
  71. data/spec/cosm-rb/hash_extensions_spec.rb +20 -0
  72. data/spec/cosm-rb/helpers_spec.rb +56 -0
  73. data/spec/cosm-rb/key_spec.rb +178 -0
  74. data/spec/cosm-rb/parsers/csv/datastream_defaults_spec.rb +12 -0
  75. data/spec/cosm-rb/parsers/csv/feed_defaults_spec.rb +35 -0
  76. data/spec/cosm-rb/parsers/json/datapoint_defaults_spec.rb +15 -0
  77. data/spec/cosm-rb/parsers/json/datastream_defaults_spec.rb +82 -0
  78. data/spec/cosm-rb/parsers/json/feed_defaults_spec.rb +18 -0
  79. data/spec/cosm-rb/parsers/json/key_defaults_spec.rb +8 -0
  80. data/spec/cosm-rb/parsers/json/search_result_defaults_spec.rb +12 -0
  81. data/spec/cosm-rb/parsers/json/trigger_defaults_spec.rb +16 -0
  82. data/spec/cosm-rb/parsers/xml/datapoint_defaults_spec.rb +19 -0
  83. data/spec/cosm-rb/parsers/xml/datastream_defaults_spec.rb +63 -0
  84. data/spec/cosm-rb/parsers/xml/feed_defaults_spec.rb +65 -0
  85. data/spec/cosm-rb/parsers/xml/key_defaults_spec.rb +16 -0
  86. data/spec/cosm-rb/parsers/xml/trigger_defaults_spec.rb +16 -0
  87. data/spec/cosm-rb/search_result_spec.rb +258 -0
  88. data/spec/cosm-rb/string_extensions_spec.rb +12 -0
  89. data/spec/cosm-rb/template_spec.rb +74 -0
  90. data/spec/cosm-rb/templates/csv/datapoint_defaults_spec.rb +41 -0
  91. data/spec/cosm-rb/templates/csv/datastream_defaults_spec.rb +131 -0
  92. data/spec/cosm-rb/templates/csv/feed_defaults_spec.rb +78 -0
  93. data/spec/cosm-rb/templates/json/datapoint_defaults_spec.rb +14 -0
  94. data/spec/cosm-rb/templates/json/datastream_defaults_spec.rb +170 -0
  95. data/spec/cosm-rb/templates/json/feed_defaults_spec.rb +397 -0
  96. data/spec/cosm-rb/templates/json/key_defaults_spec.rb +29 -0
  97. data/spec/cosm-rb/templates/json/search_result_defaults_spec.rb +37 -0
  98. data/spec/cosm-rb/templates/json/trigger_defaults_spec.rb +19 -0
  99. data/spec/cosm-rb/templates/xml/datapoint_defaults_spec.rb +14 -0
  100. data/spec/cosm-rb/templates/xml/datastream_defaults_spec.rb +113 -0
  101. data/spec/cosm-rb/templates/xml/feed_defaults_spec.rb +131 -0
  102. data/spec/cosm-rb/templates/xml/search_result_defaults_spec.rb +44 -0
  103. data/spec/cosm-rb/trigger_spec.rb +117 -0
  104. data/spec/fixtures/models.rb +81 -0
  105. data/spec/spec_helper.rb +17 -0
  106. data/spec/support/contain_datapoint_eeml_matcher.rb +16 -0
  107. data/spec/support/contain_datastream_eeml_matcher.rb +60 -0
  108. data/spec/support/contain_feed_eeml_matcher.rb +96 -0
  109. data/spec/support/datapoint_helper.rb +53 -0
  110. data/spec/support/datastream_helper.rb +300 -0
  111. data/spec/support/describe_eeml_matcher.rb +23 -0
  112. data/spec/support/feed_helper.rb +771 -0
  113. data/spec/support/fully_represent_datapoint_matcher.rb +30 -0
  114. data/spec/support/fully_represent_datastream_matcher.rb +92 -0
  115. data/spec/support/fully_represent_feed_matcher.rb +226 -0
  116. data/spec/support/fully_represent_key_matcher.rb +74 -0
  117. data/spec/support/fully_represent_search_result_matcher.rb +67 -0
  118. data/spec/support/fully_represent_trigger_matcher.rb +29 -0
  119. data/spec/support/key_helper.rb +74 -0
  120. data/spec/support/search_result_helper.rb +252 -0
  121. data/spec/support/trigger_helper.rb +51 -0
  122. metadata +363 -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,92 @@
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 = JSON.parse(formatted_datastream)
79
+ case json['version']
80
+ when '1.0.0'
81
+ raise "Not implemented"
82
+ else
83
+ false
84
+ end
85
+ end
86
+
87
+ def match_csv_datastream(datastream, formatted_datastream)
88
+ datastream.current_value.to_s.should == formatted_datastream.strip
89
+ end
90
+ end
91
+
92
+
@@ -0,0 +1,226 @@
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} 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 = 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 = 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
+ end
42
+ end
43
+
44
+ def match_xml_feed(feed, formatted_feed)
45
+ xml = Nokogiri.parse(formatted_feed)
46
+ case xml.root.attributes["version"].value
47
+ when "0.5.1"
48
+ environment = xml.at_xpath("//xmlns:environment")
49
+ feed.title.should == environment.at_xpath("xmlns:title").content
50
+ feed.updated.should == environment.attributes["updated"].value
51
+ feed.created.should == environment.attributes["created"].value
52
+ feed.creator.should == environment.attributes["creator"].value
53
+ feed.feed.should == environment.at_xpath("xmlns:feed").content
54
+ if auto_feed_url = environment.at_xpath("xmlns:auto_feed_url")
55
+ feed.auto_feed_url.should == auto_feed_url.content
56
+ end
57
+ feed.status.should == environment.at_xpath("xmlns:status").content
58
+ feed.description.should == environment.at_xpath("xmlns:description").content
59
+ feed.icon.should == environment.at_xpath("xmlns:icon").content
60
+ feed.website.should == environment.at_xpath("xmlns:website").content
61
+ feed.email.should == environment.at_xpath("xmlns:email").content
62
+ feed.private.should == environment.at_xpath("xmlns:private").content
63
+ feed.tags.should == environment.xpath("xmlns:tag").map(&:content).sort{|a,b| a.downcase<=>b.downcase}.join(',')
64
+ owner = environment.at_xpath("xmlns:user")
65
+ if owner
66
+ feed.owner_login.should == owner.at_xpath("xmlns:login").content
67
+ end
68
+ location = environment.at_xpath("xmlns:location")
69
+ if location
70
+ feed.location_name.should == location.at_xpath("xmlns:name").content
71
+ feed.location_lat.should == location.at_xpath("xmlns:lat").content
72
+ feed.location_lon.should == location.at_xpath("xmlns:lon").content
73
+ feed.location_ele.should == location.at_xpath("xmlns:ele").content
74
+ feed.location_domain.should == location.attributes["domain"].value
75
+ feed.location_exposure.should == location.attributes["exposure"].value
76
+ feed.location_disposition.should == location.attributes["disposition"].value
77
+ end
78
+ feed.datastreams.each do |ds|
79
+ data = environment.at_xpath("xmlns:data[@id=\"#{ds.id}\"]")
80
+ ds.id.should == data.attributes["id"].value
81
+ ds.tags.should == data.xpath("xmlns:tag").map(&:content).sort{|a,b| a.downcase<=>b.downcase}.join(',')
82
+ current_value = data.at_xpath("xmlns:current_value")
83
+ ds.current_value.should == current_value.content
84
+ ds.updated.should == current_value.attributes["at"].value
85
+ ds.min_value.should == data.at_xpath("xmlns:min_value").content
86
+ ds.max_value.should == data.at_xpath("xmlns:max_value").content
87
+ unit = data.at_xpath("xmlns:unit")
88
+ if unit
89
+ ds.unit_label.should == unit.content
90
+ ds.unit_type.should == unit.attributes["type"].value if unit.attributes["type"]
91
+ ds.unit_symbol.should == unit.attributes["symbol"].value if unit.attributes["symbol"]
92
+ end
93
+ ds.datapoints.each do |point|
94
+ dp = data.at_xpath("xmlns:datapoints").at_xpath("xmlns:value[@at=\"#{point.at}\"]")
95
+ point.value.should == dp.content
96
+ end
97
+ end
98
+ true
99
+ when "5"
100
+ environment = xml.at_xpath("//xmlns:environment")
101
+ feed.title.should == environment.at_xpath("xmlns:title").content
102
+ feed.updated.should == environment.attributes["updated"].value
103
+ feed.creator.should == "http://www.haque.co.uk"
104
+ feed.feed.should == environment.at_xpath("xmlns:feed").content
105
+ feed.status.should == environment.at_xpath("xmlns:status").content
106
+ feed.description.should == environment.at_xpath("xmlns:description").content
107
+ feed.icon.should == environment.at_xpath("xmlns:icon").content
108
+ feed.website.should == environment.at_xpath("xmlns:website").content
109
+ feed.email.should == environment.at_xpath("xmlns:email").content
110
+ location = environment.at_xpath("xmlns:location")
111
+ if location
112
+ feed.location_name.should == location.at_xpath("xmlns:name").content
113
+ feed.location_lat.should == location.at_xpath("xmlns:lat").content
114
+ feed.location_lon.should == location.at_xpath("xmlns:lon").content
115
+ feed.location_ele.should == location.at_xpath("xmlns:ele").content
116
+ feed.location_domain.should == location.attributes["domain"].value
117
+ feed.location_exposure.should == location.attributes["exposure"].value
118
+ feed.location_disposition.should == location.attributes["disposition"].value
119
+ end
120
+ feed.datastreams.each do |ds|
121
+ data = environment.at_xpath("xmlns:data[@id=\"#{ds.id}\"]")
122
+ ds.id.should == data.attributes["id"].value
123
+ ds.tags.should == data.xpath("xmlns:tag").map(&:content).sort{|a,b| a.downcase<=>b.downcase}.join(',')
124
+ current_value = data.at_xpath("xmlns:value")
125
+ ds.current_value.should == current_value.content
126
+ ds.updated.should == environment.attributes["updated"].value
127
+ ds.min_value.should == current_value.attributes["minValue"].value
128
+ ds.max_value.should == current_value.attributes["maxValue"].value
129
+ unit = data.at_xpath("xmlns:unit")
130
+ if unit
131
+ ds.unit_label.should == unit.content
132
+ ds.unit_type.should == unit.attributes["type"].value if unit.attributes["type"]
133
+ ds.unit_symbol.should == unit.attributes["symbol"].value if unit.attributes["symbol"]
134
+ end
135
+ end
136
+ true
137
+ else
138
+ false
139
+ end
140
+ end
141
+
142
+ def match_json_feed(feed, formatted_feed)
143
+ json = JSON.parse(formatted_feed)
144
+ case json['version']
145
+ when '1.0.0'
146
+ feed.title.should == json["title"]
147
+ feed.status.should == json["status"]
148
+ feed.creator.should == json["creator"]
149
+ feed.updated.should == json["updated"]
150
+ feed.created.should == json["created"]
151
+ feed.website.should == json["website"]
152
+ feed.private.should == json["private"]
153
+ feed.feed.should == json["feed"]
154
+ feed.auto_feed_url.should == json["auto_feed_url"]
155
+ no_units = true
156
+ feed.datastreams.should_not be_empty
157
+ feed.datastreams.each do |datastream|
158
+ ds = json['datastreams'].detect{|s| s["id"] == datastream.id}
159
+ datastream.current_value.should == ds["current_value"]
160
+ datastream.min_value.should == ds["min_value"]
161
+ datastream.max_value.should == ds["max_value"]
162
+ datastream.updated.should == ds["at"]
163
+ datastream.tags.should == ds["tags"].join(',')
164
+ if ds["unit"]
165
+ no_units = false
166
+ datastream.unit_label.should == ds["unit"]["label"]
167
+ datastream.unit_symbol.should == ds["unit"]["symbol"]
168
+ datastream.unit_type.should == ds["unit"]["type"]
169
+ end
170
+ datastream.datapoints.each do |datapoint|
171
+ dp = ds['datapoints'].detect{|s| s["at"] == datapoint.at}
172
+ datapoint.value.should == dp["value"]
173
+ end
174
+ end
175
+ raise "This test is testing a feed with no datastream units" if no_units
176
+ feed.id.should == json["id"]
177
+ json["location"].should_not be_empty
178
+ feed.location_disposition.should == json["location"]["disposition"]
179
+ feed.location_domain.should == json["location"]["domain"]
180
+ feed.location_ele.should == json["location"]["ele"]
181
+ feed.location_exposure.should == json["location"]["exposure"]
182
+ feed.location_lat.should == json["location"]["lat"]
183
+ feed.location_lon.should == json["location"]["lon"]
184
+ feed.location_name.should == json["location"]["name"]
185
+ feed.owner_login.should == json["user"]["login"]
186
+ when '0.6-alpha'
187
+ feed.title.should == json["title"]
188
+ feed.status.should == json["status"]
189
+ feed.updated.should == json["updated"]
190
+ feed.website.should == json["website"]
191
+ feed.private.should be_nil
192
+ feed.feed.should == json["feed"]
193
+ no_units = true
194
+ feed.datastreams.should_not be_empty
195
+ feed.datastreams.each do |datastream|
196
+ ds = json['datastreams'].detect{|s| s["id"] == datastream.id}
197
+ datastream.current_value.should == ds["values"].first["value"]
198
+ datastream.min_value.should == ds["values"].first["min_value"]
199
+ datastream.max_value.should == ds["values"].first["max_value"]
200
+ datastream.updated.should == ds["values"].first["recorded_at"]
201
+ datastream.tags.should == ds["tags"].join(',')
202
+ if ds["unit"]
203
+ no_units = false
204
+ datastream.unit_label.should == ds["unit"]["label"]
205
+ datastream.unit_symbol.should == ds["unit"]["symbol"]
206
+ datastream.unit_type.should == ds["unit"]["type"]
207
+ end
208
+ end
209
+ raise "This test is testing a feed with no datastream units" if no_units
210
+ feed.id.should == json["id"]
211
+ json["location"].should_not be_empty
212
+ feed.location_disposition.should == json["location"]["disposition"]
213
+ feed.location_domain.should == json["location"]["domain"]
214
+ feed.location_ele.should == json["location"]["ele"]
215
+ feed.location_exposure.should == json["location"]["exposure"]
216
+ feed.location_lat.should == json["location"]["lat"]
217
+ feed.location_lon.should == json["location"]["lon"]
218
+ feed.location_name.should == json["location"]["name"]
219
+ else
220
+ false
221
+ end
222
+ end
223
+
224
+ end
225
+
226
+
@@ -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 = JSON.parse(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 = JSON.parse(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
+
@@ -0,0 +1,29 @@
1
+ RSpec::Matchers.define :fully_represent_trigger do |format, formatted_trigger|
2
+ match do |trigger|
3
+ if format.to_sym == :xml
4
+ match_xml_trigger(trigger, formatted_trigger)
5
+ end
6
+ end
7
+
8
+ failure_message_for_should do |trigger|
9
+ "expected #{trigger} to fully represent #{formatted_trigger}"
10
+ end
11
+
12
+ description do
13
+ "expected #{formatted_datapoint.class} to be fully represented"
14
+ end
15
+
16
+ def match_xml_trigger(trigger, formatted_trigger)
17
+ xml = Nokogiri.parse(formatted_trigger)
18
+ trigger.id.should == xml.at_xpath("//id").content
19
+ trigger.url.should == xml.at_xpath("//url").content
20
+ trigger.trigger_type.should == xml.at_xpath("//trigger-type").content
21
+ trigger.threshold_value.should == xml.at_xpath("//threshold-value").content
22
+ trigger.notified_at.should == xml.at_xpath("//notified-at").content
23
+ trigger.user.should == xml.at_xpath("//user").content
24
+ trigger.environment_id.should == xml.at_xpath("//environment-id").content
25
+ trigger.stream_id.should == xml.at_xpath("//stream-id").content
26
+ end
27
+ end
28
+
29
+
@@ -0,0 +1,74 @@
1
+ def key_as_(format, options = {})
2
+ # Default data
3
+ # This data is based on http://api.cosm.com/v2/feeds/504
4
+ case format.to_s
5
+ when 'hash', 'json'
6
+ data = { "id" => 40, "key" => "abcdefghasdfaoisdj109usasdf0a9sf", "label" => "Our awesome label",
7
+ "user" => "lebreeze", "expires_at" => 12345, "private_access" => true,
8
+ "permissions" => [
9
+ { "source_ip" => "127.0.0.1", "referer" => "http://cosm.com",
10
+ "access_methods" => %w(get put post delete),
11
+ "resources" => [
12
+ { "feed_id" => 424, "datastream_id" => "1" }
13
+ ]
14
+ }
15
+ ]}
16
+ when 'xml'
17
+ data = <<XML
18
+ <?xml version="1.0" encoding="UTF-8"?>
19
+ <key>
20
+ <id>40</id>
21
+ <api-key>abcdefghasdfaoisdj109usasdf0a9sf</api-key>
22
+ <expires-at>12345</expires-at>
23
+ <user>lebreeze</user>
24
+ <label>Our awesome label</label>
25
+ <private-access>true</private-access>
26
+ <permissions>
27
+ <permission>
28
+ <referer>http://cosm.com</referer>
29
+ <source-ip>127.0.0.1</source-ip>
30
+ <access-methods>
31
+ <access-method>GET</access-method>
32
+ <access-method>PUT</access-method>
33
+ <access-method>POST</access-method>
34
+ <access-method>DELETE</access-method>
35
+ </access-methods>
36
+ <resources>
37
+ <resource>
38
+ <feed-id>424</feed-id>
39
+ <datastream-id>1</datastream-id>
40
+ </resource>
41
+ </resources>
42
+ </permission>
43
+ </permissions>
44
+ </key>
45
+ XML
46
+ end
47
+
48
+ # Add extra options we passed
49
+ if options[:with]
50
+ options[:with].each do |field, value|
51
+ data[field.to_s] = value
52
+ end
53
+ end
54
+
55
+ # Remove options we don't need
56
+ if options[:except]
57
+ options[:except].each do |field,_|
58
+ data.delete(field.to_s)
59
+ end
60
+ end
61
+
62
+ # Return the feed in the requested format
63
+ case format.to_s
64
+ when 'hash'
65
+ data
66
+ when 'json'
67
+ { "key" => data }.to_json
68
+ when 'xml'
69
+ data
70
+ else
71
+ raise "#{format} undefined"
72
+ end
73
+ end
74
+