delano-tryouts 0.7.0 → 0.7.1

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/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: