delano-tryouts 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.txt CHANGED
@@ -1,9 +1,14 @@
1
1
  TRYOUTS, CHANGES
2
2
 
3
3
 
4
- #### 0.6.4 (2009-06-25) ###############################
4
+ #### 0.7.1 (2009-06-26) ###############################
5
5
 
6
- NOTE: command testing (:cli) is still disabled.
6
+ * FIXED: Updated manifest in gemspec
7
+ * CHANGE: :cli testing is disabled indefinitely
8
+ * ADDED: Found Muggsy Bogues
9
+
10
+
11
+ #### 0.7.0 (2009-06-25) ###############################
7
12
 
8
13
  * FIXED: Stash wasn't being displayed in the drill report
9
14
  * CHANGE: CLI is now formatted to be 80 characters wide.
@@ -80,11 +85,11 @@ NOTE: command testing (:cli) is disabled.
80
85
  * ADDED: Drill stash!
81
86
  * ADDED: xdream and better handling for drills and dreams with no name
82
87
 
88
+
83
89
  #### 0.4.1 (2009-06-07) ###############################
84
90
 
85
91
  * CHANGE: The CLI output is no longer terrifyingly ugly
86
92
 
87
-
88
93
  #### 0.4.0 (2009-06-05) ###############################
89
94
 
90
95
  NOTE: Initial public release
data/lib/tryouts.rb CHANGED
@@ -32,7 +32,7 @@ class Tryouts
32
32
  # Raised when there is a problem loading or parsing a Tryouts::Drill::Dream object
33
33
  class BadDreams < Exception; end
34
34
 
35
- VERSION = "0.7.0"
35
+ VERSION = "0.7.1"
36
36
 
37
37
  require 'tryouts/mixins'
38
38
  require 'tryouts/tryout'
@@ -0,0 +1,51 @@
1
+
2
+
3
+
4
+
5
+ class Tryouts; class Drill; module Sergeant
6
+
7
+ # = Benchmark
8
+ #
9
+ # The sergeant responsible for running benchmarks
10
+ #
11
+ class Benchmark
12
+ require 'benchmark'
13
+
14
+ attr_reader :output
15
+
16
+ # * +reps+ Number of times to execute drill (>= 0, <= 30). Default: 3
17
+ #
18
+ def initialize(reps=nil)
19
+ @reps = (1..30).include?(reps) ? reps : 5
20
+ @stats = Tryouts::Stats.new
21
+ end
22
+
23
+ def run(block, context, &inline)
24
+ # A Proc object takes precedence over an inline block.
25
+ runtime = (block.nil? ? inline : block)
26
+ response = Tryouts::Drill::Reality.new
27
+ if runtime.nil?
28
+ raise "We need a block to benchmark"
29
+ else
30
+ begin
31
+
32
+ @reps.times do
33
+ run = ::Benchmark.realtime &runtime
34
+ @stats.sample run
35
+ end
36
+
37
+ response.output = @stats
38
+
39
+ rescue => e
40
+ puts e.message, e.backtrace if Tryouts.verbose > 2
41
+ response.output = false
42
+ response.etype = e.class
43
+ response.error = e.message
44
+ response.trace = e.backtrace
45
+ end
46
+ end
47
+ response
48
+ end
49
+
50
+ end
51
+ end; end; end
@@ -0,0 +1,132 @@
1
+
2
+ require 'benchmark'
3
+
4
+
5
+ class Tryouts; class Drill; module Sergeant
6
+
7
+ # = RBenchmark
8
+ #
9
+ # This is an implementation of Better-Benchmark:
10
+ # http://github.com/Pistos/better-benchmark/
11
+ #
12
+ # NOTE: It's a work in progress and currently not functioning
13
+ #
14
+ # See also: http://www.graphpad.com/articles/interpret/Analyzing_two_groups/wilcoxon_matched_pairs.htm
15
+ #
16
+ module RBenchmark
17
+
18
+ VERSION = '0.7.0'
19
+
20
+ class ComparisonPartial
21
+ def initialize( block, options )
22
+ @block1 = block
23
+ @options = options
24
+ end
25
+
26
+ def with( &block2 )
27
+ times1 = []
28
+ times2 = []
29
+
30
+ (1..@options[ :iterations ]).each do |iteration|
31
+ if @options[ :verbose ]
32
+ $stdout.print "."; $stdout.flush
33
+ end
34
+
35
+ times1 << ::Benchmark.realtime do
36
+ @options[ :inner_iterations ].times do |i|
37
+ @block1.call( iteration )
38
+ end
39
+ end
40
+ times2 << ::Benchmark.realtime do
41
+ @options[ :inner_iterations ].times do |i|
42
+ block2.call( iteration )
43
+ end
44
+ end
45
+ end
46
+
47
+ r = RSRuby.instance
48
+ wilcox_result = r.wilcox_test( times1, times2 )
49
+
50
+ {
51
+ :results1 => {
52
+ :times => times1,
53
+ :mean => r.mean( times1 ),
54
+ :stddev => r.sd( times1 ),
55
+ },
56
+ :results2 => {
57
+ :times => times2,
58
+ :mean => r.mean( times2 ),
59
+ :stddev => r.sd( times2 ),
60
+ },
61
+ :p => wilcox_result[ 'p.value' ],
62
+ :W => wilcox_result[ 'statistic' ][ 'W' ],
63
+ :significant => (
64
+ wilcox_result[ 'p.value' ] < @options[ :required_significance ]
65
+ ),
66
+ }
67
+ end
68
+ alias to with
69
+ end
70
+
71
+ # Options:
72
+ # :iterations
73
+ # The number of times to execute the pair of blocks.
74
+ # :inner_iterations
75
+ # Used to increase the time taken per iteration.
76
+ # :required_significance
77
+ # Maximum allowed p value in order to declare the results statistically significant.
78
+ # :verbose
79
+ # Whether to print a dot for each iteration (as a sort of progress meter).
80
+ #
81
+ # To use better-benchmark properly, it is important to set :iterations and
82
+ # :inner_iterations properly. There are a few things to bear in mind:
83
+ #
84
+ # (1) Do not set :iterations too high. It should normally be in the range
85
+ # of 10-20, but can be lower. Over 25 should be considered too high.
86
+ # (2) Execution time for one run of the blocks under test should not be too
87
+ # small (or else random variance will muddle the results). Aim for at least
88
+ # 1.0 seconds per iteration.
89
+ # (3) Minimize the proportion of any warmup time (and cooldown time) of one
90
+ # block run.
91
+ #
92
+ # In order to achieve these goals, you will need to tweak :inner_iterations
93
+ # based on your situation. The exact number you should use will depend on
94
+ # the strength of the hardware (CPU, RAM, disk), and the amount of work done
95
+ # by the blocks. For code blocks that execute extremely rapidly, you may
96
+ # need hundreds of thousands of :inner_iterations.
97
+ def self.compare_realtime( options = {}, &block1 )
98
+ require 'rsruby'
99
+
100
+ options[ :iterations ] ||= 20
101
+ options[ :inner_iterations ] ||= 1
102
+ options[ :required_significance ] ||= 0.01
103
+
104
+ if options[ :iterations ] > 30
105
+ warn "The number of iterations is set to #{options[ :iterations ]}. " +
106
+ "Using too many iterations may make the test results less reliable. " +
107
+ "It is recommended to increase the number of :inner_iterations instead."
108
+ end
109
+
110
+ ComparisonPartial.new( block1, options )
111
+ end
112
+
113
+ def self.report_on( result )
114
+ puts
115
+ puts( "Set 1 mean: %.3f s" % [ result[ :results1 ][ :mean ] ] )
116
+ puts( "Set 1 std dev: %.3f" % [ result[ :results1 ][ :stddev ] ] )
117
+ puts( "Set 2 mean: %.3f s" % [ result[ :results2 ][ :mean ] ] )
118
+ puts( "Set 2 std dev: %.3f" % [ result[ :results2 ][ :stddev ] ] )
119
+ puts "p.value: #{result[ :p ]}"
120
+ puts "W: #{result[ :W ]}"
121
+ puts(
122
+ "The difference (%+.1f%%) %s statistically significant." % [
123
+ ( ( result[ :results2 ][ :mean ] - result[ :results1 ][ :mean ] ) / result[ :results1 ][ :mean ] ) * 100,
124
+ result[ :significant ] ? 'IS' : 'IS NOT'
125
+ ]
126
+ )
127
+ end
128
+ end
129
+
130
+ end; end; end
131
+
132
+
@@ -0,0 +1,92 @@
1
+ # Copyright (c) 2005 Zed A. Shaw
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
+ # for more information.
6
+
7
+ # Stolen from:
8
+ # http://mongrel.rubyforge.org/browser/trunk/lib/mongrel/stats.rb
9
+ #
10
+ # A very simple little class for doing some basic fast statistics sampling.
11
+ # You feed it either samples of numeric data you want measured or you call
12
+ # Stats.tick to get it to add a time delta between the last time you called it.
13
+ # When you're done either call sum, sumsq, n, min, max, mean or sd to get
14
+ # the information. The other option is to just call dump and see everything.
15
+ #
16
+ # It does all of this very fast and doesn't take up any memory since the samples
17
+ # are not stored but instead all the values are calculated on the fly.
18
+ class Tryouts
19
+ class Stats
20
+ attr_reader :sum, :sumsq, :n, :min, :max
21
+
22
+ def initialize(name=:unknown)
23
+ @name = name
24
+ reset
25
+ end
26
+
27
+ # Resets the internal counters so you can start sampling again.
28
+ def reset
29
+ @sum = 0.0
30
+ @sumsq = 0.0
31
+ @last_time = Time.new
32
+ @n = 0.0
33
+ @min = 0.0
34
+ @max = 0.0
35
+ end
36
+
37
+ # Adds a sampling to the calculations.
38
+ def sample(s)
39
+ @sum += s
40
+ @sumsq += s * s
41
+ if @n == 0
42
+ @min = @max = s
43
+ else
44
+ @min = s if @min > s
45
+ @max = s if @max < s
46
+ end
47
+ (@n+=1).to_f
48
+ end
49
+
50
+ # Dump this Stats object with an optional additional message.
51
+ def dump(msg = "", out=STDERR)
52
+ out.puts "#{msg}: #{self.to_s}"
53
+ end
54
+
55
+ # Returns a common display (used by dump)
56
+ def to_s
57
+ "[#{@name}]: SUM=%0.4f, SUMSQ=%0.4f, N=%0.4f, MEAN=%0.4f, SD=%0.4f, MIN=%0.4f, MAX=%0.4f" % [@sum, @sumsq, @n, mean, sd, @min, @max]
58
+ end
59
+
60
+
61
+ # Calculates and returns the mean for the data passed so far.
62
+ def mean
63
+ @sum / @n
64
+ end
65
+
66
+ # Calculates the standard deviation of the data so far.
67
+ def sdev
68
+ # (sqrt( ((s).sumsq - ( (s).sum * (s).sum / (s).n)) / ((s).n-1) ))
69
+ begin
70
+ Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) ).to_f
71
+ rescue Errno::EDOM
72
+ 0.0
73
+ end
74
+ end
75
+
76
+
77
+ # Adds a time delta between now and the last time you called this. This
78
+ # will give you the average time between two activities.
79
+ #
80
+ # An example is:
81
+ #
82
+ # t = Stats.new("do_stuff")
83
+ # 10000.times { do_stuff(); t.tick }
84
+ # t.dump("time")
85
+ #
86
+ def tick
87
+ now = Time.now
88
+ sample(now - @last_time)
89
+ @last_time = now
90
+ end
91
+ end
92
+ end
data/tryouts.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  @spec = Gem::Specification.new do |s|
2
2
  s.name = "tryouts"
3
3
  s.rubyforge_project = "tryouts"
4
- s.version = "0.7.0"
4
+ s.version = "0.7.1"
5
5
  s.summary = "Tryouts are high-level tests for your Ruby code. May all your dreams come true!"
6
6
  s.description = s.summary
7
7
  s.author = "Delano Mandelbaum"
@@ -48,12 +48,20 @@
48
48
  lib/tryouts/drill/context.rb
49
49
  lib/tryouts/drill/response.rb
50
50
  lib/tryouts/drill/sergeant/api.rb
51
+ lib/tryouts/drill/sergeant/benchmark.rb
51
52
  lib/tryouts/drill/sergeant/cli.rb
53
+ lib/tryouts/drill/sergeant/rbenchmark.rb
52
54
  lib/tryouts/mixins.rb
53
55
  lib/tryouts/mixins/hash.rb
54
56
  lib/tryouts/orderedhash.rb
57
+ lib/tryouts/stats.rb
55
58
  lib/tryouts/tryout.rb
56
59
  tryouts.gemspec
60
+ tryouts/01_mixins_tryouts.rb
61
+ tryouts/10_syntax_tryouts.rb
62
+ tryouts/20_cli_tryouts.rb
63
+ tryouts/50_class_context_tryouts.rb
64
+ tryouts/standalone_test.rb
57
65
  )
58
66
 
59
67
  s.has_rdoc = true
@@ -0,0 +1,26 @@
1
+
2
+ library :tryouts, File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ group "Mixins"
5
+
6
+
7
+
8
+ test_hash = {
9
+ :level1 => {
10
+ :level2 => {},
11
+ :apples => 1
12
+ },
13
+ :help => [1, :a, 900001, Object.new, Hash],
14
+ :oranges => 90
15
+ }
16
+
17
+
18
+ tryouts "Hash" do
19
+ setup do
20
+
21
+ end
22
+
23
+ drill "knows the deepest point", test_hash.deepest_point, 3
24
+ drill "has a last method", {}, :last, :respond_to?
25
+
26
+ end
@@ -0,0 +1,40 @@
1
+
2
+ tryout "DSL Syntax", :api do
3
+
4
+ dream 4770744
5
+ drill "can specify dream above the drill" do
6
+ 4770744
7
+ end
8
+
9
+ dream Array, :class
10
+ drill "can pass based on output object class" do
11
+ [1,2,3]
12
+ end
13
+
14
+ dream NameError, :exception
15
+ drill "can pass based on exception class" do
16
+ bad_method_call
17
+ end
18
+
19
+ drill "dreamless drills that return true will pass" do
20
+ true
21
+ end
22
+
23
+ drill "inline true values will pass too", true
24
+ drill "can specify inline return values", :food, :food
25
+ drill "can specify match format", 'mahir', /..hi./i, :match
26
+
27
+ dream "big"
28
+ dream String, :class
29
+ dream /\Ab.g\z/, :match
30
+ drill "can handle multiple dreams" do
31
+ "big"
32
+ end
33
+
34
+ drill "can specify gt (>) format", 2, 1, :gt
35
+ drill "can specify gte (>=) format", 2, 2, :gte
36
+ drill "can specify lt (<) format", 1, 2, :lt
37
+ drill "can specify lte (<=) format", 2, 2, :lte
38
+
39
+ drill "can run arbitrary formats", [3,1,2], [1,2,3], :sort
40
+ end
@@ -0,0 +1,46 @@
1
+
2
+ TRYOUTS_HOME = File.expand_path(File.join(File.dirname(__FILE__), ".."))
3
+ MOCKOUT_PATH = File.join(TRYOUTS_HOME, "bin", "mockout")
4
+
5
+ ##group "mockout cli"
6
+ ##command :mockout, MOCKOUT_PATH
7
+ ##dreams File.join(GYMNASIUM_HOME, 'mockoutcli_dreams.rb')
8
+ ##
9
+ ##tryout "Common Usage" do
10
+ ## drill "No args", :info
11
+ ## drill "YAML Output", :f, :yaml, :info
12
+ ## drill "JSON Output", :f, :json, :info
13
+ ##end
14
+ ##
15
+ ##tryout "inline dream that passes", :cli, :mockout do
16
+ ## output = ["we expect mockout to", "echo these lines back"]
17
+ ##
18
+ ## # $ bin/mockout sergeant -e "we expect mockout to" "echo these lines back"
19
+ ## drill "echo arguments", :info, :e, output[0], output[1]
20
+ ## dream "echo arguments", output
21
+ ##end
22
+ ##
23
+ ##tryout "inline dream that fails", :cli, :mockout do
24
+ ## dream "echo arguments", "The dream does"
25
+ ## drill "echo arguments", :info, :e, "not match reality"
26
+ ##end
27
+ ##
28
+ ##
29
+ ##dreams "Common Usage" do
30
+ ## dream "No Comman" do
31
+ ## output inline(%Q{
32
+ ## Date: 2009-02-16
33
+ ## Owners: greg, rupaul, telly, prince kinko
34
+ ## Players: d-bam, alberta, birds, condor man
35
+ ## })
36
+ ## end
37
+ ## dream "YAML Output" do
38
+ ## format :to_yaml
39
+ ## output ({
40
+ ## "Date" => "2009-02-16",
41
+ ## "Players" => ["d-bam", "alberta", "birds", "condor man"],
42
+ ## "Owners" => ["greg", "rupaul", "telly", "prince kinko"]
43
+ ## })
44
+ ## end
45
+ ##end
46
+
@@ -0,0 +1,30 @@
1
+
2
+ group "Class context tests"
3
+
4
+ tryout "Setting class variables", :api do
5
+ setup do
6
+ class ::Olivia; end
7
+ @@from_setup = Olivia.new # NOTE: module_eval seems to solve this problem
8
+ @from_setup = true
9
+ end
10
+
11
+ drill "can't access class var created in setup (1.9 only)", NameError, :exception do
12
+ @@from_setup
13
+ end
14
+
15
+ drill "can access class var created in setup (1.8 only)", 'Olivia' do
16
+ @@from_setup.class.to_s
17
+ end
18
+
19
+ drill "create class var", 'Olivia' do
20
+ @@from_drill = Olivia.new
21
+ @@from_drill.class.to_s
22
+ end
23
+
24
+ drill "can access class var created in drill", 'Olivia' do
25
+ @@from_drill.class.to_s
26
+ end
27
+
28
+ dream /\w\d\w \d\w\d/, :match
29
+ drill "Knows where Santa Claus lives", 'H0H 0H0'
30
+ end
@@ -0,0 +1,37 @@
1
+ ## Tryouts - Standalone Test
2
+ #
3
+ # This tryout is intended to be run on its own,
4
+ # without the tryouts exectuable. That's why it's
5
+ # named _test.rb, so tryouts won't see it. It uses
6
+ # the same dreams as MockoutCLI.
7
+ #
8
+ # Usage: ruby tryouts/standalone_test.rb
9
+ #
10
+
11
+ TRYOUTS_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..'))
12
+ TRYOUTS_LIB = File.join(TRYOUTS_HOME, 'lib')
13
+ MOCKOUT_PATH = File.join(TRYOUTS_HOME, 'bin', 'mockout')
14
+ $:.unshift TRYOUTS_LIB # Put our local lib in first place
15
+
16
+ require 'tryouts'
17
+
18
+ class StandaloneCLI < Tryouts
19
+ command :mockout, MOCKOUT_PATH
20
+ #dreams File.join(TRYOUTS_HOME, 'tryouts', 'mockoutcli_dreams.rb')
21
+
22
+ tryout "common usage" do
23
+ drill 'no command'
24
+ drill 'no args', :sergeant
25
+ drill 'yaml output', :f, 'yaml', :sergeant
26
+ drill 'json output', :f, 'json', :sergeant
27
+ end
28
+
29
+ tryout "inline dream will pass", :cli, :mockout do
30
+ output = ['we expect mockout to', 'echo these lines back']
31
+ dream output
32
+ # $ bin/mockout sergeant -e 'we expect mockout to' 'echo these lines back'
33
+ drill 'echo arguments', :sergeant, :e, *output
34
+ end
35
+ end
36
+
37
+ StandaloneCLI.run
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delano-tryouts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -65,12 +65,20 @@ files:
65
65
  - lib/tryouts/drill/context.rb
66
66
  - lib/tryouts/drill/response.rb
67
67
  - lib/tryouts/drill/sergeant/api.rb
68
+ - lib/tryouts/drill/sergeant/benchmark.rb
68
69
  - lib/tryouts/drill/sergeant/cli.rb
70
+ - lib/tryouts/drill/sergeant/rbenchmark.rb
69
71
  - lib/tryouts/mixins.rb
70
72
  - lib/tryouts/mixins/hash.rb
71
73
  - lib/tryouts/orderedhash.rb
74
+ - lib/tryouts/stats.rb
72
75
  - lib/tryouts/tryout.rb
73
76
  - tryouts.gemspec
77
+ - tryouts/01_mixins_tryouts.rb
78
+ - tryouts/10_syntax_tryouts.rb
79
+ - tryouts/20_cli_tryouts.rb
80
+ - tryouts/50_class_context_tryouts.rb
81
+ - tryouts/standalone_test.rb
74
82
  has_rdoc: true
75
83
  homepage: http://github.com/delano/tryouts
76
84
  post_install_message: