eoat 0.1.0

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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/.yardopts +8 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +361 -0
  9. data/Rakefile +9 -0
  10. data/eoat.gemspec +37 -0
  11. data/lib/eoat.rb +80 -0
  12. data/lib/eoat/cache/file_cache.rb +109 -0
  13. data/lib/eoat/cache/memcached_cache.rb +54 -0
  14. data/lib/eoat/cache/none_cache.rb +36 -0
  15. data/lib/eoat/cache/redis_cache.rb +61 -0
  16. data/lib/eoat/eve_api.rb +49 -0
  17. data/lib/eoat/exception.rb +63 -0
  18. data/lib/eoat/request.rb +82 -0
  19. data/lib/eoat/result/eve_type.rb +163 -0
  20. data/lib/eoat/version.rb +4 -0
  21. data/lib/eoat/zk_api.rb +33 -0
  22. data/spec/eoat/eve_api_spec.rb +80 -0
  23. data/spec/eoat/eve_result_spec.rb +127 -0
  24. data/spec/eoat/file_cache_spec.rb +29 -0
  25. data/spec/eoat/memcached_cache_spec.rb +14 -0
  26. data/spec/eoat/redis_cache_spec.rb +14 -0
  27. data/spec/eoat/zk_api_spec.rb +55 -0
  28. data/spec/eoat_spec.rb +39 -0
  29. data/spec/fixtures/eve/account/APIKeyInfo.xml.aspx +13 -0
  30. data/spec/fixtures/eve/corp/KillLog.xml.aspx +6 -0
  31. data/spec/fixtures/eve/eve/CertificateTree.xml.aspx +3846 -0
  32. data/spec/fixtures/eve/eve/CharacterInfo.xml.aspx +24 -0
  33. data/spec/fixtures/eve/eve/CharacterName.xml.aspx +11 -0
  34. data/spec/fixtures/eve/eve/ErrorList.xml.aspx +91 -0
  35. data/spec/fixtures/eve/eve/FacWarStats.xml.aspx +31 -0
  36. data/spec/fixtures/eve/eve/FacWarTopStats.xml.aspx +733 -0
  37. data/spec/fixtures/eve/server/ServerStatus.xml.aspx +9 -0
  38. data/spec/fixtures/zkillboard/api-kills-allianceID-99002003-limit-5-xml +1 -0
  39. data/spec/fixtures/zkillboard/api-kills-solo-xml +1 -0
  40. data/spec/spec_helper.rb +86 -0
  41. metadata +259 -0
@@ -0,0 +1,82 @@
1
+ module EOAT
2
+ # Request class. Returns an instance of the class-result from the cache or performs http request.
3
+ # @author Ivan Kotov {mailto:i.s.kotov.ws e-mail}
4
+ # @example Call to get result from https://api.eveonline.com/eve/CharacterInfo.xml.aspx?characterID=208974814
5
+ # EOAT::Request.new(
6
+ # 'https://api.eveonline.com',
7
+ # '/eve/CharacterInfo.xml.aspx?characterID=208974814',
8
+ # EOAT::Result::EveType::Result
9
+ # ).get
10
+ # @return
11
+ # The instance of the class specified in the attributes.
12
+ # @raise
13
+ # [EOAT::Exception::HTTP404Error] the request path not found
14
+ # @raise
15
+ # [EOAT::Exception::HTTPError] response status code is not 200, 404.
16
+ # Contain status code and response headers
17
+ # @raise
18
+ # [EOAT::Exception::EveApiError] if response status code is 0.
19
+ # Contain a parsed error page message and error code
20
+ class Request
21
+
22
+ # @param host [String] the request host string
23
+ # @param uri [String] the request query string
24
+ # @param result_class [Class] the class to contain result of request
25
+ def initialize(host, uri, result_class)
26
+ @host = host
27
+ @uri = uri
28
+ @result = result_class
29
+ end
30
+
31
+ # Method-collector of private methods. Performs basic algorithm of output.
32
+ def get
33
+ cache = cache_get
34
+ if cache
35
+ cache
36
+ else
37
+ result = @result.new(http_request)
38
+ cache_save(result)
39
+ result
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ # HTTP request method. It is used when the data were not obtained from the cache.
46
+ # Uses only global variables and instance variables.
47
+ # @return
48
+ # [Hash, Array] if response body is XML or JSON
49
+ # [String] if response body is HTML
50
+ def http_request
51
+ r = HTTParty.get("#{@host}/#{@uri}", :headers => EOAT.headers)
52
+ case r.response.code.to_i
53
+ when 200
54
+ return r.parsed_response
55
+ when 0
56
+ EOAT::Exception.parse_error_page(r.parsed_response)
57
+ when 404
58
+ raise EOAT::Exception::HTTP404Error.new "Request url path '/#{@uri}' not found"
59
+ else
60
+ raise EOAT::Exception::HTTPError.new(
61
+ r.response.code.to_i,
62
+ r.headers.to_h
63
+ ),
64
+ "Request host '#{@host}' return error: '#{r.response.code} - #{r.response.message}'"
65
+ end
66
+ end
67
+
68
+ # Request cached result from cache handler.
69
+ # If the request is successful, the result will
70
+ # be changed parameter 'from_cache' to true.
71
+ def cache_get
72
+ result = EOAT.cache.get(@host, @uri)
73
+ result.from_cache = true if result
74
+ result
75
+ end
76
+
77
+ # Save parsed result to cache handler.
78
+ def cache_save(content)
79
+ EOAT.cache.save(@host, @uri, content)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,163 @@
1
+ module EOAT
2
+ # Collection of response parser classes
3
+ # @author Ivan Kotov {mailto:i.s.kotov.ws e-mail}
4
+ module Result
5
+ # EveApi XML parser classes.
6
+ # Is used to parse the query result from the EVE API and ZKillboard API
7
+ # @author Ivan Kotov {mailto:i.s.kotov.ws e-mail}
8
+ # @note
9
+ # I'm not proud written below. But I pursued only would it
10
+ # be convenient to use. Thank for this xml structure from EVE API.
11
+ module EveType
12
+ # Parser class of of EVE API xml.
13
+ # Has the structure of the xml root. Starting from ['eveapi']
14
+ # @example
15
+ # eve = EOAT::Result::EveType::Result.new(xml_to_hash)
16
+ # eve.from_cache #=> false
17
+ # @attribute from_cache [FalseClass, TrueClass] Return `true` if data from cache
18
+ # @attribute cached_until [Time] Return `cachedUntil` as time
19
+ # @attribute request_time [Time] Alias to xml `currentTime` as time
20
+ # @attribute result [Array] List of children
21
+ class Result
22
+ attr_accessor :from_cache
23
+ attr_reader :cached_until, :request_time, :result
24
+
25
+ # @param [Hash] hash the xml body parsed to hash
26
+ def initialize(hash)
27
+ hash = hash.key?('eveapi') ? hash['eveapi'] : EOAT::Exception::ParseError.new('Wrong parse data')
28
+ @from_cache = false
29
+ @cached_until = Time.parse(hash['cachedUntil'] + 'UTC')
30
+ @request_time = Time.parse(hash['currentTime'] + 'UTC')
31
+ @result = hash['result'].keys - Array.new(1, 'rowset')
32
+ hash['result'].keys.each do |key|
33
+ value = hash['result'][key]
34
+ case value
35
+ when Hash
36
+ if value.key? 'row'
37
+ var_name = value['name']
38
+ var_value = RowSet.new(value)
39
+ @result << var_name
40
+ else
41
+ var_name = key
42
+ var_value = Row.new(value)
43
+ end
44
+ self.instance_variable_set("@#{var_name}", var_value)
45
+ self.class.send(
46
+ :define_method,
47
+ var_name,
48
+ proc{self.instance_variable_get("@#{var_name}")}
49
+ )
50
+ when Array
51
+ value.each do |v|
52
+ self.instance_variable_set("@#{v['name']}", RowSet.new(v))
53
+ self.class.send(
54
+ :define_method,
55
+ v['name'],
56
+ proc{self.instance_variable_get("@#{v['name']}")}
57
+ )
58
+ @result << v['name']
59
+ end
60
+ when String
61
+ self.instance_variable_set("@#{key}", value)
62
+ self.class.send(
63
+ :define_method,
64
+ key,
65
+ proc{self.instance_variable_get("@#{key}")}
66
+ )
67
+ else
68
+ raise EOAT::Exception::ParseError.new "Unable to parse the the value of #{value}"
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ # Rowset container for xml data.
75
+ # Usually not called directly
76
+ # @attribute key [String] The value of key for indexing
77
+ # @attribute columns [Array] The array of methods names for Row class
78
+ # @attribute name [String] The name of rowset
79
+ # @attribute entries [Array] The array of Row objects
80
+ class RowSet
81
+ attr_accessor :key, :columns, :entries
82
+
83
+ # @param [Hash] hash the roset value from xml as hash
84
+ def initialize(hash)
85
+ @key = hash['key']
86
+ @columns = hash['columns'].split(',')
87
+ @name = hash['name']
88
+ if hash.key? 'row'
89
+ case hash['row']
90
+ when Array
91
+ @entries = Array.new(hash['row'].map.each {|row| Row.new(row)})
92
+ when Hash
93
+ @entries = Array.new(1, Row.new(hash['row']))
94
+ else
95
+ raise EOAT::Exception::ParseError.new "Unable to parse the the value of #{hash['row']}"
96
+ end
97
+ else
98
+ @entries = Array.new
99
+ end
100
+ end
101
+
102
+ # TODO: Correct method. Eliminate return of only the first result.
103
+
104
+ # Get method for entries. Used attribute `key` for indexing.
105
+ # Return first fount Row.
106
+ # @param [Integer, String] key the value that been search
107
+ def get(key)
108
+ @entries.at(@entries.index {|x| x.send(@key) == key.to_s})
109
+ end
110
+ end
111
+
112
+ # Key-values container. All methods generated automatically.
113
+ class Row
114
+
115
+ # @param [Hash] hash the xml row value from xml as hash
116
+ def initialize(hash)
117
+ hash.each do |key, value|
118
+ case value
119
+ when Hash
120
+ if value.key? 'row'
121
+ var_name = value['name']
122
+ var_value = RowSet.new(value)
123
+ else
124
+ var_name = key
125
+ var_value = Row.new(value)
126
+ end
127
+ self.instance_variable_set("@#{var_name}",var_value)
128
+ self.class.send(
129
+ :define_method,
130
+ var_name,
131
+ proc {
132
+ self.instance_variable_get("@#{var_name}")
133
+ }
134
+ )
135
+ when String, NilClass
136
+ self.instance_variable_set("@#{key}", value)
137
+ self.class.send(
138
+ :define_method,
139
+ key,
140
+ proc {
141
+ self.instance_variable_get("@#{key}")
142
+ }
143
+ )
144
+ when Array
145
+ value.each do |element|
146
+ self.instance_variable_set("@#{element['name']}", RowSet.new(element))
147
+ self.class.send(
148
+ :define_method,
149
+ element['name'],
150
+ proc {
151
+ self.instance_variable_get("@#{element['name']}")
152
+ }
153
+ )
154
+ end
155
+ else
156
+ raise EOAT::Exception::ParseError.new "Unable to parse the the key: #{key}, value: #{value.class}; hash: #{hash}."
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,4 @@
1
+ module EOAT
2
+ # Current gem version
3
+ VERSION = '0.1.0'
4
+ end
@@ -0,0 +1,33 @@
1
+ module EOAT
2
+ # ZKApi class - call class. Collects user input, building a url request
3
+ # and passes it to the Request class.
4
+ # @author Ivan Kotov {mailto:i.s.kotov.ws e-mail}
5
+ # @example Get last 10 solo kills
6
+ # solo_kills = EOAT::ZKApi.new('solo').kills(:limit => 10)
7
+ # solo_kills.kills.entries.first.killID #=> "32966816"
8
+ class ZKApi
9
+
10
+ # @param [Array] args the array of request parameters without value
11
+ # @param [String] host the request host, default: https://zkillboard.com
12
+ def initialize(*args, host: 'http://zkillboard.com')
13
+ @host = host
14
+ @uri_part = args.empty? ? '' : '/'.concat(args.join('/'))
15
+ end
16
+
17
+ # Create an request according to the method called.
18
+ # This is used to dynamically create api calls.
19
+ def method_missing(method, **kwargs)
20
+ uri = create_uri(method.id2name, kwargs)
21
+ EOAT::Request.new(@host, uri, EOAT::Result::EveType::Result).get
22
+ end
23
+
24
+ # Collect all request parameters and combine it to query string.
25
+ # @param [String] fake_method the name of missing method
26
+ # @param [Hash] kwargs the keyword arguments
27
+ # @return [String]
28
+ def create_uri(fake_method, **kwargs)
29
+ @uri_part += kwargs ? kwargs.map {|k, v| "/#{k}/#{v}"}.join : ''
30
+ "api/#{fake_method}#{@uri_part}/xml"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe EOAT::EveApi do
4
+ before :each do
5
+ EOAT.cache = EOAT::Cache::NoneCache.new
6
+ end
7
+
8
+ describe 'initialization' do
9
+ it 'can accept empty data to the input' do
10
+ EOAT::EveApi.new
11
+ end
12
+
13
+ it 'takes a key_id, v_code, scope, host as input' do
14
+ EOAT::EveApi.new('keyID', 'vCode', scope: 'account', host: 'http://test.com')
15
+ end
16
+
17
+ it 'takes only scope as input' do
18
+ EOAT::EveApi.new(scope: 'account')
19
+ EOAT::EveApi.new(:scope => 'account')
20
+ end
21
+
22
+ it 'takes only host as input' do
23
+ EOAT::EveApi.new(host: 'http://test.com')
24
+ EOAT::EveApi.new(:host => 'http://test.com')
25
+ end
26
+
27
+ it 'raise an ArgumentError if vCode not specify' do
28
+ expect { EOAT::EveApi.new('test keyID') }.to raise_error ArgumentError
29
+ end
30
+
31
+ let(:v_code) { Symbol 'vCode'}
32
+ it 'raise an ArgumentError if vCode not String' do
33
+ expect { EOAT::EveApi.new('test keyID', :v_code) }.to raise_error ArgumentError
34
+ end
35
+ end
36
+
37
+ describe 'API requests' do
38
+ it 'was return EOAT::Result::EveType::Result class' do
39
+ stub_eve_request('/server/ServerStatus.xml.aspx')
40
+ EOAT::EveApi.new(:scope => 'server').ServerStatus.class.should == EOAT::Result::EveType::Result
41
+ end
42
+
43
+ it 'was accept arguments for the method and return EOAT::Result::EveType::Result class' do
44
+ stub_eve_request('/eve/CharacterInfo.xml.aspx?characterID=208974814')
45
+ EOAT::EveApi.new.CharacterInfo(:characterID => 208974814).class.should == EOAT::Result::EveType::Result
46
+ stub_eve_request('/eve/CharacterName.xml.aspx?IDs=208974814,797400947')
47
+ EOAT::EveApi.new.CharacterName(:IDs => '208974814,797400947').class.should == EOAT::Result::EveType::Result
48
+ end
49
+
50
+ it 'was accept keyID and vCode and return EOAT::Result::EveType::Result class' do
51
+ stub_eve_request('/account/APIKeyInfo.xml.aspx?keyID=123&vCode=test')
52
+ EOAT::EveApi.new(123, 'test', :scope => 'account').APIKeyInfo.key.accessMask.should == '268435455'
53
+ end
54
+
55
+ it 'raise EOAT::Exception::HTTP404Error' do
56
+ stub_request(
57
+ :get,
58
+ 'https://api.eveonline.com/eve/Characters.xml.aspx?keyID=123&vCode=test'
59
+ ).with(
60
+ :headers => EOAT.headers
61
+ ).to_return(:status => 404, :body => '', :headers => {})
62
+ expect { EOAT::EveApi.new(123, 'test').Characters }.to raise_error EOAT::Exception::HTTP404Error
63
+ end
64
+
65
+ it 'raise EOAT::Exception::HTTPError' do
66
+ stub_request(
67
+ :get,
68
+ 'https://api.eveonline.com/account/Characters.xml.aspx?keyID=123&vCode=test'
69
+ ).with(
70
+ :headers => EOAT.headers
71
+ ).to_return(:status => 403, :body => '', :headers => {})
72
+ expect { EOAT::EveApi.new(123, 'test', :scope => 'account').Characters }.to raise_error EOAT::Exception::HTTPError
73
+ end
74
+
75
+ it 'raise EOAT::Exception::EveApiError' do
76
+ stub_eve_request('/corp/KillLog.xml.aspx?keyID=123&vCode=test', 0)
77
+ expect { EOAT::EveApi.new(123, 'test', :scope => 'corp').KillLog }.to raise_error EOAT::Exception::EveApiError
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,127 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe EOAT::Result::EveType::Result do
4
+ before :each do
5
+ EOAT.cache = EOAT::Cache::NoneCache.new
6
+ end
7
+
8
+ it 'should have the Result->RowSet->Row classes structure' do
9
+ stub_eve_request('/eve/ErrorList.xml.aspx')
10
+ response = EOAT::EveApi.new.ErrorList
11
+ response.class.should == EOAT::Result::EveType::Result
12
+ response.result.class.should == Array
13
+ response.errors.class.should == EOAT::Result::EveType::RowSet
14
+ response.errors.entries.class.should == Array
15
+ response.errors.entries.first.class.should == EOAT::Result::EveType::Row
16
+ end
17
+
18
+ it 'should have the Result->RowSet->Row->RowSet->Row->RowSet->Row classes structure' do
19
+ stub_eve_request('/eve/CertificateTree.xml.aspx')
20
+ response = EOAT::EveApi.new.CertificateTree
21
+ response.class.should == EOAT::Result::EveType::Result
22
+ response.result.class.should == Array
23
+ response.categories.class.should == EOAT::Result::EveType::RowSet
24
+ response.categories.columns.class.should == Array
25
+ category = response.categories.entries.first
26
+ category.class.should == EOAT::Result::EveType::Row
27
+ category.categoryID.class.should == String
28
+ category.categoryName.class.should == String
29
+ category.classes.class.should == EOAT::Result::EveType::RowSet
30
+ category.classes.columns.class.should == Array
31
+ category.classes.entries.class.should == Array
32
+ classe = category.classes.entries.first
33
+ classe.class.should == EOAT::Result::EveType::Row
34
+ classe.classID.class.should == String
35
+ classe.className.class.should == String
36
+ classe.certificates.class.should == EOAT::Result::EveType::RowSet
37
+ classe.certificates.columns.class == Array
38
+ certificate = classe.certificates.entries.first
39
+ certificate.class.should == EOAT::Result::EveType::Row
40
+ certificate.certificateID.class.should == String
41
+ certificate.grade.class.should == String
42
+ certificate.corporationID.class.should == String
43
+ certificate.description.class.should == String
44
+ certificate.requiredSkills.class.should == EOAT::Result::EveType::RowSet
45
+ certificate.requiredSkills.entries.class == Array
46
+ certificate.requiredCertificates.class.should == EOAT::Result::EveType::RowSet
47
+ certificate.requiredCertificates.entries.class == Array
48
+ certificate.requiredSkills.entries.first.class.should == EOAT::Result::EveType::Row
49
+ certificate.requiredCertificates.entries.size.should == 0
50
+ end
51
+
52
+ it 'should have Result->(Row,RowSets)->Row structure' do
53
+ stub_eve_request('/eve/FacWarStats.xml.aspx')
54
+ factions_wars = EOAT::EveApi.new.FacWarStats
55
+ factions_wars.result.class.should == Array
56
+ factions_wars.totals.class.should == EOAT::Result::EveType::Row
57
+ factions_wars.factions.class.should == EOAT::Result::EveType::RowSet
58
+ factions_wars.factions.entries.class.should == Array
59
+ factions_wars.factions.entries.first.class.should == EOAT::Result::EveType::Row
60
+ factions_wars.factionWars.class.should == EOAT::Result::EveType::RowSet
61
+ factions_wars.factionWars.entries.class.should == Array
62
+ factions_wars.factionWars.entries.first.class.should == EOAT::Result::EveType::Row
63
+ end
64
+
65
+ it 'should have Result->Row->RowSets->Row structure' do
66
+ stub_eve_request('/eve/FacWarTopStats.xml.aspx')
67
+ stats = EOAT::EveApi.new.FacWarTopStats
68
+ stats.result.class.should == Array
69
+ stats.characters.class.should == EOAT::Result::EveType::Row
70
+ stats.characters.KillsYesterday.class.should == EOAT::Result::EveType::RowSet
71
+ stats.characters.KillsYesterday.entries.class.should == Array
72
+ stats.characters.KillsYesterday.entries.first.class.should == EOAT::Result::EveType::Row
73
+ stats.characters.KillsLastWeek.class.should == EOAT::Result::EveType::RowSet
74
+ stats.characters.KillsLastWeek.entries.class.should == Array
75
+ stats.characters.KillsLastWeek.entries.first.class.should == EOAT::Result::EveType::Row
76
+ stats.characters.KillsTotal.class.should == EOAT::Result::EveType::RowSet
77
+ stats.characters.KillsTotal.entries.class.should == Array
78
+ stats.characters.KillsTotal.entries.first.class.should == EOAT::Result::EveType::Row
79
+ stats.characters.VictoryPointsYesterday.class.should == EOAT::Result::EveType::RowSet
80
+ stats.characters.VictoryPointsYesterday.entries.class.should == Array
81
+ stats.characters.VictoryPointsYesterday.entries.first.class.should == EOAT::Result::EveType::Row
82
+ stats.characters.VictoryPointsLastWeek.class.should == EOAT::Result::EveType::RowSet
83
+ stats.characters.VictoryPointsLastWeek.entries.class.should == Array
84
+ stats.characters.VictoryPointsLastWeek.entries.first.class.should == EOAT::Result::EveType::Row
85
+ stats.characters.VictoryPointsTotal.class.should == EOAT::Result::EveType::RowSet
86
+ stats.characters.VictoryPointsTotal.entries.class.should == Array
87
+ stats.characters.VictoryPointsTotal.entries.first.class.should == EOAT::Result::EveType::Row
88
+ stats.corporations.class.should == EOAT::Result::EveType::Row
89
+ stats.corporations.KillsYesterday.class.should == EOAT::Result::EveType::RowSet
90
+ stats.corporations.KillsYesterday.entries.class.should == Array
91
+ stats.corporations.KillsYesterday.entries.first.class.should == EOAT::Result::EveType::Row
92
+ stats.corporations.KillsLastWeek.class.should == EOAT::Result::EveType::RowSet
93
+ stats.corporations.KillsLastWeek.entries.class.should == Array
94
+ stats.corporations.KillsLastWeek.entries.first.class.should == EOAT::Result::EveType::Row
95
+ stats.corporations.KillsTotal.class.should == EOAT::Result::EveType::RowSet
96
+ stats.corporations.KillsTotal.entries.class.should == Array
97
+ stats.corporations.KillsTotal.entries.first.class.should == EOAT::Result::EveType::Row
98
+ stats.corporations.VictoryPointsYesterday.class.should == EOAT::Result::EveType::RowSet
99
+ stats.corporations.VictoryPointsYesterday.entries.class.should == Array
100
+ stats.corporations.VictoryPointsYesterday.entries.first.class.should == EOAT::Result::EveType::Row
101
+ stats.corporations.VictoryPointsLastWeek.class.should == EOAT::Result::EveType::RowSet
102
+ stats.corporations.VictoryPointsLastWeek.entries.class.should == Array
103
+ stats.corporations.VictoryPointsLastWeek.entries.first.class.should == EOAT::Result::EveType::Row
104
+ stats.corporations.VictoryPointsTotal.class.should == EOAT::Result::EveType::RowSet
105
+ stats.corporations.VictoryPointsTotal.entries.class.should == Array
106
+ stats.corporations.VictoryPointsTotal.entries.first.class.should == EOAT::Result::EveType::Row
107
+ stats.factions.class.should == EOAT::Result::EveType::Row
108
+ stats.factions.KillsYesterday.class.should == EOAT::Result::EveType::RowSet
109
+ stats.factions.KillsYesterday.entries.class.should == Array
110
+ stats.factions.KillsYesterday.entries.first.class.should == EOAT::Result::EveType::Row
111
+ stats.factions.KillsLastWeek.class.should == EOAT::Result::EveType::RowSet
112
+ stats.factions.KillsLastWeek.entries.class.should == Array
113
+ stats.factions.KillsLastWeek.entries.first.class.should == EOAT::Result::EveType::Row
114
+ stats.factions.KillsTotal.class.should == EOAT::Result::EveType::RowSet
115
+ stats.factions.KillsTotal.entries.class.should == Array
116
+ stats.factions.KillsTotal.entries.first.class.should == EOAT::Result::EveType::Row
117
+ stats.factions.VictoryPointsYesterday.class.should == EOAT::Result::EveType::RowSet
118
+ stats.factions.VictoryPointsYesterday.entries.class.should == Array
119
+ stats.factions.VictoryPointsYesterday.entries.first.class.should == EOAT::Result::EveType::Row
120
+ stats.factions.VictoryPointsLastWeek.class.should == EOAT::Result::EveType::RowSet
121
+ stats.factions.VictoryPointsLastWeek.entries.class.should == Array
122
+ stats.factions.VictoryPointsLastWeek.entries.first.class.should == EOAT::Result::EveType::Row
123
+ stats.factions.VictoryPointsTotal.class.should == EOAT::Result::EveType::RowSet
124
+ stats.factions.VictoryPointsTotal.entries.class.should == Array
125
+ stats.factions.VictoryPointsTotal.entries.first.class.should == EOAT::Result::EveType::Row
126
+ end
127
+ end