eoat 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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