randumb 0.2.0 → 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.
data/lib/randumb.rb CHANGED
@@ -1,54 +1,13 @@
1
- require 'active_support/core_ext/module/delegation'
2
- require 'active_record/relation'
3
-
4
- module Randumb
5
- # https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/query_methods.rb
6
- module ActiveRecord
7
-
8
- module Relation
9
-
10
- def random(max_items = nil)
11
- return_first_record = max_items.nil? # see return switch at end
12
- max_items ||= 1
13
- relation = clone
14
-
15
- if connection.adapter_name =~ /sqlite/i || connection.adapter_name =~ /postgres/i
16
- rand_syntax = "RANDOM()"
17
- elsif connection.adapter_name =~ /mysql/i
18
- rand_syntax = "RAND()"
19
- else
20
- raise Exception, "ActiveRecord adapter: '#{connection.adapter_name}' not supported by randumb. Send a pull request or open a ticket: https://github.com/spilliton/randumb"
21
- end
22
-
23
- the_scope = relation.order(rand_syntax)
24
- the_scope = the_scope.limit(max_items) unless relation.limit_value && relation.limit_value < max_items
25
-
26
- # return first record if method was called without parameters
27
- if return_first_record
28
- the_scope.first
29
- else
30
- the_scope.all
31
- end
32
- end
33
-
34
- end # Relation
35
-
36
- module Base
37
- # Class method
38
- def random(max_items = nil)
39
- relation.random(max_items)
40
- end
41
- end
42
-
43
-
44
- end # ActiveRecord
45
- end # Randumb
1
+ require 'randumb/version'
2
+ require 'randumb/relation'
46
3
 
47
4
  # Mix it in
48
5
  class ActiveRecord::Relation
49
6
  include Randumb::ActiveRecord::Relation
7
+ include Randumb::ActiveRecord::MethodMissingMagicks
50
8
  end
51
9
 
52
10
  class ActiveRecord::Base
53
11
  extend Randumb::ActiveRecord::Base
12
+ extend Randumb::ActiveRecord::MethodMissingMagicks
54
13
  end
@@ -0,0 +1,160 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+ require 'active_record/relation'
3
+
4
+ module Randumb
5
+ # https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/query_methods.rb
6
+ module ActiveRecord
7
+
8
+ module Relation
9
+
10
+ # If the max_items argument is omitted, one random entity will be returned.
11
+ # If you provide the integer argument, you will get back an array of records.
12
+ def random(max_items = nil)
13
+ random_weighted(nil, max_items)
14
+ end
15
+
16
+ # If ranking_column is provided, that named column wil be multiplied
17
+ # by a random number to determine probability of order. The ranking column must be numeric.
18
+ def random_weighted(ranking_column, max_items = nil)
19
+ relation = clone
20
+
21
+ # postgres won't let you do an order_by when also doing a distinct
22
+ # let's just use the in-memory option in this case
23
+ if relation.uniq_value && connection.adapter_name =~ /postgres/i
24
+ if ranking_column
25
+ raise Exception, "random_weighted: not possible when using .uniq and the postgres db adapter"
26
+ else
27
+ return random_by_id_shuffle(max_items)
28
+ end
29
+ end
30
+
31
+ # ensure a valid column for ranking
32
+ if ranking_column
33
+ column_data = @klass.columns_hash[ranking_column.to_s]
34
+ raise ArgumentError.new("random_weighted: #{ranking_column} is not a column on #{@klass.table_name}!") unless column_data
35
+ raise ArgumentError.new("random_weighted: #{ranking_column} is not a numeric column on #{@klass.table_name}!") unless [:integer, :float].include?(column_data.type)
36
+ end
37
+
38
+ # choose the right syntax
39
+ if connection.adapter_name =~ /(sqlite|postgres)/i
40
+ rand_syntax = "RANDOM()"
41
+ elsif connection.adapter_name =~ /mysql/i
42
+ rand_syntax = "RAND()"
43
+ else
44
+ raise Exception, "ActiveRecord adapter: '#{connection.adapter_name}' not supported by randumb. Send a pull request or open a ticket: https://github.com/spilliton/randumb"
45
+ end
46
+
47
+ order_clause = if ranking_column.nil?
48
+ rand_syntax
49
+ else
50
+ if connection.adapter_name =~ /sqlite/i
51
+ # computer multiplication is faster than division I was once taught...so translate here
52
+ max_int = 9223372036854775807.0
53
+ multiplier = 1.0 / max_int
54
+ "(#{ranking_column} * ABS(#{rand_syntax} * #{multiplier}) ) DESC"
55
+ else
56
+ "(#{ranking_column} * #{rand_syntax}) DESC"
57
+ end
58
+ end
59
+
60
+ the_scope = relation.order(order_clause)
61
+
62
+ # override the limit if they are requesting multiple records
63
+ if max_items && (!relation.limit_value || relation.limit_value > max_items)
64
+ the_scope = the_scope.limit(max_items)
65
+ end
66
+
67
+ # return first record if method was called without parameters
68
+ if max_items.nil?
69
+ the_scope.first
70
+ else
71
+ the_scope.all
72
+ end
73
+ end
74
+
75
+
76
+ # This was my first implementation, adding it as an option for people to use
77
+ # and to fall back on for pesky DB one off situations...
78
+ # https://github.com/spilliton/randumb/issues/7
79
+ def random_by_id_shuffle(max_items = nil)
80
+ return_first_record = max_items.nil?# see return switch at end
81
+ max_items ||= 1
82
+ relation = clone
83
+
84
+ # store these for including on final scope
85
+ original_includes = relation.includes_values
86
+ original_selects = relation.select_values
87
+
88
+ # clear these for our id only query
89
+ relation.select_values = []
90
+ relation.includes_values = []
91
+
92
+ # do original query but only for id field
93
+ id_only_relation = relation.select("#{table_name}.id")
94
+ id_results = connection.select_all(id_only_relation.to_sql)
95
+
96
+ # get requested number of random ids
97
+ if max_items == 1 && id_results.length > 0
98
+ ids = [ id_results[ rand(id_results.length) ]['id'] ]
99
+ else
100
+ ids = id_results.shuffle![0,max_items].collect!{ |h| h['id'] }
101
+ end
102
+
103
+ # build scope for final query
104
+ the_scope = klass.includes(original_includes)
105
+
106
+ # specifying empty selects caused bug in rails 3.0.0/3.0.1
107
+ the_scope = the_scope.select(original_selects) unless original_selects.empty?
108
+
109
+ # get the records and shuffle since the order of the ids
110
+ # passed to find_all_by_id isn't retained in the result set
111
+ records = the_scope.find_all_by_id(ids).shuffle!
112
+
113
+ # return first record if method was called without parameters
114
+ if return_first_record
115
+ records.first
116
+ else
117
+ records
118
+ end
119
+ end
120
+
121
+ end
122
+
123
+
124
+ # Class methods
125
+ module Base
126
+ def random(max_items = nil)
127
+ relation.random(max_items)
128
+ end
129
+
130
+ def random_weighted(ranking_column, max_items = nil)
131
+ relation.random_weighted(ranking_column, max_items)
132
+ end
133
+
134
+ def random_by_id_shuffle(max_items = nil)
135
+ relation.random_by_id_shuffle(max_items)
136
+ end
137
+ end
138
+
139
+
140
+ # These get registered as class and instance methods
141
+ module MethodMissingMagicks
142
+ def method_missing(symbol, *args)
143
+ if symbol.to_s =~ /^random_weighted_by_(\w+)$/
144
+ random_weighted($1, *args)
145
+ else
146
+ super
147
+ end
148
+ end
149
+
150
+ def respond_to?(symbol, include_private=false)
151
+ if symbol.to_s =~ /^random_weighted_by_(\w+)$/
152
+ true
153
+ else
154
+ super
155
+ end
156
+ end
157
+ end
158
+
159
+ end # ActiveRecord
160
+ end # Randumb
@@ -0,0 +1,3 @@
1
+ module Randumb
2
+ VERSION = "0.3.0"
3
+ end
@@ -0,0 +1,4 @@
1
+ class Album < ActiveRecord::Base
2
+ belongs_to :artist
3
+
4
+ end
@@ -0,0 +1,5 @@
1
+ class Artist < ActiveRecord::Base
2
+ has_many :albums
3
+
4
+ scope :at_least_three_views, where("views >= 3")
5
+ end
@@ -0,0 +1,13 @@
1
+ FactoryGirl.define do
2
+ factory :artist do
3
+ name { Faker::Lorem.words(3).join(' ') }
4
+ views { Random.rand(50) }
5
+ rating { Random.rand(100) / 100 }
6
+ end
7
+
8
+ factory :album do
9
+ name { Faker::Lorem.words(3).join(' ') }
10
+ views { Random.rand(50) }
11
+ end
12
+
13
+ end
@@ -0,0 +1,193 @@
1
+ $:.unshift '.'; require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class RandumbTest < Test::Unit::TestCase
4
+
5
+ def assert_equal_for_both_methods(expected, obj, params = nil)
6
+ assert_equal expected, obj.send(:random, params), "when calling random"
7
+ assert_equal expected, obj.send(:random_by_id_shuffle, params), "when calling random_by_id_shuffle"
8
+ end
9
+
10
+
11
+ should "should return empty when no record in table" do
12
+ assert_equal 0, Artist.count
13
+
14
+ assert_equal_for_both_methods nil, Artist
15
+ # above is equivalent to:
16
+ # assert_equal nil, Artist.random
17
+ # assert_equal nil, Artist.random_by_id_shuffle
18
+
19
+ assert_equal_for_both_methods [], Artist, 1
20
+ # above is equivalent to:
21
+ # assert_equal [], Artist.random(1)
22
+ # assert_equal [], Artist.random_by_id_shuffle(1)
23
+
24
+ assert_equal_for_both_methods nil, Artist.limit(50)
25
+ end
26
+
27
+ context "1 record in the table" do
28
+ setup do
29
+ @high_on_fire = FactoryGirl.create(:artist, :name => "High On Fire", :views => 1)
30
+ end
31
+
32
+ should "select only 1 record even when you request more" do
33
+ assert_equal 1, Artist.count
34
+
35
+ assert_equal_for_both_methods @high_on_fire, Artist
36
+ assert_equal_for_both_methods [@high_on_fire], Artist, 1
37
+ assert_equal_for_both_methods [@high_on_fire], Artist, 30
38
+ end
39
+
40
+ should "not return a record that doesnt match where" do
41
+ assert_equal_for_both_methods nil, Artist.where(:name => "The Little Gentlemen")
42
+ end
43
+
44
+ context "3 records in table" do
45
+ setup do
46
+ @fiona_apple = FactoryGirl.create(:artist, :name => "Fiona Apple", :views => 3)
47
+ @magnetic_fields = FactoryGirl.create(:artist, :name => "The Magnetic Fields", :views => 2)
48
+ end
49
+
50
+ should "apply randomness after other orders when using sql method" do
51
+ assert_equal @fiona_apple, Artist.order("views desc").random
52
+ assert_equal [@fiona_apple, @magnetic_fields], Artist.order("views desc").random(2)
53
+ end
54
+
55
+ should "take smaller limit if one is provided in scope" do
56
+ assert_equal 2, Artist.limit(2).random(3).length
57
+ assert_equal 2, Artist.limit(2).random_by_id_shuffle(3).length
58
+
59
+ assert_equal 2, Artist.limit(3).random(2).length
60
+ assert_equal 2, Artist.limit(3).random_by_id_shuffle(2).length
61
+ end
62
+
63
+ should "respect selecting certain columns" do
64
+ assert_equal 3, Artist.find(@fiona_apple.id).views
65
+
66
+ artists = Artist.select(:name).random(3)
67
+ assert_equal false, artists.first.name.nil?
68
+ assert_raise (ActiveModel::MissingAttributeError) {artists.first.views}
69
+
70
+ artists = Artist.select(:name).random_by_id_shuffle(3)
71
+ assert_equal false, artists.first.name.nil?
72
+ assert_raise (ActiveModel::MissingAttributeError) {artists.first.views}
73
+ end
74
+
75
+ should "respect scopes" do
76
+ assert_equal_for_both_methods [@fiona_apple], Artist.at_least_three_views, 3
77
+ end
78
+
79
+ should "select only as many as in the db if we request more" do
80
+ random_artists = Artist.random(10)
81
+ assert_equal 3, random_artists.length
82
+ assert_equal true, random_artists.include?(@high_on_fire)
83
+ assert_equal true, random_artists.include?(@fiona_apple)
84
+ assert_equal true, random_artists.include?(@magnetic_fields)
85
+
86
+ random_artists = Artist.random_by_id_shuffle(10)
87
+ assert_equal 3, random_artists.length
88
+ assert_equal true, random_artists.include?(@high_on_fire)
89
+ assert_equal true, random_artists.include?(@fiona_apple)
90
+ assert_equal true, random_artists.include?(@magnetic_fields)
91
+ end
92
+
93
+ context "with some albums" do
94
+ setup do
95
+ @tidal = FactoryGirl.create(:album, :name => "Tidal", :artist => @fiona_apple)
96
+ @extraordinary_machine = FactoryGirl.create(:album, :name => "Extraordinary Machine", :artist => @fiona_apple)
97
+ @sixty_nine_love_songs = FactoryGirl.create(:album, :name => "69 Love Songs", :artist => @magnetic_fields)
98
+ @snakes_for_the_divine = FactoryGirl.create(:album, :name => "Snakes For the Divine", :artist => @high_on_fire)
99
+ end
100
+
101
+
102
+ should "work with includes for default method" do
103
+ artists = Artist.includes(:albums).random(10)
104
+ fiona_apple = artists.find { |a| a.name == "Fiona Apple" }
105
+ # if I add a new album now, it shouldn't be in the albums assocation yet b/c it was already loaded
106
+ FactoryGirl.create(:album, :name => "When The Pawn", :artist => @fiona_apple)
107
+
108
+ assert_equal 2, fiona_apple.albums.length
109
+ assert_equal 3, @fiona_apple.reload.albums.length
110
+ end
111
+
112
+ should "work with includes for shuffle method" do
113
+ artists = Artist.includes(:albums).random_by_id_shuffle(10)
114
+ fiona_apple = artists.find { |a| a.name == "Fiona Apple" }
115
+ # if I add a new album now, it shouldn't be in the albums assocation yet b/c it was already loaded
116
+ FactoryGirl.create(:album, :name => "When The Pawn", :artist => @fiona_apple)
117
+
118
+ assert_equal 2, fiona_apple.albums.length
119
+ assert_equal 3, @fiona_apple.reload.albums.length
120
+ end
121
+
122
+ should "work with joins for default method" do
123
+ albums = Album.joins(:artist).where("artists.views > 1").random(3)
124
+
125
+ assert_equal 3, albums.length
126
+ assert_equal false, albums.include?(@snakes_for_the_divine)
127
+ assert_equal true, albums.include?(@tidal)
128
+ assert_equal true, albums.include?(@extraordinary_machine)
129
+ assert_equal true, albums.include?(@sixty_nine_love_songs)
130
+ end
131
+
132
+ should "work with joins for shuffle method" do
133
+ albums = Album.joins(:artist).where("artists.views > 1").random_by_id_shuffle(3)
134
+
135
+ assert_equal 3, albums.length
136
+ assert_equal false, albums.include?(@snakes_for_the_divine)
137
+ assert_equal true, albums.include?(@tidal)
138
+ assert_equal true, albums.include?(@extraordinary_machine)
139
+ assert_equal true, albums.include?(@sixty_nine_love_songs)
140
+ end
141
+
142
+ should "work with uniq" do
143
+ assert_equal 2, Artist.uniq.random(2).length
144
+ assert_equal 2, Artist.uniq.random_by_id_shuffle(2).length
145
+
146
+ assert_not_nil Artist.uniq.random
147
+ assert_not_nil Artist.uniq.random_by_id_shuffle
148
+ end
149
+
150
+ end
151
+
152
+ end
153
+
154
+ end
155
+
156
+ context "2 records in table" do
157
+ setup do
158
+ @hum = FactoryGirl.create(:artist, :name => "Hum", :views => 3)
159
+ @minutemen = FactoryGirl.create(:artist, :name => "Minutemen", :views => 2)
160
+ end
161
+
162
+ should "eventually render the 2 possible orders using default method" do
163
+ order1 = [@hum, @minutemen]
164
+ order2 = [@minutemen, @hum]
165
+ order1_found = false
166
+ order2_found = false
167
+ 100.times do
168
+ order = Artist.random(2)
169
+ order1_found = true if order == order1
170
+ order2_found = true if order == order2
171
+ break if order1_found && order2_found
172
+ end
173
+ assert order1_found
174
+ assert order2_found
175
+ end
176
+
177
+ should "eventually render the 2 possible orders using shuffle method" do
178
+ order1 = [@hum, @minutemen]
179
+ order2 = [@minutemen, @hum]
180
+ order1_found = false
181
+ order2_found = false
182
+ 100.times do
183
+ order = Artist.random_by_id_shuffle(2)
184
+ order1_found = true if order == order1
185
+ order2_found = true if order == order2
186
+ break if order1_found && order2_found
187
+ end
188
+ assert order1_found
189
+ assert order2_found
190
+ end
191
+ end
192
+
193
+ end
@@ -0,0 +1,67 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'rubygems'
3
+ require 'test/unit'
4
+ require 'shoulda'
5
+ require 'factory_girl'
6
+ require 'faker'
7
+ require 'active_record'
8
+ require 'active_support/dependencies'
9
+ require 'active_support/core_ext/logger'
10
+ # require 'active_record/fixtures'
11
+ require 'randumb'
12
+
13
+ MODELS_PATH = File.join(File.dirname(__FILE__), 'models')
14
+
15
+
16
+ ActiveRecord::Base.logger = Logger.new(STDERR)
17
+ ActiveRecord::Base.logger.level = Logger::WARN
18
+
19
+ config = YAML::load(File.open(File.expand_path("../databases.yml", __FILE__)))
20
+ version = ActiveRecord::VERSION::STRING
21
+ driver = (ENV["DB"] or "sqlite3").downcase
22
+ in_memory = config[driver]["database"] == ":memory:"
23
+
24
+ # http://about.travis-ci.org/docs/user/database-setup/
25
+ commands = {
26
+ "mysql" => "mysql -e 'create database randumb_test;'",
27
+ "postgres" => "psql -c 'create database randumb_test;' -U postgres"
28
+ }
29
+ %x{#{commands[driver] || true}}
30
+
31
+ ActiveRecord::Base.establish_connection config[driver]
32
+ puts "Using #{RUBY_VERSION} AR #{version} with #{driver}"
33
+
34
+
35
+ ActiveRecord::Base.connection.create_table(:artists, :force => true) do |t|
36
+ t.string "name"
37
+ t.integer "views"
38
+ t.float "rating"
39
+ t.datetime "created_at"
40
+ t.datetime "updated_at"
41
+ end
42
+
43
+ ActiveRecord::Base.connection.create_table(:albums, :force => true) do |t|
44
+ t.string "name"
45
+ t.integer "views"
46
+ t.integer "artist_id"
47
+ t.datetime "created_at"
48
+ t.datetime "updated_at"
49
+ end
50
+
51
+ # setup models for lazy load
52
+ dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
53
+ dep.autoload_paths.unshift MODELS_PATH
54
+
55
+ # load factories now
56
+ require 'test/models/factories'
57
+
58
+ # clear db for every test
59
+ class Test::Unit::TestCase
60
+
61
+ def setup
62
+ Artist.delete_all
63
+ Album.delete_all
64
+ end
65
+
66
+ end
67
+
@@ -0,0 +1,125 @@
1
+ $:.unshift '.'; require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class WeightedTest < Test::Unit::TestCase
4
+
5
+ should "raise exception when called with a non-existent column" do
6
+ assert_raises(ArgumentError) do
7
+ Artist.random_weighted(:blah)
8
+ end
9
+ assert_raises(ArgumentError) do
10
+ Artist.random_weighted_by_blah
11
+ end
12
+ end
13
+
14
+ should "raise exception when called with a non-numeric column" do
15
+ assert_raises(ArgumentError) do
16
+ Artist.random_weighted(:name)
17
+ end
18
+ assert_raises(ArgumentError) do
19
+ Artist.random_weighted_by_name
20
+ end
21
+ end
22
+
23
+ if ENV["DB"] == "postgres"
24
+ should "raise exception if being called with uniq/postgres" do
25
+ assert_raises(Exception) do
26
+ Artist.uniq.random_weighted(:name)
27
+ end
28
+ end
29
+ else
30
+ should "work with uniq if not postgres" do
31
+ assert_nil Artist.uniq.random_weighted_by_views
32
+ end
33
+ end
34
+
35
+ should "not blow up with integer columns and float column types" do
36
+ assert_nil Artist.random_weighted_by_views
37
+ assert_nil Artist.random_weighted_by_rating
38
+ end
39
+
40
+ should "not interfere with active record dynamic methods that use method_missing" do
41
+ @artist = FactoryGirl.create(:artist, :name => 'Spiritualized')
42
+ assert_equal @artist, Artist.find_by_name('Spiritualized')
43
+ end
44
+
45
+ should "respond to respond_to?" do
46
+ assert Artist.respond_to?(:random_weighted_by_views)
47
+ assert Artist.respond_to?(:random_weighted_by_xxxxxx)
48
+ assert Artist.at_least_three_views.respond_to?(:random_weighted_by_xxxxxx)
49
+ end
50
+
51
+ should "not interfere with active record dynamic methods that use respond_to?" do
52
+ assert Artist.respond_to?(:find_by_name)
53
+ end
54
+
55
+
56
+ context "order by ranking_column" do
57
+ setup do
58
+ @view_counts = [1, 2, 3, 4, 5]
59
+ @view_counts.each { |views| FactoryGirl.create(:artist, :views => views) }
60
+ end
61
+
62
+ should "order by ranking column with explicit method call" do
63
+ assert_hits_per_views do
64
+ Artist.random_weighted("views").views
65
+ end
66
+ end
67
+
68
+ should "order by ranking column with method_missing" do
69
+ assert_hits_per_views do
70
+ Artist.random_weighted_by_views.views
71
+ end
72
+ end
73
+
74
+ should "order by ranking column with explicit method call and max_items" do
75
+ assert_hits_per_views do
76
+ result = Artist.random_weighted("views", 5)
77
+ assert(result.size == 5)
78
+ result.first.views
79
+ end
80
+ end
81
+
82
+ should "order by ranking column with method_missing using max_items" do
83
+ assert_hits_per_views do
84
+ result = Artist.random_weighted_by_views(10)
85
+ assert(result.size == 5)
86
+ result.first.views
87
+ end
88
+ end
89
+
90
+ should "LAST order should fail" do
91
+ assert_raises(MiniTest::Assertion) do
92
+ assert_hits_per_views do
93
+ result = Artist.random_weighted_by_views(3)
94
+ assert(result.size == 3)
95
+ result.last.views
96
+ end
97
+ end
98
+ end
99
+
100
+ should "order by ranking column with method_missing using 1 max_items" do
101
+ assert_hits_per_views do
102
+ result = Artist.random_weighted_by_views(1)
103
+ assert(result.size == 1)
104
+ result.first.views
105
+ end
106
+ end
107
+
108
+ def assert_hits_per_views
109
+ hits_per_views = Hash.new
110
+ @view_counts.each { |views| hits_per_views[views] = 0 }
111
+
112
+ 1000.times do
113
+ hits_per_views[yield] += 1
114
+ end
115
+ last_count = 0
116
+ @view_counts.each do |views|
117
+ hits = hits_per_views[views]
118
+ assert(hits >= last_count, "#{hits} > #{last_count} : There were an unexpected number of visits: #{hits_per_views.to_yaml}")
119
+ last_count = hits
120
+ end
121
+ end
122
+ end
123
+
124
+
125
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: randumb
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.0
5
+ version: 0.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Zachary Kloepping
@@ -10,19 +10,85 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-05-06 00:00:00 Z
13
+ date: 2012-07-07 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: rspec
16
+ name: activesupport
17
17
  prerelease: false
18
18
  requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 3.0.0
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: activerecord
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 3.0.0
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: pg
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
19
52
  none: false
20
53
  requirements:
21
54
  - - ">="
22
55
  - !ruby/object:Gem::Version
23
56
  version: "0"
24
57
  type: :development
25
- version_requirements: *id001
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: shoulda
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: factory_girl
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: "3.0"
79
+ type: :development
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: faker
83
+ prerelease: false
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ type: :development
91
+ version_requirements: *id007
26
92
  description:
27
93
  email:
28
94
  executables: []
@@ -32,7 +98,15 @@ extensions: []
32
98
  extra_rdoc_files: []
33
99
 
34
100
  files:
101
+ - lib/randumb/relation.rb
102
+ - lib/randumb/version.rb
35
103
  - lib/randumb.rb
104
+ - test/models/album.rb
105
+ - test/models/artist.rb
106
+ - test/models/factories.rb
107
+ - test/randumb_test.rb
108
+ - test/test_helper.rb
109
+ - test/weighted_test.rb
36
110
  homepage: https://github.com/spilliton/randumb
37
111
  licenses: []
38
112
 
@@ -60,5 +134,10 @@ rubygems_version: 1.8.24
60
134
  signing_key:
61
135
  specification_version: 3
62
136
  summary: Adds the ability to pull random records from ActiveRecord
63
- test_files: []
64
-
137
+ test_files:
138
+ - test/models/album.rb
139
+ - test/models/artist.rb
140
+ - test/models/factories.rb
141
+ - test/randumb_test.rb
142
+ - test/test_helper.rb
143
+ - test/weighted_test.rb