kat 0.1.3 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1666db6fd7cf5f49236cfea2499c32073800ccc0
4
- data.tar.gz: a6c24a63dcc968c552804ed7a22005defd63e86b
3
+ metadata.gz: 6431728ef307439d3dff0b3f60e3619c0ae4d37c
4
+ data.tar.gz: 914cef06e731347f85c4c8ba9c5363711d134e4a
5
5
  SHA512:
6
- metadata.gz: 249bcc1134cd966ebaa3ace2ebb91d4cbc538366205588f764562cff82f270878b63a37b01c7596e431f0076a3b20585d84bdc32008eebf634b2dd43a2dea246
7
- data.tar.gz: 3acb8c04eb256cb39ed597743d9ebe9f38dc1db756e2d2c79184b308094276e7908ff32d496a3fd971c2621854631e987781af110c1acc89a35183eeb13cec04
6
+ metadata.gz: d64ef6998d9d27411680c8aa08e42d6cf5d15dbe33a82122a9ede9ba04c75841e24a93b98c126207beadd3713e4d7102c67ccbd5fdd0411b716011050ed33030
7
+ data.tar.gz: 7ec114ce7cf00ca98b9d94345c8cc1b6dbaf3aaf812334146fe58ae7e84f224cb92ec677c3e948d4593939e17d4058d3c4c11b967a75317fac8baa133668aa56
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in kat.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'rake'
8
+ end
data/LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2013 Fission Xuiptz
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of
6
- this software and associated documentation files (the "Software"), to deal in
7
- the Software without restriction, including without limitation the rights to
8
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
- the Software, and to permit persons to whom the Software is furnished to do so,
10
- subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Fission Xuiptz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ task :default => :test
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs.push 'lib'
8
+ t.test_files = FileList['test/*_test.rb']
9
+ end
data/lib/kat.rb CHANGED
@@ -1,60 +1,109 @@
1
- # TODO: Implement field sort and sort order
2
- # Lookup advanced search for language and platform values
3
- # Comments
4
- # Tests
1
+ # TODO: Lookup advanced search for language and platform values
5
2
 
6
3
  require 'nokogiri'
7
4
  require 'open-uri'
8
5
 
9
6
  class Kat
10
7
  KAT_URL = 'http://kickass.to'
11
- SEARCH_URL = "#{KAT_URL}/usearch/"
8
+ EMPTY_URL = "new"
9
+ SEARCH_URL = "usearch"
12
10
  ADVANCED_URL = "#{KAT_URL}/torrents/search/advanced/"
13
11
 
14
12
  STRING_FIELDS = [ :category, :seeds, :user, :age, :files, :imdb, :season, :episode ]
13
+
14
+ # The names of these fields are transposed for ease of use
15
15
  SELECT_FIELDS = [ { :name => :language, :id => :lang_id }, { :name => :platform, :id => :platform_id } ]
16
+
17
+ # If these are set to anything but nil or false, they're turned on in the query
16
18
  SWITCH_FIELDS = [ :safe, :verified ]
17
19
 
18
- attr_reader :results, :pages, :error
20
+ SORT_FIELDS = %w(size files_count time_add seeders leechers)
21
+
22
+ # The number of pages of results
23
+ attr_reader :pages
24
+
25
+ # Any error in searching is stored here
26
+ attr_reader :error
19
27
 
28
+ #
29
+ # Create a new +Kat+ object to search Kickass Torrents.
30
+ #
31
+ # The search term can be nil, a string/symbol, or an array of strings/symbols.
32
+ #
33
+ # Valid options are in STRING_FIELDS, SELECT_FIELDS or SWITCH_FIELDS
34
+ #
20
35
  def initialize search_term = nil, opts = {}
21
36
  @search_term = []
22
37
  @options = opts.is_a?(Hash) ? opts : {}
23
38
  self.query = search_term.is_a?(Array) ? search_term.dup : search_term
24
39
  end
25
40
 
41
+ #
42
+ # Use Kat.search(search_term) to do a quick search
43
+ #
26
44
  def self.search search_term
27
45
  self.new(search_term).search
28
46
  end
29
47
 
48
+ #
49
+ # Generate a query string from the stored options, supplying an optional page number
50
+ #
30
51
  def query page = 0
31
- @query.join(' ').gsub(/[^a-z0-9: _-]/i, '') + (page > 0 ? "/#{page + 1}" : '') + (@query.empty? ? '' : '/')
52
+ q = [ SEARCH_URL, @query.join(' ').gsub(/[^a-z0-9: _-]/i, '') ]
53
+ q = [ EMPTY_URL ] if q[1].empty?
54
+ q << page + 1 if page > 0
55
+ q << if SORT_FIELDS.include? @options[:sort].to_s
56
+ "?field=#{options[:sort].to_s}&sorder=#{options[:asc] ? 'asc' : 'desc'}"
57
+ else
58
+ '' # ensure a trailing slash after the search terms or page number
59
+ end
60
+ q.join '/'
32
61
  end
33
62
 
63
+ #
64
+ # Change the search term for the query, triggering a rebuild of the query string
65
+ # and clearing past results.
66
+ #
67
+ # Raises ArgumentError if search_term is not a String, Symbol or Array
68
+ #
34
69
  def query= search_term
35
70
  @search_term = case search_term
36
- when nil then []
37
- when String then [ search_term ]
38
- when Array then search_term.flatten.select {|el| el.is_a? String }
39
- else raise ArgumentError, "search_term must be a String or Array object. #{search_term.inspect} given."
71
+ when nil then []
72
+ when String, Symbol then [ search_term ]
73
+ when Array then search_term.flatten.select {|el| [ String, Symbol ].include? el.class }
74
+ else raise ArgumentError, "search_term must be a String, Symbol or Array. #{search_term.inspect} given."
40
75
  end
41
76
  build_query
42
77
  end
43
78
 
79
+ #
80
+ # Get a copy of the search options hash
81
+ #
44
82
  def options
45
83
  @options.dup
46
84
  end
47
85
 
86
+ #
87
+ # Change search options with a hash, triggering a rebuild of the query string and
88
+ # clearing past results.
89
+ #
90
+ # Raises ArgumentError if opts is not a Hash
91
+ #
48
92
  def options= opts
49
- raise ArgumentError, "opts must be a Hash object. #{opts.inspect} given." unless opts.is_a? Hash
93
+ raise ArgumentError, "opts must be a Hash. #{opts.inspect} given." unless opts.is_a? Hash
50
94
  @options.merge! opts
51
95
  build_query
52
96
  end
53
97
 
98
+ #
99
+ # Perform the search, supplying an optional page number to search on. Returns
100
+ # a result set limited to the 25 results Kickass Torrents returns itself. Will
101
+ # cache results for subsequent calls of search with the same query string.
102
+ #
54
103
  def search page = 0
55
- unless query.empty? or @results[page] or (@pages > 0 and page >= @pages)
104
+ unless query.empty? or @results[page] or (@pages > -1 and page >= @pages)
56
105
  begin
57
- doc = Nokogiri::HTML(open("#{SEARCH_URL}#{URI::encode(query page)}"))
106
+ doc = Nokogiri::HTML(open("#{KAT_URL}/#{URI::encode(query page)}"))
58
107
  @results[page] = doc.css('td.torrentnameCell').map do |node|
59
108
  { :title => node.css('a.normalgrey').text,
60
109
  :magnet => node.css('a.imagnet').first.attributes['href'].value,
@@ -65,30 +114,55 @@ class Kat
65
114
  :seeds => (node = node.next_element).text.to_i,
66
115
  :leeches => (node = node.next_element).text.to_i }
67
116
  end
68
- @pages = doc.css('div.pages > a').last.text.to_i if @pages == 0
69
- @pages = 1 if @pages == 0
117
+
118
+ # If we haven't previously performed a search with this query string, get the
119
+ # number of pages from the pagination bar at the bottom of the results page.
120
+ @pages = doc.css('div.pages > a').last.text.to_i if @pages < 0
121
+
122
+ # If there was no pagination bar and the previous statement didn't trigger
123
+ # a NoMethodError, there are results but only 1 page worth.
124
+ @pages = 1 if @pages <= 0
125
+ rescue NoMethodError
126
+ # The results page had no pagination bar, but did return some results.
127
+ @pages = 1
70
128
  rescue => e
71
- if e.name == :text
72
- @pages = 1
73
- else
74
- @error = { :error => e, :query => query(page) }
75
- end
129
+ # No result throws a 404 error.
130
+ @pages = 0 if e.class == OpenURI::HTTPError and e.message['404 Not Found']
131
+ @error = { :error => e, :query => query(page) }
76
132
  end
77
133
  end
78
134
 
79
- @results[page]
135
+ results[page]
136
+ end
137
+
138
+ #
139
+ # Get a copy of the results
140
+ #
141
+ def results
142
+ @results.dup
80
143
  end
81
144
 
145
+ #
146
+ # If the method_sym or its plural is a field name in the results list, this will tell us
147
+ # if we can fetch the list of values. It'll only happen after a successful search.
148
+ #
82
149
  def respond_to? method_sym, include_private = false
83
- return true if not @results.empty? and (@results.last.first[method_sym] or @results.last.first[method_sym.to_s.chop.to_sym])
150
+ if not (@results.empty? or @results.last.empty?) and
151
+ (@results.last.first[method_sym] or @results.last.first[method_sym.to_s.chop.to_sym])
152
+ return true
153
+ end
84
154
  super
85
155
  end
86
156
 
87
157
  private
88
158
 
159
+ #
160
+ # Clear out the query and rebuild it from the various stored options. Also clears out the
161
+ # results set and sets pages back to -1
162
+ #
89
163
  def build_query
90
164
  @query = @search_term.dup
91
- @pages = 0
165
+ @pages = -1
92
166
  @results = []
93
167
 
94
168
  @query << "\"#{@options[:exact]}\"" if @options[:exact]
@@ -100,13 +174,18 @@ private
100
174
  SWITCH_FIELDS.each {|f| @query << "#{f}:1" if @options[f] }
101
175
  end
102
176
 
177
+ #
178
+ # If method_sym or its plural form is a field name in the results list, fetch the list of values.
179
+ # Can only happen after a successful search.
180
+ #
103
181
  def method_missing method_sym, *arguments, &block
182
+ # Don't need no fancy schmancy pluralizing method. Just try chopping off the 's'.
104
183
  m = method_sym.to_s.chop.to_sym
105
- if not @results.empty? and (@results.last.first[method_sym] or @results.last.first[m])
106
- @results.compact.map {|rs| rs.map {|r| r[method_sym] || r[m] } }.flatten
107
- else
108
- super
184
+ if not (@results.empty? or @results.last.empty?) and
185
+ (@results.last.first[method_sym] or @results.last.first[m])
186
+ return @results.compact.map {|rs| rs.map {|r| r[method_sym] || r[m] } }.flatten
109
187
  end
188
+ super
110
189
  end
111
190
 
112
191
  end
@@ -1,3 +1,3 @@
1
1
  class Kat
2
- VERSION = '0.1.3'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1,256 @@
1
+ require 'minitest/autorun'
2
+
3
+ begin
4
+ require 'minitest/pride'
5
+ rescue LoadError
6
+ end
7
+
8
+ require 'kat'
9
+
10
+ describe Kat do
11
+ before do
12
+ @kat = { :vanilla => Kat.new,
13
+ :basic => Kat.new('test'),
14
+ :advanced => Kat.new('test', { :category => 'books' }) }
15
+ end
16
+
17
+ # Quick search tests
18
+
19
+ describe 'when quick searching' do
20
+ it 'returns a result set' do
21
+ Kat.search('test').must_be_instance_of Array
22
+ Kat.search('test').size.must_equal 25
23
+ end
24
+ end
25
+
26
+ # Vanilla query tests
27
+
28
+ describe 'when checking if a vanilla query responds to result field before searching' do
29
+ it 'returns false' do
30
+ [ :titles, :magnets, :downloads, :sizes, :files, :ages, :seeds, :leeches ].each do |s|
31
+ @kat[:vanilla].respond_to?(s).must_equal false
32
+ end
33
+ end
34
+ end
35
+
36
+ describe 'when checking if a vanilla query responds to result fields after searching' do
37
+ it 'returns true' do
38
+ @kat[:vanilla].search
39
+ [ :titles, :magnets, :downloads, :sizes, :files, :ages, :seeds, :leeches ].each do |s|
40
+ @kat[:vanilla].respond_to?(s).must_equal true
41
+ end
42
+ end
43
+ end
44
+
45
+ describe 'when building a vanilla query' do
46
+ it 'returns a query to new torrents' do
47
+ @kat[:vanilla].query.must_equal 'new/'
48
+ end
49
+ end
50
+
51
+ describe 'when searching with a vanilla query' do
52
+ it 'returns a full result set' do
53
+ @kat[:vanilla].search.must_be_instance_of Array
54
+ [ :search, :titles, :magnets, :downloads, :sizes, :files, :ages, :seeds, :leeches ].each do |s|
55
+ @kat[:vanilla].send(s).size.must_equal 25
56
+ end
57
+ end
58
+ end
59
+
60
+ describe 'when searching the 2nd page of a vanilla query' do
61
+ it 'returns a full result set' do
62
+ @kat[:vanilla].search(1).must_be_instance_of Array
63
+ @kat[:vanilla].search(1).size.must_equal 25
64
+ end
65
+ end
66
+
67
+ describe 'when searching 2 pages of a vanilla query' do
68
+ it 'returns 50 results for each result field' do
69
+ @kat[:vanilla].search
70
+ @kat[:vanilla].search(1)
71
+ if @kat[:vanilla].respond_to? :titles
72
+ [ :titles, :magnets, :downloads, :sizes, :files, :ages, :seeds, :leeches ].each do |s|
73
+ @kat[:vanilla].send(s).size.must_equal 50
74
+ end
75
+ else
76
+ # Returning a failure, not an error
77
+ proc { @kat[:vanilla].titles }.wont_raise NoMethodError
78
+ end
79
+ end
80
+ end
81
+
82
+ describe 'when rebuilding a vanilla query' do
83
+ it 'returns a query to new torrents' do
84
+ @kat[:vanilla].query = nil
85
+ @kat[:vanilla].query.must_equal 'new/'
86
+ end
87
+ end
88
+
89
+ describe 'when changing the search term on a vanilla query' do
90
+ it 'returns a query to usearch' do
91
+ @kat[:vanilla].query = 'test'
92
+ @kat[:vanilla].query.must_equal 'usearch/test/'
93
+ end
94
+ end
95
+
96
+ describe 'when adding an array of search terms to a vanilla query' do
97
+ it 'returns a query to usearch' do
98
+ @kat[:vanilla].query = [ 'test', 'category:books' ]
99
+ @kat[:vanilla].query.must_equal 'usearch/test category:books/'
100
+ end
101
+ end
102
+
103
+ describe 'when adding an array of crap to a vanilla query' do
104
+ it 'returns a valid query' do
105
+ @kat[:vanilla].query = [ 0, {}, [ 'test', 0..1 ] ]
106
+ @kat[:vanilla].query.must_equal 'usearch/test/'
107
+ end
108
+ end
109
+
110
+ # Basic query tests
111
+
112
+ describe 'when checking if a basic query responds to result fields after searching' do
113
+ it 'returns true' do
114
+ @kat[:basic].search
115
+ [ :titles, :magnets, :downloads, :sizes, :files, :ages, :seeds, :leeches ].each do |s|
116
+ @kat[:basic].respond_to?(s).must_equal true
117
+ end
118
+ end
119
+ end
120
+
121
+ describe 'when building a basic query' do
122
+ it 'returns a query to usearch' do
123
+ @kat[:basic].query.must_equal 'usearch/test/'
124
+ end
125
+ end
126
+
127
+ describe 'when building a basic query with pages' do
128
+ it 'returns a query to usearch with page numbers' do
129
+ @kat[:basic].query(1).must_equal 'usearch/test/2/'
130
+ end
131
+ end
132
+
133
+ describe 'when changing the search term of a basic query to nil' do
134
+ it 'returns a query to new' do
135
+ @kat[:basic].query = nil
136
+ @kat[:basic].query.must_equal 'new/'
137
+ end
138
+ end
139
+
140
+ describe 'when adding options to a basic query' do
141
+ it 'returns a query to usearch with options' do
142
+ @kat[:basic].options = { :category => 'movies' }
143
+ @kat[:basic].options.must_equal({ :category => 'movies' })
144
+ @kat[:basic].query.must_equal 'usearch/test category:movies/'
145
+ @kat[:basic].results.must_be_empty
146
+ @kat[:basic].pages.must_be :==, -1
147
+ end
148
+ end
149
+
150
+ describe 'when adding options to a basic query with pages' do
151
+ it 'returns a query to usearch with options and page numbers' do
152
+ @kat[:basic].options = { :category => 'movies' }
153
+ @kat[:basic].options.must_equal({ :category => 'movies' })
154
+ @kat[:basic].query(1).must_equal 'usearch/test category:movies/2/'
155
+ @kat[:basic].results.must_be_empty
156
+ @kat[:basic].pages.must_be :==, -1
157
+ end
158
+ end
159
+
160
+ describe 'when searching with a basic query' do
161
+ it 'returns a result set' do
162
+ @kat[:basic].search.must_be_instance_of Array
163
+ @kat[:basic].search.size.must_equal 25
164
+ @kat[:basic].pages.must_be :>, 0
165
+ end
166
+ end
167
+
168
+ describe 'when searching the 2nd page of a basic query' do
169
+ it 'returns a result set' do
170
+ @kat[:basic].search(1).must_be_instance_of Array
171
+ @kat[:basic].search(1).size.must_equal 25
172
+ @kat[:basic].pages.must_be :>, 0
173
+ end
174
+ end
175
+
176
+ describe 'when searching with the same basic query twice' do
177
+ it 'returns the same result set' do
178
+ @kat[:basic].search.must_equal @kat[:basic].search
179
+ end
180
+ end
181
+
182
+ describe 'when searching for something that does not exist in a basic query' do
183
+ it 'returns an empty set, sets an error and sets pages to 0' do
184
+ @kat[:basic].query = 'owijefbvoweivf'
185
+ @kat[:basic].search.must_be_nil
186
+ @kat[:basic].error.must_be_instance_of Hash
187
+ @kat[:basic].error[:error].must_be_instance_of OpenURI::HTTPError
188
+ @kat[:basic].error[:error].message.must_equal '404 Not Found'
189
+ @kat[:basic].pages.must_equal 0
190
+ end
191
+ end
192
+
193
+ describe 'when searching for something with 1 page of results in a basic query' do
194
+ it 'returns a result set and sets the pages to 1' do
195
+ @kat[:basic].options = { :category => 'wallpapers' }
196
+ @kat[:basic].options.must_equal({ :category => 'wallpapers' })
197
+ @kat[:basic].search.wont_be_nil
198
+ @kat[:basic].search.size.wont_equal 0
199
+ end
200
+ end
201
+
202
+ describe 'when passing query= a Symbol' do
203
+ it 'works just like a String' do
204
+ @kat[:basic].query = :test
205
+ @kat[:basic].query.must_equal 'usearch/test/'
206
+ end
207
+ end
208
+
209
+ describe 'when passing a non-String-or-Array object to query=' do
210
+ it 'raises an ArgumentError' do
211
+ proc { @kat[:basic].query = { :foo => 'bar' } }.must_raise ArgumentError
212
+ end
213
+ end
214
+
215
+ describe 'when passing a non-Hash object to options=' do
216
+ it 'raises an ArgumentError' do
217
+ proc { @kat[:basic].options = 'foobar' }.must_raise ArgumentError
218
+ end
219
+ end
220
+
221
+ # Advanced query tests
222
+
223
+ describe 'when building an advanced query' do
224
+ it 'returns a query with options to usearch' do
225
+ @kat[:advanced].query.must_equal 'usearch/test category:books/'
226
+ end
227
+ end
228
+
229
+ describe 'when building an advanced query with pages' do
230
+ it 'returns a query with options and page numbers' do
231
+ @kat[:advanced].query(1).must_equal 'usearch/test category:books/2/'
232
+ end
233
+ end
234
+
235
+ describe 'when building an advanced query with select fields' do
236
+ it 'returns a query with options to usearch' do
237
+ @kat[:advanced].options = { :language => 2 }
238
+ @kat[:advanced].query.must_equal 'usearch/test category:books lang_id:2/'
239
+ end
240
+ end
241
+
242
+ describe 'when using symbols instead of strings in an advanced query' do
243
+ it 'returns the same query string' do
244
+ @kat[:advanced].options = { :category => :books }
245
+ @kat[:advanced].query.must_equal 'usearch/test category:books/'
246
+ end
247
+ end
248
+
249
+ describe 'when sorting fields' do
250
+ it 'adds a sort part to the query string' do
251
+ @kat[:advanced].options = { :sort => :size }
252
+ @kat[:advanced].query.must_equal 'usearch/test category:books/?field=size&sorder=desc'
253
+ end
254
+ end
255
+
256
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fission Xuiptz
@@ -31,6 +31,7 @@ extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
33
  - .gitignore
34
+ - .travis.yml
34
35
  - Gemfile
35
36
  - LICENSE
36
37
  - README.md
@@ -38,6 +39,7 @@ files:
38
39
  - kat.gemspec
39
40
  - lib/kat.rb
40
41
  - lib/kat/version.rb
42
+ - test/kat_test.rb
41
43
  homepage: http://github.com/fissionxuiptz/kat
42
44
  licenses:
43
45
  - MIT
@@ -62,4 +64,5 @@ rubygems_version: 2.0.3
62
64
  signing_key:
63
65
  specification_version: 4
64
66
  summary: Kickass Torrents Interface
65
- test_files: []
67
+ test_files:
68
+ - test/kat_test.rb