Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Improve specs for Array#choice / Array#sample #159

Merged
merged 4 commits into from

2 participants

@bak
bak commented

Four commits dealing with Array#choice and Array#sample

Goal here was to improve spec names and implementations, to reveal what they actually do. This is mainly accomplished by avoiding the language of "testing for randomness" in favor of measurable facets of something that we expect to be random, such as membership in the source array, and distribution of the results. Additionally split an omnibus spec into well-defined expectations.

Note this is a reimplementation of a previously-closed PR, because I changed my mind about how to approach the problem, and wanted to rewrite the commits themselves.

bak added some commits
@bak bak Spec that results of Array#sample & #choice are distributed across set
Methods for testing randomness are by nature insufficient, but we can
at least describe that the results of these methods are distributed
across the source set (however random or nonrandom that distribution may
be).
bf63961
@bak bak Test pieces of Array#sample(n) independently
The existing spec specified that (1) the result of #sample should come
from the source array in a few different assertions, and (2) that
 #sample(n) should not return n of an element if that element is not
present in the source at least n times.

Additionally, adds a spec for the condition where the array is not
unique.
ccc6e11
@bak bak Array#sample & #choice spec names should describe actual spec behavior
Our test can only check that the returned value is a member of the
Array, not that it is random, so let spec title reflect that.

Likewise, using `10.times { ... }` suggests that randomness or
consistency of the return value is somehow being tested. Just checking
for membership once should be adequate, and is clearer about what it is
actually doing.
43f63a9
@bak bak Clarifies preconditions for the Array#sample(n) to return source array 9fe3b57
@brixen brixen merged commit 3315888 into from
@brixen
Owner

@bak please see 4c8fac6 for some updates to your patches. I will cover this stuff more in upcoming doc changes, but wanted to point the out.

@bak
bak commented

@brixen Great, thanks for the direction on preferred block style, and the pointer on expectation clarity. I like that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 5, 2012
  1. @bak

    Spec that results of Array#sample & #choice are distributed across set

    bak authored
    Methods for testing randomness are by nature insufficient, but we can
    at least describe that the results of these methods are distributed
    across the source set (however random or nonrandom that distribution may
    be).
  2. @bak

    Test pieces of Array#sample(n) independently

    bak authored
    The existing spec specified that (1) the result of #sample should come
    from the source array in a few different assertions, and (2) that
     #sample(n) should not return n of an element if that element is not
    present in the source at least n times.
    
    Additionally, adds a spec for the condition where the array is not
    unique.
  3. @bak

    Array#sample & #choice spec names should describe actual spec behavior

    bak authored
    Our test can only check that the returned value is a member of the
    Array, not that it is random, so let spec title reflect that.
    
    Likewise, using `10.times { ... }` suggests that randomness or
    consistency of the return value is somehow being tested. Just checking
    for membership once should be adequate, and is clearer about what it is
    actually doing.
  4. @bak
This page is out of date. Refresh to see the latest.
Showing with 44 additions and 19 deletions.
  1. +10 −3 core/array/choice_spec.rb
  2. +34 −16 core/array/sample_spec.rb
View
13 core/array/choice_spec.rb
@@ -3,9 +3,16 @@
describe "Array#choice" do
ruby_version_is "1.8.7"..."1.9" do
- it "selects a random value from the array" do
- a = [1,2,3,4]
- 10.times { a.include?(a.choice).should be_true }
+ it "returns a value from the array" do
+ [4].choice.should eql(4)
+ end
+
+ it "returns a distribution of results" do
+ source = [0,1,2,3,4]
+ choices = (0..1000).collect { |el|
+ source.choice
+ }.uniq.sort
+ choices.should == source
end
it "returns nil for empty arrays" do
View
50 core/array/sample_spec.rb
@@ -3,11 +3,16 @@
describe "Array#sample" do
ruby_version_is "1.8.8" do
- it "selects a random value from the array" do
- a = [1, 2, 3, 4]
- 10.times {
- a.include?(a.sample).should be_true
- }
+ it "selects a value from the array" do
+ [4].sample.should eql(4)
+ end
+
+ it "returns a distribution of results" do
+ source = [0,1,2,3,4]
+ samples = (0..1000).collect { |el|
+ source.sample
+ }.uniq.sort
+ samples.should eql(source)
end
it "returns nil for empty arrays" do
@@ -19,17 +24,30 @@
lambda { [1, 2].sample(-1) }.should raise_error(ArgumentError)
end
- it "returns different random values from the array" do
- a = [1, 2, 3, 4]
- sum = []
- 42.times {
- pair = a.sample(2)
- sum.concat(pair)
- (pair - a).should == []
- pair[0].should_not == pair[1]
+ it "selects values from the array" do
+ source = [1,2,3,4]
+ source.should include(*source.sample(2))
+ end
+
+ it "does not return the same value if the array is unique" do
+ source = [1, 2, 3, 4]
+ 1000.times {
+ pair = source.sample(2)
+ pair[0].should_not eql(pair[1])
}
- a.should == [1, 2, 3, 4]
- (a - sum).should == [] # Might fail once every 2^40 times ...
+ end
+
+ it "may return the same value if the array is not unique" do
+ source = [4, 4]
+ source.sample(2).should eql([4,4])
+ end
+
+ it "returns a distribution of results" do
+ source = [0,1,2,3,4]
+ samples = (0..1000).collect { |el|
+ source.sample(3)
+ }.flatten.uniq.sort
+ samples.should eql(source)
end
it "tries to convert n to an Integer using #to_int" do
@@ -41,7 +59,7 @@
a.sample(obj).size.should == 2
end
- it "returns all values with n big enough" do
+ it "returns all values when n >= array size" do
a = [1, 2, 3, 4]
a.sample(4).sort.should == a
a.sample(5).sort.should == a
Something went wrong with that request. Please try again.