cosm-rb 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -5
- data/Rakefile +6 -4
- data/cosm-rb.gemspec +11 -3
- data/lib/cosm-rb.rb +9 -1
- data/lib/cosm-rb/datastream.rb +0 -10
- data/lib/cosm-rb/parsers/csv/datastream_defaults.rb +10 -2
- data/lib/cosm-rb/parsers/csv/feed_defaults.rb +15 -10
- data/lib/cosm-rb/parsers/json/feed_defaults.rb +29 -24
- data/lib/cosm-rb/parsers/xml/datapoint_defaults.rb +1 -0
- data/lib/cosm-rb/parsers/xml/datastream_defaults.rb +7 -5
- data/lib/cosm-rb/parsers/xml/feed_defaults.rb +63 -39
- data/lib/cosm-rb/templates/csv/datapoint_defaults.rb +4 -4
- data/lib/cosm-rb/templates/csv/datastream_defaults.rb +2 -2
- data/lib/cosm-rb/templates/csv/feed_defaults.rb +5 -5
- data/lib/cosm-rb/version.rb +1 -1
- data/spec/cosm-rb/datastream_spec.rb +1 -0
- data/spec/cosm-rb/parsers/csv/datastream_defaults_spec.rb +22 -0
- data/spec/cosm-rb/parsers/csv/feed_defaults_spec.rb +18 -0
- data/spec/cosm-rb/parsers/json/feed_defaults_spec.rb +22 -0
- data/spec/cosm-rb/parsers/xml/feed_defaults_spec.rb +70 -0
- data/spec/cosm-rb/templates/csv/datapoint_defaults_spec.rb +2 -2
- data/spec/cosm-rb/templates/csv/datastream_defaults_spec.rb +5 -5
- data/spec/cosm-rb/templates/csv/feed_defaults_spec.rb +7 -7
- data/spec/spec_helper.rb +14 -0
- data/spec/support/feed_helper.rb +11 -1
- data/spec/support/fully_represent_feed_matcher.rb +15 -6
- metadata +44 -87
data/.travis.yml
CHANGED
data/Rakefile
CHANGED
@@ -20,10 +20,12 @@ desc "Run all specs in spec directory"
|
|
20
20
|
RSpec::Core::RakeTask.new do |t|
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
if RUBY_VERSION.to_f < 1.9
|
24
|
+
desc "Run all specs with rcov"
|
25
|
+
RSpec::Core::RakeTask.new(:rcov => :clean) do |t|
|
26
|
+
t.rcov = true
|
27
|
+
t.rcov_opts = '--exclude .gem/*,spec/*,.bundle/*,config/*,.rvm/*,lib/cosm-rb.rb'
|
28
|
+
end
|
27
29
|
end
|
28
30
|
|
29
31
|
namespace :spec do
|
data/cosm-rb.gemspec
CHANGED
@@ -25,10 +25,18 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_dependency("nokogiri", ">=1.4.4")
|
26
26
|
s.add_dependency("httparty", ">=0.8.3")
|
27
27
|
|
28
|
+
if RUBY_VERSION.to_f < 1.9
|
29
|
+
s.add_dependency("fastercsv", ">=1.5.x")
|
30
|
+
end
|
31
|
+
|
28
32
|
begin
|
29
|
-
if
|
30
|
-
|
31
|
-
|
33
|
+
if !defined?(JRUBY_VERSION)
|
34
|
+
if RUBY_VERSION.to_f < 1.9
|
35
|
+
s.add_development_dependency("ruby-debug")
|
36
|
+
s.add_development_dependency("rcov", ">=0.9.9")
|
37
|
+
else
|
38
|
+
s.add_development_dependency("simplecov")
|
39
|
+
end
|
32
40
|
end
|
33
41
|
rescue
|
34
42
|
p "Could not detect ruby version"
|
data/lib/cosm-rb.rb
CHANGED
@@ -4,7 +4,6 @@ if defined?(JRUBY_VERSION)
|
|
4
4
|
else
|
5
5
|
require 'yajl/json_gem'
|
6
6
|
end
|
7
|
-
require 'csv'
|
8
7
|
|
9
8
|
$:.unshift(File.dirname(File.expand_path(__FILE__)))
|
10
9
|
|
@@ -31,3 +30,12 @@ require 'cosm-rb/permission'
|
|
31
30
|
require 'cosm-rb/resource'
|
32
31
|
|
33
32
|
require 'cosm-rb/client'
|
33
|
+
|
34
|
+
if RUBY_VERSION.to_f < 1.9
|
35
|
+
require 'fastercsv'
|
36
|
+
Cosm::CSV = FasterCSV
|
37
|
+
else
|
38
|
+
require 'csv'
|
39
|
+
Cosm::CSV = CSV
|
40
|
+
end
|
41
|
+
|
data/lib/cosm-rb/datastream.rb
CHANGED
@@ -13,16 +13,6 @@ module Cosm
|
|
13
13
|
include Cosm::Parsers::CSV::DatastreamDefaults
|
14
14
|
|
15
15
|
include Validations
|
16
|
-
# validate :before, :join_tags
|
17
|
-
|
18
|
-
# validates_presence_of :id
|
19
|
-
# validates_length_of :current_value, :maximum => 255
|
20
|
-
# validates_length_of :tags, :maximum => 255
|
21
|
-
# validates_inclusion_of :unit_type, :in => VALID_UNIT_TYPES,
|
22
|
-
# :allow_nil => true,
|
23
|
-
# :message => "is not a valid unit_type (pick one from #{VALID_UNIT_TYPES} or leave blank)"
|
24
|
-
# validates_format_of :id, :with => /\A[\w\-\+\.]+\Z/
|
25
|
-
#
|
26
16
|
|
27
17
|
def valid?
|
28
18
|
pass = true
|
@@ -2,8 +2,16 @@ module Cosm
|
|
2
2
|
module Parsers
|
3
3
|
module CSV
|
4
4
|
module DatastreamDefaults
|
5
|
-
def from_csv(csv)
|
6
|
-
|
5
|
+
def from_csv(csv, csv_version = nil)
|
6
|
+
rows = Cosm::CSV.parse(csv.strip)
|
7
|
+
raise InvalidCSVError, "CSV is invalid. Can only construct a Cosm::Datastream object from a single row of data" if rows.size > 1
|
8
|
+
row = rows.first
|
9
|
+
raise InvalidCSVError, "CSV is invalid. Too many fields; must only be a single value, or a timestamp and a value" if row.size > 2
|
10
|
+
if row.size == 2
|
11
|
+
return { "updated" => row[0], "current_value" => row[1].to_s }
|
12
|
+
else
|
13
|
+
return { "current_value" => row[0].to_s }
|
14
|
+
end
|
7
15
|
end
|
8
16
|
end
|
9
17
|
end
|
@@ -2,20 +2,25 @@ module Cosm
|
|
2
2
|
module Parsers
|
3
3
|
module CSV
|
4
4
|
class UnknownVersionError < StandardError ; end
|
5
|
+
class InvalidCSVError < StandardError ; end
|
6
|
+
|
5
7
|
module FeedDefaults
|
6
8
|
def from_csv(csv, csv_version = nil)
|
7
|
-
|
8
|
-
version = detect_version(
|
9
|
+
rows = Cosm::CSV.parse(csv.strip)
|
10
|
+
version = detect_version(rows, csv_version)
|
9
11
|
hash = Hash.new
|
10
12
|
if version == :v2
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
raise InvalidCSVError, "CSV is invalid. Incorrect number of fields" if rows.sort { |a,b| a.length <=> b.length }.reverse.first.length > 3
|
14
|
+
hash["datastreams"] = rows.collect {|row|
|
15
|
+
timestamp = {}
|
16
|
+
if row.size == 3
|
17
|
+
timestamp["updated"] = row[1]
|
18
|
+
end
|
19
|
+
{ "id" => row.first.to_s, "current_value" => row.last.to_s }.merge(timestamp)
|
15
20
|
}
|
16
21
|
elsif version == :v1
|
17
22
|
hash["datastreams"] = []
|
18
|
-
|
23
|
+
rows.first.each_with_index do |current_value, stream_id|
|
19
24
|
hash["datastreams"] << { "id" => stream_id.to_s, "current_value" => current_value }
|
20
25
|
end
|
21
26
|
end
|
@@ -25,10 +30,10 @@ module Cosm
|
|
25
30
|
|
26
31
|
private
|
27
32
|
|
28
|
-
def detect_version(
|
33
|
+
def detect_version(rows, version = nil)
|
29
34
|
return version if version
|
30
|
-
return :v2 if
|
31
|
-
return :v1 if
|
35
|
+
return :v2 if rows.size >= 2
|
36
|
+
return :v1 if rows.size == 1 && rows.first.size != 2
|
32
37
|
raise UnknownVersionError, "CSV Version could not be detected"
|
33
38
|
end
|
34
39
|
end
|
@@ -10,7 +10,7 @@ module Cosm
|
|
10
10
|
case hash['version']
|
11
11
|
when '1.0.0'
|
12
12
|
transform_1_0_0(hash)
|
13
|
-
when '0.6-alpha'
|
13
|
+
when '0.6-alpha', '0.6'
|
14
14
|
transform_0_6_alpha(hash)
|
15
15
|
end
|
16
16
|
end
|
@@ -59,30 +59,35 @@ module Cosm
|
|
59
59
|
def transform_0_6_alpha(hash)
|
60
60
|
hash["retrieved_at"] = hash["updated"]
|
61
61
|
hash["state"] = hash["status"]
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
if hash["datastreams"]
|
63
|
+
hash["datastreams"] = hash["datastreams"].collect do |datastream|
|
64
|
+
unit_hash = {}
|
65
|
+
if unit = datastream.delete('unit')
|
66
|
+
unit_hash['unit_type'] = unit['type']
|
67
|
+
unit_hash['unit_symbol'] = unit['symbol']
|
68
|
+
unit_hash['unit_label'] = unit['label']
|
69
|
+
end
|
70
|
+
value_hash = {}
|
71
|
+
if datastream["values"].size >= 1
|
72
|
+
value_hash["current_value"] = datastream["values"].first["value"]
|
73
|
+
value_hash["min_value"] = datastream["values"].first["min_value"]
|
74
|
+
value_hash["max_value"] = datastream["values"].first["max_value"]
|
75
|
+
value_hash["updated"] = datastream["values"].first["recorded_at"]
|
76
|
+
end
|
77
|
+
{
|
78
|
+
"id" => datastream["id"],
|
79
|
+
"tags" => join_tags(datastream["tags"]),
|
80
|
+
}.merge(value_hash).merge(unit_hash)
|
81
|
+
end
|
82
|
+
if location = hash.delete("location")
|
83
|
+
hash["location_disposition"] = location["disposition"]
|
84
|
+
hash["location_domain"] = location["domain"]
|
85
|
+
hash["location_ele"] = location["ele"]
|
86
|
+
hash["location_exposure"] = location["exposure"]
|
87
|
+
hash["location_lat"] = location["lat"]
|
88
|
+
hash["location_lon"] = location["lon"]
|
89
|
+
hash["location_name"] = location["name"]
|
68
90
|
end
|
69
|
-
{
|
70
|
-
"id" => datastream["id"],
|
71
|
-
"current_value" => datastream["values"].first["value"],
|
72
|
-
"min_value" => datastream["values"].first["min_value"],
|
73
|
-
"max_value" => datastream["values"].first["max_value"],
|
74
|
-
"updated" => datastream["values"].first["recorded_at"],
|
75
|
-
"tags" => join_tags(datastream["tags"]),
|
76
|
-
}.merge(unit_hash)
|
77
|
-
end
|
78
|
-
if location = hash.delete("location")
|
79
|
-
hash["location_disposition"] = location["disposition"]
|
80
|
-
hash["location_domain"] = location["domain"]
|
81
|
-
hash["location_ele"] = location["ele"]
|
82
|
-
hash["location_exposure"] = location["exposure"]
|
83
|
-
hash["location_lat"] = location["lat"]
|
84
|
-
hash["location_lon"] = location["lon"]
|
85
|
-
hash["location_name"] = location["name"]
|
86
91
|
end
|
87
92
|
hash
|
88
93
|
end
|
@@ -6,6 +6,7 @@ module Cosm
|
|
6
6
|
xml = Nokogiri.parse(xml)
|
7
7
|
hash = {}
|
8
8
|
environment = xml.at_xpath("//xmlns:environment")
|
9
|
+
raise InvalidXMLError, "Missing 'environment' node from base node" if environment.nil?
|
9
10
|
data = environment.at_xpath("xmlns:data")
|
10
11
|
datapoint = data.at_xpath("xmlns:datapoints")
|
11
12
|
value = datapoint.at_xpath("xmlns:value")
|
@@ -18,12 +18,13 @@ module Cosm
|
|
18
18
|
def transform_0_5_1(xml)
|
19
19
|
hash = {}
|
20
20
|
environment = xml.at_xpath("//xmlns:environment")
|
21
|
+
raise InvalidXMLError, "Missing 'environment' node from base node" if environment.nil?
|
21
22
|
data = environment.at_xpath("xmlns:data")
|
22
23
|
hash["feed_id"] = environment.attributes["id"].value
|
23
24
|
hash["feed_creator"] = environment.attributes["creator"].value
|
24
25
|
hash["id"] = data.attributes["id"].value
|
25
|
-
if (tags = data.xpath("xmlns:tag").collect
|
26
|
-
hash["tags"] = tags.sort{|a,b| a.downcase <=> b.downcase}.
|
26
|
+
if (tags = data.xpath("xmlns:tag").collect { |t| t.content.strip }).any?
|
27
|
+
hash["tags"] = Cosm::CSV.generate_line(tags.sort{|a,b| a.downcase <=> b.downcase}).strip
|
27
28
|
end
|
28
29
|
current_value = data.at_xpath("xmlns:current_value")
|
29
30
|
hash["current_value"] = current_value.content
|
@@ -40,7 +41,7 @@ module Cosm
|
|
40
41
|
value = datapoint.at_xpath("xmlns:value")
|
41
42
|
{
|
42
43
|
"value" => value.content,
|
43
|
-
"at" => value.attributes["at"].
|
44
|
+
"at" => value.attributes["at"].value
|
44
45
|
}
|
45
46
|
end
|
46
47
|
hash
|
@@ -50,13 +51,14 @@ module Cosm
|
|
50
51
|
def transform_5(xml)
|
51
52
|
hash = {}
|
52
53
|
environment = xml.at_xpath("//xmlns:environment")
|
54
|
+
raise InvalidXMLError, "Missing 'environment' node from base node" if environment.nil?
|
53
55
|
data = environment.at_xpath("xmlns:data")
|
54
56
|
hash["feed_id"] = environment.attributes["id"].value
|
55
57
|
hash["feed_creator"] = "http://www.haque.co.uk"
|
56
58
|
hash["updated"] = environment.attributes["updated"].value
|
57
59
|
hash["id"] = data.attributes["id"].value
|
58
|
-
if (tags = data.xpath("xmlns:tag").collect
|
59
|
-
hash["tags"] = tags.sort{|a,b| a.downcase <=> b.downcase}.
|
60
|
+
if (tags = data.xpath("xmlns:tag").collect { |t| t.content.strip }).any?
|
61
|
+
hash["tags"] = Cosm::CSV.generate_line(tags.sort{ |a,b| a.downcase <=> b.downcase }).strip
|
60
62
|
end
|
61
63
|
current_value = data.at_xpath("xmlns:value")
|
62
64
|
hash["current_value"] = current_value.content
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module Cosm
|
2
2
|
module Parsers
|
3
3
|
module XML
|
4
|
+
class InvalidXMLError < StandardError; end
|
4
5
|
module FeedDefaults
|
5
6
|
def from_xml(xml)
|
6
7
|
xml = Nokogiri.parse(xml)
|
7
8
|
case xml.root.attributes["version"].value
|
8
9
|
when "0.5.1"
|
9
10
|
transform_0_5_1(xml)
|
10
|
-
else
|
11
|
+
else
|
11
12
|
transform_5(xml)
|
12
13
|
end
|
13
14
|
end
|
@@ -16,60 +17,73 @@ module Cosm
|
|
16
17
|
def transform_0_5_1(xml)
|
17
18
|
hash = {}
|
18
19
|
environment = xml.at_xpath("//xmlns:environment")
|
20
|
+
raise InvalidXMLError, "Missing 'environment' node from base node" if environment.nil?
|
19
21
|
hash["updated"] = environment.attributes["updated"].value
|
20
22
|
hash["created"] = environment.attributes["created"].value
|
21
23
|
hash["creator"] = environment.attributes["creator"].value
|
22
|
-
hash["title"] = environment.at_xpath("xmlns:title").content
|
23
|
-
hash["feed"] = environment.at_xpath("xmlns:feed").content
|
24
|
-
hash["auto_feed_url"] = environment.at_xpath("xmlns:auto_feed_url").content
|
25
|
-
hash["status"] = environment.at_xpath("xmlns:status").content
|
26
|
-
hash["description"] = environment.at_xpath("xmlns:description").content
|
27
|
-
hash["icon"] = environment.at_xpath("xmlns:icon").content
|
28
|
-
hash["website"] = environment.at_xpath("xmlns:website").content
|
29
|
-
hash["email"] = environment.at_xpath("xmlns:email").content
|
30
|
-
hash["private"] = environment.at_xpath("xmlns:private").content
|
31
|
-
|
24
|
+
hash["title"] = strip(environment.at_xpath("xmlns:title").content)
|
25
|
+
hash["feed"] = strip(environment.at_xpath("xmlns:feed").content)
|
26
|
+
hash["auto_feed_url"] = strip(environment.at_xpath("xmlns:auto_feed_url").content)
|
27
|
+
hash["status"] = strip(environment.at_xpath("xmlns:status").content)
|
28
|
+
hash["description"] = strip(environment.at_xpath("xmlns:description").content)
|
29
|
+
hash["icon"] = strip(environment.at_xpath("xmlns:icon").content)
|
30
|
+
hash["website"] = strip(environment.at_xpath("xmlns:website").content)
|
31
|
+
hash["email"] = strip(environment.at_xpath("xmlns:email").content)
|
32
|
+
hash["private"] = strip(environment.at_xpath("xmlns:private").content)
|
33
|
+
if (tags = environment.xpath("xmlns:tag").collect { |t| t.content.strip }).any?
|
34
|
+
hash["tags"] = Cosm::CSV.generate_line(tags.sort{|a,b| a.downcase <=> b.downcase}).strip
|
35
|
+
end
|
32
36
|
location = environment.at_xpath("xmlns:location")
|
33
37
|
if location
|
34
|
-
hash["location_name"] = location.at_xpath("xmlns:name").content
|
35
|
-
hash["location_lat"] = location.at_xpath("xmlns:lat").content
|
36
|
-
hash["location_lon"] = location.at_xpath("xmlns:lon").content
|
37
|
-
hash["location_ele"] = location.at_xpath("xmlns:ele").content
|
38
|
+
hash["location_name"] = strip(location.at_xpath("xmlns:name").content)
|
39
|
+
hash["location_lat"] = strip(location.at_xpath("xmlns:lat").content)
|
40
|
+
hash["location_lon"] = strip(location.at_xpath("xmlns:lon").content)
|
41
|
+
hash["location_ele"] = strip(location.at_xpath("xmlns:ele").content)
|
38
42
|
hash["location_domain"] = location.attributes["domain"].value
|
39
43
|
hash["location_exposure"] = location.attributes["exposure"].value
|
40
44
|
hash["location_disposition"] = location.attributes["disposition"].value
|
41
45
|
end
|
42
46
|
owner = environment.at_xpath("xmlns:user")
|
43
47
|
if owner
|
44
|
-
hash["owner_login"] = owner.at_xpath("xmlns:login").content
|
48
|
+
hash["owner_login"] = strip(owner.at_xpath("xmlns:login").content)
|
45
49
|
end
|
46
50
|
hash["datastreams"] = environment.xpath("xmlns:data").collect do |datastream|
|
47
51
|
current_value = datastream.at_xpath("xmlns:current_value")
|
52
|
+
if current_value
|
53
|
+
value_hash = {
|
54
|
+
"current_value" => strip(current_value.content),
|
55
|
+
"updated" => current_value.attributes["at"].value,
|
56
|
+
}
|
57
|
+
else
|
58
|
+
value_hash = {}
|
59
|
+
end
|
48
60
|
unit = datastream.at_xpath("xmlns:unit")
|
49
61
|
if unit
|
50
62
|
unit_hash = {
|
51
|
-
"unit_label" => unit.content,
|
63
|
+
"unit_label" => strip(unit.content),
|
52
64
|
"unit_type" => unit.attributes["type"].value,
|
53
65
|
"unit_symbol" => unit.attributes["symbol"].value,
|
54
66
|
}
|
55
67
|
else
|
56
68
|
unit_hash = {}
|
57
69
|
end
|
70
|
+
if (tags = datastream.xpath("xmlns:tag").collect { |t| t.content.strip }).any?
|
71
|
+
tags_hash = { "tags" => Cosm::CSV.generate_line(tags.sort { |a, b| a.downcase <=> b.downcase }).strip }
|
72
|
+
else
|
73
|
+
tags_hash = {}
|
74
|
+
end
|
58
75
|
{
|
59
76
|
"id" => datastream.attributes["id"].value,
|
60
|
-
"
|
61
|
-
"
|
62
|
-
"updated" => current_value.attributes["at"].value,
|
63
|
-
"min_value" => datastream.at_xpath("xmlns:min_value").content,
|
64
|
-
"max_value" => datastream.at_xpath("xmlns:max_value").content,
|
77
|
+
"min_value" => strip(datastream.at_xpath("xmlns:min_value").content),
|
78
|
+
"max_value" => strip(datastream.at_xpath("xmlns:max_value").content),
|
65
79
|
"datapoints" => datastream.xpath("xmlns:datapoints").collect do |datapoint|
|
66
80
|
value = datapoint.at_xpath("xmlns:value")
|
67
81
|
{
|
68
82
|
"at" => value.attributes["at"].value,
|
69
|
-
"value" => value.content,
|
83
|
+
"value" => strip(value.content),
|
70
84
|
}
|
71
85
|
end
|
72
|
-
}.merge(unit_hash)
|
86
|
+
}.merge(value_hash).merge(unit_hash).merge(tags_hash)
|
73
87
|
end
|
74
88
|
hash
|
75
89
|
end
|
@@ -78,21 +92,22 @@ module Cosm
|
|
78
92
|
def transform_5(xml)
|
79
93
|
hash = {}
|
80
94
|
environment = xml.at_xpath("//xmlns:environment")
|
95
|
+
raise InvalidXMLError, "Missing 'environment' node from base node" if environment.nil?
|
81
96
|
hash["updated"] = environment.attributes["updated"].value
|
82
97
|
hash["creator"] = "http://www.haque.co.uk"
|
83
|
-
hash["title"] = environment.at_xpath("xmlns:title").content
|
84
|
-
hash["feed"] = environment.at_xpath("xmlns:feed").content
|
85
|
-
hash["status"] = environment.at_xpath("xmlns:status").content
|
86
|
-
hash["description"] = environment.at_xpath("xmlns:description").content
|
87
|
-
hash["icon"] = environment.at_xpath("xmlns:icon").content
|
88
|
-
hash["website"] = environment.at_xpath("xmlns:website").content
|
89
|
-
hash["email"] = environment.at_xpath("xmlns:email").content
|
98
|
+
hash["title"] = strip(environment.at_xpath("xmlns:title").content)
|
99
|
+
hash["feed"] = strip(environment.at_xpath("xmlns:feed").content)
|
100
|
+
hash["status"] = strip(environment.at_xpath("xmlns:status").content)
|
101
|
+
hash["description"] = strip(environment.at_xpath("xmlns:description").content)
|
102
|
+
hash["icon"] = strip(environment.at_xpath("xmlns:icon").content)
|
103
|
+
hash["website"] = strip(environment.at_xpath("xmlns:website").content)
|
104
|
+
hash["email"] = strip(environment.at_xpath("xmlns:email").content)
|
90
105
|
location = environment.at_xpath("xmlns:location")
|
91
106
|
if location
|
92
|
-
hash["location_name"] = location.at_xpath("xmlns:name").content
|
93
|
-
hash["location_lat"] = location.at_xpath("xmlns:lat").content
|
94
|
-
hash["location_lon"] = location.at_xpath("xmlns:lon").content
|
95
|
-
hash["location_ele"] = location.at_xpath("xmlns:ele").content
|
107
|
+
hash["location_name"] = strip(location.at_xpath("xmlns:name").content)
|
108
|
+
hash["location_lat"] = strip(location.at_xpath("xmlns:lat").content)
|
109
|
+
hash["location_lon"] = strip(location.at_xpath("xmlns:lon").content)
|
110
|
+
hash["location_ele"] = strip(location.at_xpath("xmlns:ele").content)
|
96
111
|
hash["location_domain"] = location.attributes["domain"].value
|
97
112
|
hash["location_exposure"] = location.attributes["exposure"].value
|
98
113
|
hash["location_disposition"] = location.attributes["disposition"].value
|
@@ -102,24 +117,33 @@ module Cosm
|
|
102
117
|
unit = datastream.at_xpath("xmlns:unit")
|
103
118
|
if unit
|
104
119
|
unit_hash = {
|
105
|
-
"unit_label" => unit.content,
|
120
|
+
"unit_label" => strip(unit.content),
|
106
121
|
"unit_type" => unit.attributes["type"].value,
|
107
122
|
"unit_symbol" => unit.attributes["symbol"].value,
|
108
123
|
}
|
109
124
|
else
|
110
125
|
unit_hash = {}
|
111
126
|
end
|
127
|
+
if (tags = datastream.xpath("xmlns:tag").collect { |t| t.content.strip }).any?
|
128
|
+
tags_hash = { "tags" => Cosm::CSV.generate_line(tags.sort { |a, b| a.downcase <=> b.downcase }).strip }
|
129
|
+
else
|
130
|
+
tags_hash = {}
|
131
|
+
end
|
112
132
|
{
|
113
133
|
"id" => datastream.attributes["id"].value,
|
114
|
-
"
|
115
|
-
"current_value" => current_value.content,
|
134
|
+
"current_value" => strip(current_value.content),
|
116
135
|
"updated" => environment.attributes["updated"].value,
|
117
136
|
"min_value" => current_value.attributes["minValue"].value,
|
118
137
|
"max_value" => current_value.attributes["maxValue"].value,
|
119
|
-
}.merge(unit_hash)
|
138
|
+
}.merge(unit_hash).merge(tags_hash)
|
120
139
|
end
|
121
140
|
hash
|
122
141
|
end
|
142
|
+
|
143
|
+
def strip(value)
|
144
|
+
return value.nil? ? nil : value.strip
|
145
|
+
end
|
146
|
+
private :strip
|
123
147
|
end
|
124
148
|
end
|
125
149
|
end
|
@@ -6,13 +6,13 @@ module Cosm
|
|
6
6
|
options[:depth] = 4 if options[:full]
|
7
7
|
case options[:depth].to_i
|
8
8
|
when 4
|
9
|
-
::CSV.generate_line([feed_id, datastream_id, at.iso8601(6), value]).strip
|
9
|
+
Cosm::CSV.generate_line([feed_id, datastream_id, at.iso8601(6), value]).strip
|
10
10
|
when 3
|
11
|
-
::CSV.generate_line([datastream_id, at.iso8601(6), value]).strip
|
11
|
+
Cosm::CSV.generate_line([datastream_id, at.iso8601(6), value]).strip
|
12
12
|
when 2
|
13
|
-
::CSV.generate_line([at.iso8601(6), value]).strip
|
13
|
+
Cosm::CSV.generate_line([at.iso8601(6), value]).strip
|
14
14
|
else
|
15
|
-
::CSV.generate_line([value]).strip
|
15
|
+
Cosm::CSV.generate_line([value]).strip
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -30,11 +30,11 @@ module Cosm
|
|
30
30
|
datapoints.collect {|datapoint| csv << [datapoint.at.iso8601(6), datapoint.value] }
|
31
31
|
csv << [updated.iso8601(6), current_value] if csv.empty?
|
32
32
|
end
|
33
|
-
csv.collect {|row| ::CSV.generate_line(row).strip }.join("\n")
|
33
|
+
csv.collect {|row| Cosm::CSV.generate_line(row).strip }.join("\n")
|
34
34
|
end
|
35
35
|
|
36
36
|
def csv_1
|
37
|
-
::CSV.generate_line([current_value]).strip
|
37
|
+
Cosm::CSV.generate_line([current_value]).strip
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -18,9 +18,9 @@ module Cosm
|
|
18
18
|
if options[:full]
|
19
19
|
datastreams.collect do |datastream|
|
20
20
|
if datastream.datapoints.any?
|
21
|
-
datastream.datapoints.collect { |datapoint| csv << ::CSV.generate_line([id, datastream.id, datapoint.at.iso8601(6), datapoint.value]).strip }
|
21
|
+
datastream.datapoints.collect { |datapoint| csv << Cosm::CSV.generate_line([id, datastream.id, datapoint.at.iso8601(6), datapoint.value]).strip }
|
22
22
|
else
|
23
|
-
csv << ::CSV.generate_line([id, datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
23
|
+
csv << Cosm::CSV.generate_line([id, datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
24
24
|
end
|
25
25
|
|
26
26
|
|
@@ -28,9 +28,9 @@ module Cosm
|
|
28
28
|
else
|
29
29
|
datastreams.collect do |datastream|
|
30
30
|
if datastream.datapoints.any?
|
31
|
-
datastream.datapoints.collect { |datapoint| csv << ::CSV.generate_line([datastream.id, datapoint.at.iso8601(6), datapoint.value]).strip }
|
31
|
+
datastream.datapoints.collect { |datapoint| csv << Cosm::CSV.generate_line([datastream.id, datapoint.at.iso8601(6), datapoint.value]).strip }
|
32
32
|
else
|
33
|
-
csv << ::CSV.generate_line([datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
33
|
+
csv << Cosm::CSV.generate_line([datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -38,7 +38,7 @@ module Cosm
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def csv_1
|
41
|
-
::CSV.generate_line(datastreams.collect {|ds| ds.current_value }).strip
|
41
|
+
Cosm::CSV.generate_line(datastreams.collect {|ds| ds.current_value }).strip
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
data/lib/cosm-rb/version.rb
CHANGED
@@ -7,6 +7,28 @@ describe "default datastream csv parser" do
|
|
7
7
|
datastream = Cosm::Datastream.new(csv)
|
8
8
|
datastream.should fully_represent_datastream(:csv, csv)
|
9
9
|
end
|
10
|
+
|
11
|
+
it "should capture timestamp if present" do
|
12
|
+
timestamp = Time.now.iso8601(6)
|
13
|
+
csv = "#{timestamp},123"
|
14
|
+
datastream = Cosm::Datastream.new(csv)
|
15
|
+
datastream.updated.should == timestamp
|
16
|
+
datastream.current_value.should == "123"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should raise error if passed more than a single row" do
|
20
|
+
csv = "12\n13"
|
21
|
+
expect {
|
22
|
+
Cosm::Datastream.new(csv)
|
23
|
+
}.to raise_error(Cosm::Parsers::CSV::InvalidCSVError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should raise error passed more than three values in a row" do
|
27
|
+
csv = "#{Time.now.iso8601(6)},123,456"
|
28
|
+
expect {
|
29
|
+
Cosm::Datastream.new(csv)
|
30
|
+
}.to raise_error(Cosm::Parsers::CSV::InvalidCSVError)
|
31
|
+
end
|
10
32
|
end
|
11
33
|
end
|
12
34
|
|
@@ -8,6 +8,12 @@ describe "default feed csv parser" do
|
|
8
8
|
feed.should fully_represent_feed(:csv_v2, csv)
|
9
9
|
end
|
10
10
|
|
11
|
+
it "should convert no timestamp v2 CSV into attributes hash" do
|
12
|
+
csv = feed_as_(:csv, :version => 'v2_notimestamp')
|
13
|
+
feed = Cosm::Feed.new(csv)
|
14
|
+
feed.should fully_represent_feed(:csv_v2, csv)
|
15
|
+
end
|
16
|
+
|
11
17
|
it "should convert Pachube CSV v1 into attributes hash" do
|
12
18
|
csv = feed_as_(:csv, :version => 'v1')
|
13
19
|
feed = Cosm::Feed.new(csv)
|
@@ -30,6 +36,18 @@ describe "default feed csv parser" do
|
|
30
36
|
feed = Cosm::Feed.new(csv, :v1)
|
31
37
|
feed.should fully_represent_feed(:csv_v1, csv)
|
32
38
|
end
|
39
|
+
|
40
|
+
it "should raise an error if passed some wild csv with more than max permitted three columns" do
|
41
|
+
csv =<<-CSV
|
42
|
+
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,
|
43
|
+
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,
|
44
|
+
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,
|
45
|
+
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,
|
46
|
+
CSV
|
47
|
+
expect {
|
48
|
+
Cosm::Feed.new(csv)
|
49
|
+
}.to raise_error(Cosm::Parsers::CSV::InvalidCSVError)
|
50
|
+
end
|
33
51
|
end
|
34
52
|
end
|
35
53
|
|
@@ -13,6 +13,28 @@ describe "default feed json parser" do
|
|
13
13
|
feed = Cosm::Feed.new(json)
|
14
14
|
feed.should fully_represent_feed(:json, json)
|
15
15
|
end
|
16
|
+
|
17
|
+
it "should convert Pachube JSON 0.6-alpha (used by API v1) into attributes hash" do
|
18
|
+
json = feed_as_(:json, :version => "0.6")
|
19
|
+
feed = Cosm::Feed.new(json)
|
20
|
+
feed.should fully_represent_feed(:json, json)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should handle json if no value present" do
|
24
|
+
json = "{\"version\":\"0.6-alpha\",\"datastreams\":[{\"unit\":{\"label\":\"Tmax\",\"symbol\":\"C\"},\"values\":{},\"id\":\"1\"}]}"
|
25
|
+
expect {
|
26
|
+
feed = Cosm::Feed.new(json)
|
27
|
+
feed.datastreams.size.should == 1
|
28
|
+
}.to_not raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should capture empty fields if present" do
|
32
|
+
json = "{\"version\":\"1.0.0\",\"description\":\"\",\"feed\":\"\",\"location\":{\"name\":\"\"}}"
|
33
|
+
feed = Cosm::Feed.new(json)
|
34
|
+
feed.description.should == ""
|
35
|
+
feed.feed.should == ""
|
36
|
+
feed.location_name.should == ""
|
37
|
+
end
|
16
38
|
end
|
17
39
|
end
|
18
40
|
|
@@ -27,6 +27,38 @@ describe "default feed xml parser" do
|
|
27
27
|
Cosm::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
|
28
28
|
end
|
29
29
|
|
30
|
+
it "should gracefully handle 0.5.1 xml missing the base environment node" do
|
31
|
+
xml = <<-EOXML
|
32
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
33
|
+
<eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
|
34
|
+
<title>ohai</title>
|
35
|
+
</eeml>
|
36
|
+
EOXML
|
37
|
+
expect {
|
38
|
+
Cosm::Feed.new(xml)
|
39
|
+
}.to raise_error(Cosm::Parsers::XML::InvalidXMLError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should handle datastream with no current_value" do
|
43
|
+
xml = <<-EOXML
|
44
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
45
|
+
<eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/0.5.1 http://www.eeml.org/xsd/0.5.1/0.5.1.xsd">
|
46
|
+
<environment updated="2011-02-16T16:21:01.834174Z" id="504" creator="http://test.host/users/fred">
|
47
|
+
<title>Cosm Office environment</title>
|
48
|
+
<data id="0">
|
49
|
+
<tag>freakin lasers</tag>
|
50
|
+
<tag>humidity</tag>
|
51
|
+
<tag>Temperature</tag>
|
52
|
+
</data>
|
53
|
+
</environment>
|
54
|
+
</eeml>
|
55
|
+
EOXML
|
56
|
+
|
57
|
+
feed = Cosm::Feed.new(xml)
|
58
|
+
feed.datastreams.size.should == 1
|
59
|
+
feed.datastreams.first.tags.should == "freakin lasers,humidity,Temperature"
|
60
|
+
end
|
61
|
+
|
30
62
|
end
|
31
63
|
|
32
64
|
context "5 (used by API v1)" do
|
@@ -57,9 +89,47 @@ describe "default feed xml parser" do
|
|
57
89
|
|
58
90
|
it "should handle missing value attributes" do
|
59
91
|
@xml = feed_as_(:xml, :version => "5", :except_node => :value_attributes)
|
92
|
+
feed = Cosm::Feed.new(@xml)
|
60
93
|
Cosm::Feed.new(@xml).should fully_represent_feed(:xml, @xml)
|
61
94
|
end
|
62
95
|
|
96
|
+
it "should gracefully handle 0.5.1 xml missing the base environment node" do
|
97
|
+
xml = <<-EOXML
|
98
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
99
|
+
<eeml xmlns="http://www.eeml.org/xsd/005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
|
100
|
+
<title>ohai</title>
|
101
|
+
</eeml>
|
102
|
+
EOXML
|
103
|
+
expect {
|
104
|
+
Cosm::Feed.new(xml)
|
105
|
+
}.to raise_error(Cosm::Parsers::XML::InvalidXMLError)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should gracefully handle our oddly whitespaced real example" do
|
109
|
+
xml = <<-EOXML
|
110
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
111
|
+
<eeml version="5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.eeml.org/xsd/005" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd">
|
112
|
+
<environment>
|
113
|
+
<data id="4773635294300160">
|
114
|
+
<tag>
|
115
|
+
10.F59894010800</tag>
|
116
|
+
<tag>
|
117
|
+
Living Room, S wall</tag>
|
118
|
+
<value>
|
119
|
+
24.1875</value>
|
120
|
+
<unit type="derivedSI">
|
121
|
+
celsius</unit>
|
122
|
+
</data>
|
123
|
+
</environment>
|
124
|
+
</eeml>
|
125
|
+
EOXML
|
126
|
+
feed = Cosm::Feed.new(xml)
|
127
|
+
|
128
|
+
datastream = feed.datastreams.first
|
129
|
+
datastream.tags.should == "10.F59894010800,\"Living Room, S wall\""
|
130
|
+
datastream.current_value.should == "24.1875"
|
131
|
+
datastream.unit_label.should == "celsius"
|
132
|
+
end
|
63
133
|
end
|
64
134
|
end
|
65
135
|
|
@@ -29,13 +29,13 @@ describe "default datapoint json templates" do
|
|
29
29
|
it "should escape stuff that could upset csv parsers" do
|
30
30
|
@datapoint.value = "I \n , am not a csv"
|
31
31
|
csv = @datapoint.generate_csv("2")
|
32
|
-
csv.should == CSV.generate_line([@datapoint.value]).strip
|
32
|
+
csv.should == Cosm::CSV.generate_line([@datapoint.value]).strip
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should escape characters that could upset csv parsers via full" do
|
36
36
|
@datapoint.value = "I \n , am not a csv"
|
37
37
|
csv = @datapoint.generate_csv("2", :full => true)
|
38
|
-
csv.should == CSV.generate_line([@datapoint.feed_id, @datapoint.datastream_id, @datapoint.at.iso8601(6), @datapoint.value]).strip
|
38
|
+
csv.should == Cosm::CSV.generate_line([@datapoint.feed_id, @datapoint.datastream_id, @datapoint.at.iso8601(6), @datapoint.value]).strip
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -85,7 +85,7 @@ describe "default datastream json templates" do
|
|
85
85
|
@datastream.current_value = "one,field"
|
86
86
|
@datastream.datapoints = []
|
87
87
|
csv = @datastream.generate_csv("2")
|
88
|
-
csv.should == CSV.generate_line([@datastream.updated.iso8601(6),@datastream.current_value]).strip
|
88
|
+
csv.should == Cosm::CSV.generate_line([@datastream.updated.iso8601(6),@datastream.current_value]).strip
|
89
89
|
end
|
90
90
|
|
91
91
|
it "should escape characters that could upset csv parsers with datapoints" do
|
@@ -94,14 +94,14 @@ describe "default datastream json templates" do
|
|
94
94
|
dp.value = "1,field"
|
95
95
|
end
|
96
96
|
csv = @datastream.generate_csv("2")
|
97
|
-
csv.should == @datastream.datapoints.collect {|dp| CSV.generate_line([dp.at.iso8601(6),dp.value]).strip }.join("\n")
|
97
|
+
csv.should == @datastream.datapoints.collect {|dp| Cosm::CSV.generate_line([dp.at.iso8601(6),dp.value]).strip }.join("\n")
|
98
98
|
end
|
99
99
|
|
100
100
|
it "should escape characters that could upset csv parsers without datapoints via full" do
|
101
101
|
@datastream.current_value = "one,field"
|
102
102
|
@datastream.datapoints = []
|
103
103
|
csv = @datastream.generate_csv("2", :full => true)
|
104
|
-
csv.should == CSV.generate_line([@datastream.feed_id,@datastream.id,@datastream.updated.iso8601(6),@datastream.current_value]).strip
|
104
|
+
csv.should == Cosm::CSV.generate_line([@datastream.feed_id,@datastream.id,@datastream.updated.iso8601(6),@datastream.current_value]).strip
|
105
105
|
end
|
106
106
|
|
107
107
|
it "should escape characters that could upset csv parsers with datapoints via full" do
|
@@ -110,7 +110,7 @@ describe "default datastream json templates" do
|
|
110
110
|
dp.value = "1,field"
|
111
111
|
end
|
112
112
|
csv = @datastream.generate_csv("2", :full => true)
|
113
|
-
csv.should == @datastream.datapoints.collect {|dp| CSV.generate_line([@datastream.feed_id,@datastream.id,dp.at.iso8601(6),dp.value]).strip }.join("\n")
|
113
|
+
csv.should == @datastream.datapoints.collect {|dp| Cosm::CSV.generate_line([@datastream.feed_id,@datastream.id,dp.at.iso8601(6),dp.value]).strip }.join("\n")
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -124,7 +124,7 @@ describe "default datastream json templates" do
|
|
124
124
|
it "should escape characters that could upset csv parsers" do
|
125
125
|
@datastream.current_value = "I \n am full of c,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, evil"
|
126
126
|
csv = @datastream.generate_csv("1")
|
127
|
-
csv.should == CSV.generate_line([@datastream.current_value]).strip
|
127
|
+
csv.should == Cosm::CSV.generate_line([@datastream.current_value]).strip
|
128
128
|
end
|
129
129
|
end
|
130
130
|
end
|
@@ -22,7 +22,7 @@ describe "default feed json templates" do
|
|
22
22
|
end
|
23
23
|
csv = @feed.generate_csv("2")
|
24
24
|
expected_csv = @feed.datastreams.collect do |datastream|
|
25
|
-
CSV.generate_line([datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
25
|
+
Cosm::CSV.generate_line([datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
26
26
|
end.join("\n")
|
27
27
|
csv.should == expected_csv
|
28
28
|
end
|
@@ -33,7 +33,7 @@ describe "default feed json templates" do
|
|
33
33
|
end
|
34
34
|
csv = @feed.generate_csv("2", :full => true)
|
35
35
|
expected_csv = @feed.datastreams.collect do |datastream|
|
36
|
-
CSV.generate_line([@feed.id, datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
36
|
+
Cosm::CSV.generate_line([@feed.id, datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
37
37
|
end.join("\n")
|
38
38
|
csv.should == expected_csv
|
39
39
|
end
|
@@ -42,9 +42,9 @@ describe "default feed json templates" do
|
|
42
42
|
csv = @feed.generate_csv("2")
|
43
43
|
expected_csv = @feed.datastreams.collect do |datastream|
|
44
44
|
if datastream.datapoints.any?
|
45
|
-
datastream.datapoints.collect {|dp| CSV.generate_line([datastream.id, dp.at.iso8601(6), dp.value]).strip }
|
45
|
+
datastream.datapoints.collect {|dp| Cosm::CSV.generate_line([datastream.id, dp.at.iso8601(6), dp.value]).strip }
|
46
46
|
else
|
47
|
-
CSV.generate_line([datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
47
|
+
Cosm::CSV.generate_line([datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
48
48
|
end
|
49
49
|
end.join("\n")
|
50
50
|
csv.should == expected_csv
|
@@ -54,9 +54,9 @@ describe "default feed json templates" do
|
|
54
54
|
csv = @feed.generate_csv("2", :full => true)
|
55
55
|
expected_csv = @feed.datastreams.collect do |datastream|
|
56
56
|
if datastream.datapoints.any?
|
57
|
-
datastream.datapoints.collect {|dp| CSV.generate_line([@feed.id, datastream.id, dp.at.iso8601(6), dp.value]).strip }
|
57
|
+
datastream.datapoints.collect {|dp| Cosm::CSV.generate_line([@feed.id, datastream.id, dp.at.iso8601(6), dp.value]).strip }
|
58
58
|
else
|
59
|
-
CSV.generate_line([@feed.id, datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
59
|
+
Cosm::CSV.generate_line([@feed.id, datastream.id, datastream.updated.iso8601(6), datastream.current_value]).strip
|
60
60
|
end
|
61
61
|
end.join("\n")
|
62
62
|
csv.should == expected_csv
|
@@ -68,7 +68,7 @@ describe "default feed json templates" do
|
|
68
68
|
it "should represent Pachube JSON" do
|
69
69
|
csv = @feed.generate_csv("1")
|
70
70
|
expected_csv = @feed.datastreams.collect do |datastream|
|
71
|
-
CSV.generate_line([datastream.current_value]).strip
|
71
|
+
Cosm::CSV.generate_line([datastream.current_value]).strip
|
72
72
|
end.join(",")
|
73
73
|
csv.should == expected_csv
|
74
74
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,6 +5,20 @@ require 'rspec'
|
|
5
5
|
|
6
6
|
require 'time'
|
7
7
|
|
8
|
+
if !defined?(JRUBY_VERSION)
|
9
|
+
if RUBY_VERSION < "1.9"
|
10
|
+
require 'ruby-debug'
|
11
|
+
else
|
12
|
+
if ENV["COVERAGE"] == "on"
|
13
|
+
require 'simplecov'
|
14
|
+
SimpleCov.start do
|
15
|
+
add_filter "/spec/"
|
16
|
+
add_filter "/lib/cosm-rb.rb"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
8
22
|
Dir['./spec/support/**/*.rb'].map {|f| require f}
|
9
23
|
|
10
24
|
$:.push File.expand_path("../lib", __FILE__)
|
data/spec/support/feed_helper.rb
CHANGED
@@ -159,6 +159,16 @@ def feed_as_csv(version)
|
|
159
159
|
4,2011-06-13T12:30:04.714629Z,0
|
160
160
|
5,2011-06-13T12:30:04.714629Z,0
|
161
161
|
6,2011-06-13T12:30:04.714629Z,-30362
|
162
|
+
}
|
163
|
+
when 'v2_notimestamp'
|
164
|
+
%Q{
|
165
|
+
0,15
|
166
|
+
1,905
|
167
|
+
2,326
|
168
|
+
3,0
|
169
|
+
4,0
|
170
|
+
5,0
|
171
|
+
6,-30362
|
162
172
|
}
|
163
173
|
when 'unknown'
|
164
174
|
'34,98'
|
@@ -265,7 +275,7 @@ def feed_as_json(version)
|
|
265
275
|
}
|
266
276
|
]
|
267
277
|
}
|
268
|
-
when "0.6-alpha"
|
278
|
+
when "0.6-alpha", "0.6"
|
269
279
|
{
|
270
280
|
"datastreams" => [{
|
271
281
|
"tags" => ["humidity"],
|
@@ -14,7 +14,7 @@ RSpec::Matchers.define :fully_represent_feed do |format, formatted_feed|
|
|
14
14
|
end
|
15
15
|
|
16
16
|
failure_message_for_should do |feed|
|
17
|
-
"expected #{feed} to fully represent #{formatted_feed}"
|
17
|
+
"expected #{feed.attributes.inspect} to fully represent #{formatted_feed}"
|
18
18
|
end
|
19
19
|
|
20
20
|
description do
|
@@ -22,7 +22,7 @@ RSpec::Matchers.define :fully_represent_feed do |format, formatted_feed|
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def match_csv_v1_feed(feed, formatted_feed)
|
25
|
-
csv = CSV.parse(formatted_feed.strip)
|
25
|
+
csv = Cosm::CSV.parse(formatted_feed.strip)
|
26
26
|
csv.length.should == 1
|
27
27
|
csv = csv.first
|
28
28
|
feed.datastreams.length.should == csv.length
|
@@ -33,11 +33,14 @@ RSpec::Matchers.define :fully_represent_feed do |format, formatted_feed|
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def match_csv_v2_feed(feed, formatted_feed)
|
36
|
-
csv = CSV.parse(formatted_feed.strip)
|
36
|
+
csv = Cosm::CSV.parse(formatted_feed.strip)
|
37
37
|
feed.datastreams.length.should == csv.length
|
38
38
|
feed.datastreams.each do |datastream|
|
39
39
|
row = csv.detect {|d| d.first == datastream.id}
|
40
40
|
datastream.current_value.should == row.last
|
41
|
+
if row.size == 3
|
42
|
+
datastream.updated.iso8601.should == row[1]
|
43
|
+
end
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
@@ -60,7 +63,9 @@ RSpec::Matchers.define :fully_represent_feed do |format, formatted_feed|
|
|
60
63
|
feed.website.should == environment.at_xpath("xmlns:website").content
|
61
64
|
feed.email.should == environment.at_xpath("xmlns:email").content
|
62
65
|
feed.private.should == environment.at_xpath("xmlns:private").content
|
63
|
-
feed.tags
|
66
|
+
if feed.tags
|
67
|
+
feed.tags.should == environment.xpath("xmlns:tag").map(&:content).sort{|a,b| a.downcase<=>b.downcase}.join(',')
|
68
|
+
end
|
64
69
|
owner = environment.at_xpath("xmlns:user")
|
65
70
|
if owner
|
66
71
|
feed.owner_login.should == owner.at_xpath("xmlns:login").content
|
@@ -78,7 +83,9 @@ RSpec::Matchers.define :fully_represent_feed do |format, formatted_feed|
|
|
78
83
|
feed.datastreams.each do |ds|
|
79
84
|
data = environment.at_xpath("xmlns:data[@id=\"#{ds.id}\"]")
|
80
85
|
ds.id.should == data.attributes["id"].value
|
81
|
-
|
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
|
82
89
|
current_value = data.at_xpath("xmlns:current_value")
|
83
90
|
ds.current_value.should == current_value.content
|
84
91
|
ds.updated.should == current_value.attributes["at"].value
|
@@ -120,7 +127,9 @@ RSpec::Matchers.define :fully_represent_feed do |format, formatted_feed|
|
|
120
127
|
feed.datastreams.each do |ds|
|
121
128
|
data = environment.at_xpath("xmlns:data[@id=\"#{ds.id}\"]")
|
122
129
|
ds.id.should == data.attributes["id"].value
|
123
|
-
|
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
|
124
133
|
current_value = data.at_xpath("xmlns:value")
|
125
134
|
ds.current_value.should == current_value.content
|
126
135
|
ds.updated.should == environment.attributes["updated"].value
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cosm-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Paul Bellamy
|
@@ -17,12 +17,9 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2012-
|
21
|
-
default_executable:
|
20
|
+
date: 2012-07-10 00:00:00 Z
|
22
21
|
dependencies:
|
23
22
|
- !ruby/object:Gem::Dependency
|
24
|
-
prerelease: false
|
25
|
-
type: :runtime
|
26
23
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
27
24
|
none: false
|
28
25
|
requirements:
|
@@ -34,11 +31,11 @@ dependencies:
|
|
34
31
|
- 8
|
35
32
|
- 1
|
36
33
|
version: 0.8.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
37
36
|
requirement: *id001
|
38
37
|
name: yajl-ruby
|
39
38
|
- !ruby/object:Gem::Dependency
|
40
|
-
prerelease: false
|
41
|
-
type: :runtime
|
42
39
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
43
40
|
none: false
|
44
41
|
requirements:
|
@@ -50,11 +47,11 @@ dependencies:
|
|
50
47
|
- 4
|
51
48
|
- 4
|
52
49
|
version: 1.4.4
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
53
52
|
requirement: *id002
|
54
53
|
name: nokogiri
|
55
54
|
- !ruby/object:Gem::Dependency
|
56
|
-
prerelease: false
|
57
|
-
type: :runtime
|
58
55
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
59
56
|
none: false
|
60
57
|
requirements:
|
@@ -66,12 +63,28 @@ dependencies:
|
|
66
63
|
- 8
|
67
64
|
- 3
|
68
65
|
version: 0.8.3
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
69
68
|
requirement: *id003
|
70
69
|
name: httparty
|
71
70
|
- !ruby/object:Gem::Dependency
|
72
|
-
prerelease: false
|
73
|
-
type: :development
|
74
71
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 121
|
77
|
+
segments:
|
78
|
+
- 1
|
79
|
+
- 5
|
80
|
+
- x
|
81
|
+
version: 1.5.x
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
requirement: *id004
|
85
|
+
name: fastercsv
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
75
88
|
none: false
|
76
89
|
requirements:
|
77
90
|
- - ">="
|
@@ -80,12 +93,12 @@ dependencies:
|
|
80
93
|
segments:
|
81
94
|
- 0
|
82
95
|
version: "0"
|
83
|
-
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
requirement: *id005
|
84
99
|
name: ruby-debug
|
85
100
|
- !ruby/object:Gem::Dependency
|
86
|
-
|
87
|
-
type: :development
|
88
|
-
version_requirements: &id005 !ruby/object:Gem::Requirement
|
101
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
89
102
|
none: false
|
90
103
|
requirements:
|
91
104
|
- - ">="
|
@@ -96,12 +109,12 @@ dependencies:
|
|
96
109
|
- 9
|
97
110
|
- 9
|
98
111
|
version: 0.9.9
|
99
|
-
|
112
|
+
type: :development
|
113
|
+
prerelease: false
|
114
|
+
requirement: *id006
|
100
115
|
name: rcov
|
101
116
|
- !ruby/object:Gem::Dependency
|
102
|
-
|
103
|
-
type: :development
|
104
|
-
version_requirements: &id006 !ruby/object:Gem::Requirement
|
117
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
105
118
|
none: false
|
106
119
|
requirements:
|
107
120
|
- - "="
|
@@ -112,12 +125,12 @@ dependencies:
|
|
112
125
|
- 8
|
113
126
|
- 7
|
114
127
|
version: 0.8.7
|
115
|
-
|
128
|
+
type: :development
|
129
|
+
prerelease: false
|
130
|
+
requirement: *id007
|
116
131
|
name: rake
|
117
132
|
- !ruby/object:Gem::Dependency
|
118
|
-
|
119
|
-
type: :development
|
120
|
-
version_requirements: &id007 !ruby/object:Gem::Requirement
|
133
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
121
134
|
none: false
|
122
135
|
requirements:
|
123
136
|
- - "="
|
@@ -128,7 +141,9 @@ dependencies:
|
|
128
141
|
- 6
|
129
142
|
- 0
|
130
143
|
version: 2.6.0
|
131
|
-
|
144
|
+
type: :development
|
145
|
+
prerelease: false
|
146
|
+
requirement: *id008
|
132
147
|
name: rspec
|
133
148
|
description: A library for communicating with the Cosm REST API, parsing and rendering Cosm feed formats
|
134
149
|
email:
|
@@ -265,7 +280,6 @@ files:
|
|
265
280
|
- spec/support/key_helper.rb
|
266
281
|
- spec/support/search_result_helper.rb
|
267
282
|
- spec/support/trigger_helper.rb
|
268
|
-
has_rdoc: true
|
269
283
|
homepage: http://github.com/cosm/cosm-rb
|
270
284
|
licenses: []
|
271
285
|
|
@@ -296,66 +310,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
296
310
|
requirements: []
|
297
311
|
|
298
312
|
rubyforge_project:
|
299
|
-
rubygems_version: 1.
|
313
|
+
rubygems_version: 1.8.22
|
300
314
|
signing_key:
|
301
315
|
specification_version: 3
|
302
316
|
summary: A library for communicating with the Cosm REST API, parsing and rendering Cosm feed formats
|
303
|
-
test_files:
|
304
|
-
|
305
|
-
- spec/cosm-rb/base/instance_methods_spec.rb
|
306
|
-
- spec/cosm-rb/base_spec.rb
|
307
|
-
- spec/cosm-rb/client_spec.rb
|
308
|
-
- spec/cosm-rb/datapoint_spec.rb
|
309
|
-
- spec/cosm-rb/datastream_spec.rb
|
310
|
-
- spec/cosm-rb/feed_spec.rb
|
311
|
-
- spec/cosm-rb/hash_extensions_spec.rb
|
312
|
-
- spec/cosm-rb/helpers_spec.rb
|
313
|
-
- spec/cosm-rb/key_spec.rb
|
314
|
-
- spec/cosm-rb/parsers/csv/datastream_defaults_spec.rb
|
315
|
-
- spec/cosm-rb/parsers/csv/feed_defaults_spec.rb
|
316
|
-
- spec/cosm-rb/parsers/json/datapoint_defaults_spec.rb
|
317
|
-
- spec/cosm-rb/parsers/json/datastream_defaults_spec.rb
|
318
|
-
- spec/cosm-rb/parsers/json/feed_defaults_spec.rb
|
319
|
-
- spec/cosm-rb/parsers/json/key_defaults_spec.rb
|
320
|
-
- spec/cosm-rb/parsers/json/search_result_defaults_spec.rb
|
321
|
-
- spec/cosm-rb/parsers/json/trigger_defaults_spec.rb
|
322
|
-
- spec/cosm-rb/parsers/xml/datapoint_defaults_spec.rb
|
323
|
-
- spec/cosm-rb/parsers/xml/datastream_defaults_spec.rb
|
324
|
-
- spec/cosm-rb/parsers/xml/feed_defaults_spec.rb
|
325
|
-
- spec/cosm-rb/parsers/xml/key_defaults_spec.rb
|
326
|
-
- spec/cosm-rb/parsers/xml/trigger_defaults_spec.rb
|
327
|
-
- spec/cosm-rb/search_result_spec.rb
|
328
|
-
- spec/cosm-rb/string_extensions_spec.rb
|
329
|
-
- spec/cosm-rb/template_spec.rb
|
330
|
-
- spec/cosm-rb/templates/csv/datapoint_defaults_spec.rb
|
331
|
-
- spec/cosm-rb/templates/csv/datastream_defaults_spec.rb
|
332
|
-
- spec/cosm-rb/templates/csv/feed_defaults_spec.rb
|
333
|
-
- spec/cosm-rb/templates/json/datapoint_defaults_spec.rb
|
334
|
-
- spec/cosm-rb/templates/json/datastream_defaults_spec.rb
|
335
|
-
- spec/cosm-rb/templates/json/feed_defaults_spec.rb
|
336
|
-
- spec/cosm-rb/templates/json/key_defaults_spec.rb
|
337
|
-
- spec/cosm-rb/templates/json/search_result_defaults_spec.rb
|
338
|
-
- spec/cosm-rb/templates/json/trigger_defaults_spec.rb
|
339
|
-
- spec/cosm-rb/templates/xml/datapoint_defaults_spec.rb
|
340
|
-
- spec/cosm-rb/templates/xml/datastream_defaults_spec.rb
|
341
|
-
- spec/cosm-rb/templates/xml/feed_defaults_spec.rb
|
342
|
-
- spec/cosm-rb/templates/xml/search_result_defaults_spec.rb
|
343
|
-
- spec/cosm-rb/trigger_spec.rb
|
344
|
-
- spec/fixtures/models.rb
|
345
|
-
- spec/spec_helper.rb
|
346
|
-
- spec/support/contain_datapoint_eeml_matcher.rb
|
347
|
-
- spec/support/contain_datastream_eeml_matcher.rb
|
348
|
-
- spec/support/contain_feed_eeml_matcher.rb
|
349
|
-
- spec/support/datapoint_helper.rb
|
350
|
-
- spec/support/datastream_helper.rb
|
351
|
-
- spec/support/describe_eeml_matcher.rb
|
352
|
-
- spec/support/feed_helper.rb
|
353
|
-
- spec/support/fully_represent_datapoint_matcher.rb
|
354
|
-
- spec/support/fully_represent_datastream_matcher.rb
|
355
|
-
- spec/support/fully_represent_feed_matcher.rb
|
356
|
-
- spec/support/fully_represent_key_matcher.rb
|
357
|
-
- spec/support/fully_represent_search_result_matcher.rb
|
358
|
-
- spec/support/fully_represent_trigger_matcher.rb
|
359
|
-
- spec/support/key_helper.rb
|
360
|
-
- spec/support/search_result_helper.rb
|
361
|
-
- spec/support/trigger_helper.rb
|
317
|
+
test_files: []
|
318
|
+
|