arid_cache 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,9 +2,8 @@ require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
3
  class AridCacheTest < ActiveSupport::TestCase
4
4
  def setup
5
- Rails.cache.clear
6
- AridCache.store.delete!
7
- get_user
5
+ FileUtils.rm_r(Rails.cache.cache_path) if File.exists?(Rails.cache.cache_path)
6
+ @user = User.first
8
7
  end
9
8
 
10
9
  test "initializes needed objects" do
@@ -13,36 +12,28 @@ class AridCacheTest < ActiveSupport::TestCase
13
12
  end
14
13
 
15
14
  test "should respond to methods" do
16
- assert User.respond_to?(:clear_cache)
17
- assert User.first.respond_to?(:clear_cache)
15
+ assert User.respond_to?(:clear_caches)
16
+ assert @user.respond_to?(:clear_caches)
18
17
  assert_instance_of AridCache::Store, AridCache.store
18
+ assert_same AridCache::CacheProxy, AridCache.cache
19
19
  end
20
20
 
21
21
  test "should not clobber model methods" do
22
- assert_respond_to User.first, :name
22
+ assert_respond_to @user, :name
23
23
  assert_respond_to Company.first, :name
24
- assert_nothing_raised { User.first.name }
24
+ assert_nothing_raised { @user.name }
25
25
  assert_nothing_raised { Company.first.name }
26
-
27
- # Shouldn't mess with your model's method_missing
28
- assert_nothing_raised { User.first.is_high? }
29
- assert User.first.is_high?
30
- end
31
-
32
- test "should allow me to cache on the model" do
33
- assert_nothing_raised do
34
- define_model_cache(User)
35
- end
36
- #assert_instance_of(Proc, AridCache.store[User.arid_cache_key('companies')].proc)
37
26
  end
38
27
 
39
- test "should allow me to cache on the instance" do
40
- assert_nothing_raised do
41
- define_instance_cache(@user)
42
- end
43
- #assert_instance_of(Proc, AridCache.store[AridCache.store.store_key@user.arid_cache_key('companies')].proc)
28
+ test "should not clobber method_missing" do
29
+ assert_nothing_raised { @user.is_high? }
30
+ assert @user.is_high?
44
31
  end
45
-
32
+
33
+ test "should not clobber respond_to?" do
34
+ assert @user.respond_to?(:respond_not_overridden)
35
+ end
36
+
46
37
  test "should raise an error on invalid dynamic caches" do
47
38
  assert_raises ArgumentError do
48
39
  @user.cached_invalid_companies
@@ -51,7 +42,6 @@ class AridCacheTest < ActiveSupport::TestCase
51
42
 
52
43
  test "should create dynamic caches given valid arguments" do
53
44
  assert_nothing_raised { @user.cached_companies }
54
- #assert_instance_of(Proc, AridCache.store[@user.arid_cache_key('companies')].proc)
55
45
  end
56
46
 
57
47
  test "counts queries correctly" do
@@ -65,27 +55,20 @@ class AridCacheTest < ActiveSupport::TestCase
65
55
  end
66
56
 
67
57
  test "paginates results" do
68
- results = @user.cached_companies(:page => 1, :per_page => 3)
58
+ results = @user.cached_companies(:page => 1, :per_page => 3, :order => 'name desc')
69
59
  assert_kind_of WillPaginate::Collection, results
70
60
  assert_equal 3, results.size
71
61
  assert_equal @user.companies.count, results.total_entries
72
62
  assert_equal 1, results.current_page
73
63
  end
74
64
 
75
- test "overrides default paginate options" do
76
- results = @user.cached_companies(:page => 1, :per_page => 3)
77
- assert_kind_of WillPaginate::Collection, results
78
- assert_equal 3, results.size
79
- assert_equal @user.companies.count, results.total_entries
80
- end
81
-
82
- test "works for different pages" do
65
+ test "should work for different pages" do
83
66
  results = @user.cached_companies(:page => 2, :per_page => 3)
84
67
  assert_kind_of WillPaginate::Collection, results
85
68
  assert results.size <= 3
86
69
  assert_equal @user.companies.count, results.total_entries
87
70
  assert_equal 2, results.current_page
88
- end
71
+ end
89
72
 
90
73
  test "ignores random parameters" do
91
74
  result = @user.cached_companies(:invalid => :params, 'random' => 'values', :user_id => 3)
@@ -118,35 +101,57 @@ class AridCacheTest < ActiveSupport::TestCase
118
101
  end
119
102
  end
120
103
 
121
- test "calling cache_ defines methods on the object" do
122
- assert !User.method_defined?(:cached_favorite_companies)
123
- User.cache_favorite_companies(:order => 'name DESC') do
124
- User.companies
125
- end
126
- assert User.respond_to?(:cached_favorite_companies)
127
- assert_nothing_raised do
128
- User.method(:cached_favorite_companies)
129
- end
130
- end
131
-
132
104
  test "applies limit and offset" do
133
- @user.cached_limit_companies do
105
+ result = @user.cached_limit_companies do
134
106
  companies
135
107
  end
136
- assert_equal 2, @user.cached_limit_companies(:limit => 2).size
137
- assert_equal 3, @user.cached_limit_companies(:limit => 3).size
108
+ limit_two_result = @user.cached_limit_companies(:limit => 2)
109
+ assert_equal 2, limit_two_result.size
110
+ assert_equal result[0, 2], limit_two_result
111
+
112
+ limit_three_result = @user.cached_limit_companies(:limit => 3)
113
+ assert_equal 3, limit_three_result.size
114
+ assert_equal result[0, 3], limit_three_result
115
+
116
+ limit_two_offset_one_result = @user.cached_limit_companies(:limit => 2, :offset => 1)
117
+ assert_equal 2, limit_two_offset_one_result.size
118
+ assert_equal result[1, 2], limit_two_offset_one_result
119
+
120
+ offset_one_result = @user.cached_limit_companies(:offset => 1)
121
+ assert_equal result.size-1, offset_one_result.size
122
+ assert_equal result[1, result.size], offset_one_result
123
+
138
124
  assert_equal @user.companies.all(:limit => 2, :offset => 1), @user.cached_limit_companies(:limit => 2, :offset => 1)
139
125
  assert_equal @user.companies.size, @user.cached_limit_companies.size
126
+
127
+ # Careful of this Rails bug: https://rails.lighthouseapp.com/projects/8994/tickets/1349-named-scope-with-group-by-bug
140
128
  User.cached_successful_limit_companies do
141
- User.successful
129
+ User.successful.all
142
130
  end
143
- raise User.cached_successful_limit_companies.inspect
144
131
  assert_equal 2, User.cached_successful_limit_companies(:limit => 2).size
145
132
  assert_equal 3, User.cached_successful_limit_companies(:limit => 3).size
146
133
  assert_equal User.successful.all(:limit => 2, :offset => 1), User.cached_successful_limit_companies(:limit => 2, :offset => 1)
147
- assert_equal User.successful.size, User.cached_successful_limit_companies.size
134
+ assert_equal User.successful.all.size, User.cached_successful_limit_companies.size
135
+ end
136
+
137
+ test "should requery the database for limits with order" do
138
+ @user.cached_companies # prime the cache
139
+ assert_equal @user.companies.find(:all, :limit => 3, :order => 'name DESC'), @user.cached_companies(:limit => 3, :order => 'name DESC')
140
+ assert_equal @user.companies.find(:all, :limit => 3, :order => 'name ASC'), @user.cached_companies(:limit => 3, :order => 'name ASC')
148
141
  end
149
142
 
143
+ test "should activate will paginate" do
144
+ assert_nothing_raised do
145
+ User.paginate(:page => 1)
146
+ end
147
+ end
148
+
149
+ test "should requery the database for paginate with order" do
150
+ @user.cached_companies # prime the cache
151
+ assert_equal @user.companies.paginate(:page => 1, :per_page => 3, :order => 'name DESC'), @user.cached_companies(:page => 1, :per_page => 3, :order => 'name DESC')
152
+ assert_equal @user.companies.paginate(:page => 1, :per_page => 3, :order => 'name ASC'), @user.cached_companies(:page => 1, :per_page => 3, :order => 'name ASC')
153
+ end
154
+
150
155
  test "pagination should not result in an extra query" do
151
156
  assert_queries(1) do
152
157
  @user.cached_big_companies(:page => 1)
@@ -180,7 +185,7 @@ class AridCacheTest < ActiveSupport::TestCase
180
185
  assert_equal one.companies, one.cached_companies
181
186
  assert_equal two.companies, two.cached_companies
182
187
  end
183
-
188
+
184
189
  test "should handle arrays of non-active record instances" do
185
190
  assert_equal @user.pet_names, @user.cached_pet_names
186
191
  assert_equal @user.pet_names, @user.cached_pet_names
@@ -188,25 +193,127 @@ class AridCacheTest < ActiveSupport::TestCase
188
193
  end
189
194
 
190
195
  test "should empty the Rails cache" do
191
- define_model_cache(User)
192
196
  @user.cached_companies
193
197
  User.cached_companies
194
198
  assert Rails.cache.exist?(@user.arid_cache_key('companies'))
195
199
  assert Rails.cache.exist?(User.arid_cache_key('companies'))
196
- User.clear_cache
197
- assert Rails.cache.exist?(@user.arid_cache_key('companies'))
198
- assert Rails.cache.exist?(User.arid_cache_key('companies'))
200
+ User.clear_caches
201
+ assert !Rails.cache.exist?(@user.arid_cache_key('companies'))
202
+ assert !Rails.cache.exist?(User.arid_cache_key('companies'))
199
203
  end
200
-
201
- protected
202
-
203
- def get_user
204
- @user = User.first
205
- @user.clear_cache
206
- define_instance_cache(@user)
207
- @user
204
+
205
+ test "should support expiring caches" do
206
+ # The first query should put the count in the cache. The second query
207
+ # should read the count from the cache. The third query should
208
+ # reload the cache.
209
+ assert_queries(2) do
210
+ User.cached_companies_count(:expires_in => 1.second)
211
+ User.cached_companies_count(:expires_in => 1.second)
212
+ sleep(1)
213
+ User.cached_companies_count(:expires_in => 1.second)
208
214
  end
215
+ end
216
+
217
+ test "should support an auto-expire option" do
218
+ assert_match %r[users/#{@user.id}-companies], @user.arid_cache_key('companies')
219
+ assert_equal @user.arid_cache_key('companies'), @user.arid_cache_key('companies', :auto_expire => false)
220
+ assert_match %r[users/#{@user.id}-\d{14}-companies], @user.arid_cache_key('companies', :auto_expire => true)
209
221
 
222
+ # It doesn't apply to class caches, but shouldn't affect it either
223
+ assert_equal User.arid_cache_key('companies'), User.arid_cache_key('companies', :auto_expire => true)
224
+ end
225
+
226
+ test "should turn off auto-expire by default" do
227
+ assert_queries(2) do
228
+ @user.cached_companies_count
229
+ @user.touch
230
+ @user.cached_companies_count
231
+ end
232
+ end
233
+
234
+ test "should reload auto-expired caches" do
235
+ assert_queries(2) do
236
+ @user.cached_companies_count(:auto_expire => true)
237
+ @user.cached_companies_count(:auto_expire => true)
238
+ @user.updated_at = Time.now + 1.seconds
239
+ @user.cached_companies_count(:auto_expire => true)
240
+ @user.cached_companies_count(:auto_expire => true)
241
+ end
242
+ end
243
+
244
+ test "should support configuring instance caches" do
245
+ User.instance_caches { best_companies { companies } }
246
+ assert_equal @user.companies, @user.cached_best_companies
247
+ end
248
+
249
+ test "instance caches should work on all instances of the class" do
250
+ User.instance_caches { best_companies { companies } }
251
+ assert_equal @user.cached_best_companies, User.first.cached_best_companies
252
+ end
253
+
254
+ test "should support configuring class caches" do
255
+ User.class_caches { successful_users { successful } }
256
+ assert_equal User.successful, User.cached_successful_users
257
+ end
258
+
259
+ test "should create valid store keys" do
260
+ assert_equal 'user-key', AridCache.store.send(:class_store_key, User, 'key')
261
+ assert_equal 'users-key', AridCache.store.send(:instance_store_key, User, 'key')
262
+ assert_equal AridCache.store.send(:instance_store_key, User, 'key'), AridCache.store.send(:object_store_key, @user, 'key')
263
+ assert_equal AridCache.store.send(:class_store_key, User, 'key'), AridCache.store.send(:object_store_key, User, 'key')
264
+ end
265
+
266
+ test "configuring caches should not perform any queries" do
267
+ User.instance_caches do
268
+ best_companies { companies }
269
+ end
270
+ User.class_caches do
271
+ best_companies(:order => 'name DESC') { companies.find(:all, :order => 'name DESC') }
272
+ end
273
+ end
274
+
275
+ test "should support options in the cache configuration" do
276
+ User.instance_caches(:auto_expire => true) do
277
+ expires_in = 1.second
278
+ best_companies(:expires_in => expires_in) { companies }
279
+ end
280
+ assert_queries(2) do
281
+ @user.cached_best_companies_count
282
+ @user.updated_at = Time.now + 1.seconds
283
+ @user.cached_best_companies_count
284
+ @user.cached_best_companies_count
285
+ end
286
+ User.class_caches do
287
+ most_successful(:order => 'name DESC') { successful.find(:all, :order => 'name DESC') }
288
+ end
289
+ # Call it twice to ensure that on the second call the order is applied when retrieving the
290
+ # records by id
291
+ assert_equal User.successful.find(:all, :order => 'name DESC'), User.cached_most_successful
292
+ assert_equal User.successful.find(:all, :order => 'name DESC'), User.cached_most_successful
293
+ end
294
+
295
+ #
296
+ # Tests requiring manual verification by looking at the SQL logs.
297
+ # TODO move these to a separate class.
298
+ #
299
+
300
+ test "should preserve original ordering" do
301
+ # TODO. This one is hard to test because SQL usually keeps the same ordering
302
+ # and it's difficult to make it do otherwise. Best to just inspect the queries
303
+ # in the log.
304
+ @user.cached_companies
305
+ @user.cached_companies
306
+ end
307
+
308
+ test "should paginate collections in memory" do
309
+ # TODO. Tough to test because we can't just count queries
310
+ # have to look at the SQL in the logs for this one.
311
+ @user.cached_companies(:page => 2, :per_page => 3)
312
+ @user.cached_companies(:page => 1, :per_page => 3)
313
+ end
314
+
315
+ protected
316
+
210
317
  def assert_queries(num = 1)
211
318
  $query_count = 0
212
319
  yield
@@ -217,16 +324,4 @@ class AridCacheTest < ActiveSupport::TestCase
217
324
  def assert_no_queries(&block)
218
325
  assert_queries(0, &block)
219
326
  end
220
-
221
- def define_instance_cache(user)
222
- user.cache_companies(:per_page => 2) do
223
- user.companies
224
- end
225
- end
226
-
227
- def define_model_cache(model)
228
- model.cache_companies(:per_page => 2) do
229
- model.companies
230
- end
231
- end
232
327
  end
data/test/db/prepare.rb CHANGED
@@ -13,14 +13,13 @@ ActiveRecord::Base.silence do
13
13
  load(File.join(File.dirname(__FILE__), 'schema.rb'))
14
14
  end
15
15
 
16
- # Fixtures
17
- ActiveRecord::Base.silence do
18
- Fixtures.create_fixtures(File.join(File.dirname(__FILE__), '..', 'fixtures'), ActiveRecord::Base.connection.tables)
19
- end
20
-
21
16
  # Models
22
17
  Dir[File.join(File.dirname(__FILE__), '..', 'models', '*.rb')].each { |f| require f }
23
18
 
19
+ # Populate
20
+ require 'blueprint'
21
+ Blueprint.seeds
22
+
24
23
  class << ActiveRecord::Base.connection
25
24
  IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SHOW FIELDS /]
26
25
 
data/test/db/schema.rb CHANGED
@@ -2,6 +2,7 @@ ActiveRecord::Schema.define do
2
2
  create_table "users", :force => true do |t|
3
3
  t.column "name", :text
4
4
  t.column "email", :text
5
+ t.timestamps
5
6
  end
6
7
 
7
8
  create_table "companies", :force => true do |t|
@@ -9,5 +10,6 @@ ActiveRecord::Schema.define do
9
10
  t.column "owner_id", :integer
10
11
  t.column "country_id", :integer
11
12
  t.column "employees", :integer
13
+ t.timestamps
12
14
  end
13
15
  end
@@ -0,0 +1,17 @@
1
+
2
+ module ActiveSupport
3
+ module Cache
4
+ class FileStore < Store
5
+ alias :original_read :read
6
+
7
+ def read(name, options = {})
8
+ lastmod = File.mtime(real_file_path(name)) rescue nil
9
+ if lastmod && options.is_a?(Hash) && options[:expires_in] && ((lastmod + options[:expires_in]) <= Time.now)
10
+ nil
11
+ else
12
+ original_read(name, options)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ require 'machinist/active_record'
2
+ require 'sham'
3
+ require 'faker'
4
+
5
+ Sham.name { Faker::Name.name }
6
+ Sham.company_name { Faker::Company.name }
7
+ Sham.email { Faker::Internet.email }
8
+
9
+ User.blueprint do
10
+ name
11
+ email
12
+ end
13
+
14
+ Company.blueprint do
15
+ name { Sham.company_name }
16
+ employees { rand(200) }
17
+ #owner
18
+ end
19
+
20
+ module Blueprint
21
+ def self.seeds
22
+ 10.times do
23
+ user = User.make
24
+ (5 + rand(5)).times do
25
+ Company.make(:owner => user)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,6 @@
1
+ require 'arid_cache'
1
2
 
2
3
  class Company < ActiveRecord::Base
3
4
  named_scope :owned, :conditions => ['owner_id is not null']
4
- belongs_to :owner, :class_name => :User
5
+ belongs_to :owner, :class_name => 'User'
5
6
  end
data/test/models/user.rb CHANGED
@@ -3,7 +3,7 @@ require 'arid_cache'
3
3
  class User < ActiveRecord::Base
4
4
  has_many :companies, :foreign_key => :owner_id
5
5
  named_scope :companies, :joins => :companies
6
- named_scope :successful, :joins => :companies, :conditions => 'companies.employees > 50'
6
+ named_scope :successful, :joins => :companies, :conditions => 'companies.employees > 50', :group => 'users.id'
7
7
 
8
8
  def big_companies
9
9
  companies.find :all, :conditions => [ 'employees > 20' ]
@@ -20,4 +20,12 @@ class User < ActiveRecord::Base
20
20
  super
21
21
  end
22
22
  end
23
+
24
+ def respond_to?(method)
25
+ if method == :respond_not_overridden
26
+ true
27
+ else
28
+ super
29
+ end
30
+ end
23
31
  end
data/test/test_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) # AridCache lib
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib')) # test lib
3
4
 
5
+ require 'fileutils'
4
6
  require 'rubygems'
5
7
  require 'active_record'
6
8
  require 'active_support'
@@ -9,7 +11,13 @@ require 'test/unit' # required by ActiveSupport::TestCase
9
11
  require 'will_paginate'
10
12
  require 'ruby-debug'
11
13
 
12
- # Activate ARID Cache
14
+ # Activate Will Paginate
15
+ WillPaginate.enable_activerecord
16
+
17
+ # Add support for expiring file-cache store.
18
+ require 'active_support/cache/file_store_extras'
19
+
20
+ # Activate AridCache
13
21
  require 'arid_cache'
14
22
  AridCache.init_rails
15
23
 
@@ -17,8 +25,9 @@ AridCache.init_rails
17
25
  log = File.expand_path(File.join(File.dirname(__FILE__), 'log', 'test.log'))
18
26
  RAILS_DEFAULT_LOGGER = ENV["STDOUT"] ? Logger.new(STDOUT) : Logger.new(log)
19
27
 
20
- # Setup an in memory-cache
21
- RAILS_CACHE = ActiveSupport::Cache.lookup_store(:memory_store)
28
+ # Setup the cache. Use the file-store cache because the
29
+ # memory-store cache doesn't delete cache keys...I don't know why.
30
+ RAILS_CACHE = ActiveSupport::Cache.lookup_store(:file_store, "#{File.dirname(__FILE__)}/tmp/cache")
22
31
 
23
32
  # Mock Rails
24
33
  Rails = Class.new do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arid_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karl Varga
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-25 00:00:00 +08:00
12
+ date: 2010-01-15 00:00:00 +08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -23,17 +23,27 @@ dependencies:
23
23
  version: "0"
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
- name: rspec
26
+ name: will_paginate
27
27
  type: :development
28
28
  version_requirement:
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.2.9
33
+ version: "0"
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
- name: will_paginate
36
+ name: faker
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: machinist
37
47
  type: :development
38
48
  version_requirement:
39
49
  version_requirements: !ruby/object:Gem::Requirement
@@ -43,8 +53,8 @@ dependencies:
43
53
  version: "0"
44
54
  version:
45
55
  description: |
46
- ARID Cache makes caching easy and effective. ARID cache supports caching on all your model named scopes, class methods and instance methods right out of the box. ARID cache prevents caching logic from cluttering your models and clarifies your logic by making explicit calls to cached result sets.
47
- ARID Cache is designed for handling large, expensive ActiveRecord collections but is equally useful for caching anything else as well.
56
+ AridCache makes caching easy and effective. AridCache supports caching on all your model named scopes, class methods and instance methods right out of the box. AridCache prevents caching logic from cluttering your models and clarifies your logic by making explicit calls to cached result sets.
57
+ AridCache is designed for handling large, expensive ActiveRecord collections but is equally useful for caching anything else as well.
48
58
 
49
59
  email: kjvarga@gmail.com
50
60
  executables: []
@@ -76,8 +86,8 @@ files:
76
86
  - test/console
77
87
  - test/db/prepare.rb
78
88
  - test/db/schema.rb
79
- - test/fixtures/companies.yml
80
- - test/fixtures/users.yml
89
+ - test/lib/active_support/cache/file_store_extras.rb
90
+ - test/lib/blueprint.rb
81
91
  - test/log/.gitignore
82
92
  - test/models/company.rb
83
93
  - test/models/user.rb
@@ -116,6 +126,8 @@ test_files:
116
126
  - test/arid_cache_test.rb
117
127
  - test/db/prepare.rb
118
128
  - test/db/schema.rb
129
+ - test/lib/active_support/cache/file_store_extras.rb
130
+ - test/lib/blueprint.rb
119
131
  - test/models/company.rb
120
132
  - test/models/user.rb
121
133
  - test/test_helper.rb
@@ -1,6 +0,0 @@
1
- <% for digit in 1..15 %>
2
- acme_<%= digit %>:
3
- name: Acme <%= digit %>
4
- owner_id: <%= rand(10) %>
5
- employees: <%= rand(200) %>
6
- <% end %>
@@ -1,5 +0,0 @@
1
- <% for digit in 1..10 %>
2
- user_<%= digit %>:
3
- name: Bob <%= digit %>
4
- email: bob<%= digit %>@ibm.com
5
- <% end %>