tryouts 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.txt ADDED
@@ -0,0 +1,6 @@
1
+ TRYOUTS, CHANGES
2
+
3
+
4
+ #### 0.4.0 (2009-06-05) ###############################
5
+
6
+ NOTE: Initial public release
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2009 Solutious Inc, Delano Mandelbaum
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,122 @@
1
+ = Tryouts - v0.5 ALPHA
2
+
3
+ Tryouts is a high-level testing library for your command-line applications and Ruby codes.
4
+
5
+ *WORK IN PROGRESS*
6
+
7
+ 2009-05-24 - A BBQ started nearby as I was writing this documentation. It's incomplete and I'm sorry about that but I can tell you that this BBQ smells really, really good.
8
+
9
+
10
+ == Terminology
11
+
12
+ Tryouts is a bit different than other testing libraries. Test definitions are organized in a similar way as Shoulda tests (although the keywords in the syntax are different).
13
+
14
+ * Tryout: a set of drills (like basketball tryouts)
15
+ * Drill: a test.
16
+ * Dream: the expected outcome of a drill.
17
+
18
+
19
+ == Testing a command-line application (a CLI)
20
+
21
+ Tryouts tests command-line applications by comparing expected output with the actual output. Let's say we have an executable called mockout and we want to test the following commands:
22
+
23
+ $ bin/executable
24
+ $ bin/executable -f yaml
25
+
26
+ The tryout definition would look like this:
27
+
28
+ command :executable, "path/2/executable"
29
+
30
+ tryout "Common Usage", :cli do
31
+ drill "No Command"
32
+ drill "YAML Output", :f, 'yaml'
33
+ end
34
+
35
+ And the expected output would be defined like this:
36
+
37
+ dream "No Command" do
38
+ output inline(%Q{
39
+ Date: 2009-02-16
40
+ Players: d-bam, alberta, birds, condor man
41
+ Owners: greg, rupaul, telly, prince kinko
42
+ })
43
+ end
44
+ dream "YAML Output" do
45
+ format :yaml
46
+ output ({
47
+ "Date" => "2009-02-16",
48
+ "Players" => ["d-bam", "alberta", "birds", "condor man"],
49
+ "Owners" => ["greg", "rupaul", "telly", "prince kinko"]
50
+ })
51
+ end
52
+
53
+ == Testing Ruby codes (an API)
54
+
55
+ Tryouts employs the same approach for testing Ruby codes. The return value of the drill block is compared to the expectation defined by the dream. Here is an example of including dreams inside the tryout definition.
56
+
57
+ library :caesars, LIBRARY_PATH
58
+
59
+ tryout "Common Usage", :api do
60
+ dream "Some Maths", 3
61
+ drill "Some Maths" do
62
+ 12 / 4
63
+ end
64
+
65
+ dream "A Block", Proc, :class # Test the class type instead of the value
66
+ drill "A Block" do
67
+ Proc.new do
68
+ :anything
69
+ end
70
+ end
71
+ end
72
+
73
+
74
+ == ALPHA Notice
75
+
76
+ This library is very new (est. 2009-05-19) and has not been vetted by the scrutiny of time. In particular you can expect:
77
+
78
+ * Ugly/awkward output from the tryouts executable. I wrote the core functionality that I needed to start writing tryouts for my other projects. I haven't spent very much time on reporting yet. However, this will change!
79
+ * The test definition syntax may change in future releases.
80
+ * Unexpected errors.
81
+
82
+ == 3 Ways to define tryouts
83
+ There are three ways to define an instance of this class:
84
+ * In +_tryouts.rb+ files using the DSL syntax. One file per Tryouts object.
85
+ * See: http://github.com/delano/tryouts/blob/master/tryouts/mockoutcli_tryouts.rb
86
+ * In standalone ruby files using a hybrid DSL/OO syntax. Supports multiple
87
+ Tryouts objects per file.
88
+ * See: http://github.com/delano/tryouts/blob/master/tryouts/standalone_test.rb
89
+ * With regular object-oriented syntax.
90
+ * See: http://tryouts.rubyforge.org/
91
+
92
+ == On Threads
93
+
94
+ Tryouts does some funky stuff to make it simple to write tests. This "funky
95
+ stuff" means that this library is *not thread-safe at definition-time*. However, once
96
+ all tryouts files are parsed (or in OO-syntax, once all objects are created), this
97
+ class should be *thread-safe at drill-time*.
98
+
99
+ == More Info
100
+
101
+ * Check out the sourcecodes[http://github.com/delano/tryouts]
102
+ * Read the rdocs[http://tryouts.rubyforge.org/]
103
+ * About Solutious[http://solutious.com/about/]
104
+
105
+ == Thanks
106
+
107
+ * Everyone at Utrecht.rb
108
+
109
+ == Credits
110
+
111
+ * Delano (@solutious.com)
112
+
113
+ == Related Projects
114
+
115
+ * Context[http://github.com/jeremymcanally/context/tree/master]
116
+ * Testy[http://github.com/ahoward/testy/tree/master]
117
+ * Expectations[http://expectations.rubyforge.org/]
118
+ * Zebra[http://github.com/giraffesoft/zebra/tree/master]
119
+
120
+ == License
121
+
122
+ See: LICENSE.txt
data/Rakefile ADDED
@@ -0,0 +1,80 @@
1
+ require 'rubygems'
2
+ require 'rake/clean'
3
+ require 'rake/gempackagetask'
4
+ require 'hanna/rdoctask'
5
+ require 'fileutils'
6
+ include FileUtils
7
+
8
+ task :default => :package
9
+
10
+ # CONFIG =============================================================
11
+
12
+ # Change the following according to your needs
13
+ README = "README.rdoc"
14
+ CHANGES = "CHANGES.txt"
15
+ LICENSE = "LICENSE.txt"
16
+
17
+ # Files and directories to be deleted when you run "rake clean"
18
+ CLEAN.include [ 'pkg', '*.gem', '.config', 'doc']
19
+
20
+ # Virginia assumes your project and gemspec have the same name
21
+ name = (Dir.glob('*.gemspec') || ['tryouts']).first.split('.').first
22
+ load "#{name}.gemspec"
23
+ version = @spec.version
24
+
25
+ # That's it! The following defaults should allow you to get started
26
+ # on other things.
27
+
28
+
29
+ # TESTS/SPECS =========================================================
30
+
31
+
32
+
33
+ # INSTALL =============================================================
34
+
35
+ Rake::GemPackageTask.new(@spec) do |p|
36
+ p.need_tar = true if RUBY_PLATFORM !~ /mswin/
37
+ end
38
+
39
+ task :release => [ :rdoc, :package ]
40
+ task :install => [ :rdoc, :package ] do
41
+ sh %{sudo gem install pkg/#{name}-#{version}.gem}
42
+ end
43
+ task :uninstall => [ :clean ] do
44
+ sh %{sudo gem uninstall #{name}}
45
+ end
46
+
47
+
48
+ # RUBYFORGE RELEASE / PUBLISH TASKS ==================================
49
+
50
+ if @spec.rubyforge_project
51
+ desc 'Publish website to rubyforge'
52
+ task 'publish:rdoc' => 'doc/index.html' do
53
+ sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/"
54
+ end
55
+
56
+ desc 'Public release to rubyforge'
57
+ task 'publish:gem' => [:package] do |t|
58
+ sh <<-end
59
+ rubyforge add_release -o Any -a #{CHANGES} -f -n #{README} #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
60
+ rubyforge add_file -o Any -a #{CHANGES} -f -n #{README} #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
61
+ end
62
+ end
63
+ end
64
+
65
+
66
+
67
+ # RUBY DOCS TASK ==================================
68
+
69
+ Rake::RDocTask.new do |t|
70
+ t.rdoc_dir = 'doc'
71
+ t.title = @spec.summary
72
+ t.options << '--line-numbers' << '-A cattr_accessor=object'
73
+ t.options << '--charset' << 'utf-8'
74
+ t.rdoc_files.include(LICENSE)
75
+ t.rdoc_files.include(README)
76
+ t.rdoc_files.include(CHANGES)
77
+ t.rdoc_files.include('bin/tryouts')
78
+ t.rdoc_files.include('lib/**/*.rb')
79
+ end
80
+
data/bin/mockout ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # = Mockout
4
+ #
5
+ # This mock is used to generate test output for Tryouts itself.
6
+ # It is otherwise uninteresting!
7
+ #
8
+
9
+ require 'rubygems'
10
+ require 'drydock'
11
+ require 'yaml'
12
+
13
+ begin; require 'json'; rescue LoadError; end # json may not be installed
14
+
15
+ module DrillCLI
16
+ extend Drydock
17
+
18
+ global :f, :format, String, "One of: json, yaml, string (default)"
19
+
20
+
21
+ default :info
22
+ debug :on
23
+
24
+ data = {
25
+ "Date" => "2009-02-16",
26
+ "Owners" => ["greg", "rupaul", "telly", "prince kinko"],
27
+ "Players" => ["d-bam", "alberta", "birds", "condor man"]
28
+ }
29
+
30
+ option :e, :echo, "Echo the arguments"
31
+ command :info do |obj|
32
+ format = obj.global.format.nil? ? nil : "to_#{obj.global.format}"
33
+ format = nil if obj.global.format == 'string'
34
+ if obj.option.echo
35
+ puts obj.argv
36
+ else
37
+ if format.nil?
38
+ data.keys.sort.each do |n|
39
+ val = data[n]
40
+ val = val.join(', ') if val.is_a?(Array)
41
+ puts "%9s %44s" % ["#{n}:", val]
42
+ end
43
+ else
44
+ puts data.send(format)
45
+ end
46
+ end
47
+ end
48
+
49
+ end
data/bin/tryouts ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ TRYOUTS_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..'))
4
+
5
+ local_libs = %w{tryouts net-scp amazon-ec2 aws-s3 caesars drydock rye storable sysinfo annoy}
6
+ local_libs.each { |dir| $:.unshift File.join(TRYOUTS_HOME, '..', dir, 'lib') }
7
+
8
+ require 'drydock'
9
+ require 'tryouts'
10
+ require 'tryouts/cli'
11
+
12
+ # = TryoutsCLI
13
+ #
14
+ # This is the Drydock definition for the bin/tryouts executable
15
+ module TryoutsCLI
16
+ extend Drydock
17
+
18
+ debug :on
19
+ default :run, :with_args
20
+
21
+ global :q, :quiet, "Decrease output"
22
+ global :v, :verbose, "Increase output" do
23
+ @verbose ||= 0
24
+ @verbose += 1
25
+ end
26
+
27
+ about "Run tryouts from current working directory"
28
+ argv :files
29
+ command :run => Tryouts::CLI::Run
30
+
31
+ about "Show dreams available from the current working directory"
32
+ argv :files
33
+ command :dreams => Tryouts::CLI::Run
34
+
35
+ about "Show tryouts available from the current working directory"
36
+ argv :files
37
+ command :list => Tryouts::CLI::Run
38
+
39
+ end
@@ -0,0 +1,94 @@
1
+
2
+ class Tryouts; module CLI
3
+
4
+ # = Run
5
+ #
6
+ # The logic bin/tryouts uses for running tryouts.
7
+ class Run < Drydock::Command
8
+
9
+ def init
10
+ @tryouts_globs = [GYMNASIUM_GLOB, File.join(Dir.pwd, '*_tryouts.rb')]
11
+ end
12
+
13
+ def dreams
14
+ load_available_tryouts_files
15
+ if @global.verbose > 0
16
+ puts Tryouts.dreams.to_yaml
17
+ else
18
+ Tryouts.dreams.each_pair do |n,dreams|
19
+ puts n
20
+ dreams.each_pair do |n, dream|
21
+ puts " " << n
22
+ dream.each_pair do |n, drill|
23
+ puts " " << n
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def run
31
+ if @global.verbose > 0
32
+ puts "RUBY #{RUBY_VERSION} - #{RUBY_PLATFORM}"
33
+ end
34
+
35
+ load_available_tryouts_files
36
+
37
+ successes = []
38
+ Tryouts.instances.each_pair do |group,tryouts_inst|
39
+ puts '', '-'*60 unless @global.quiet
40
+ puts group
41
+ puts " #{tryouts_inst.paths.join("\n ")}" if @global.verbose > 0
42
+ tryouts_inst.tryouts.each_pair do |name,to|
43
+ to.run
44
+ to.report
45
+ STDOUT.flush
46
+ successes << to.success?
47
+ end
48
+ end
49
+ unless successes.member?(false)
50
+ puts $/, "All your dreams came true" unless @global.quiet
51
+ end
52
+ end
53
+
54
+ def list
55
+ load_available_tryouts_files
56
+ ##if @global.verbose > 2
57
+ ## puts Tryouts.instances.to_yaml # BUG: Raises "can't dump anonymous class Class"
58
+ ##else
59
+ Tryouts.instances.each_pair do |n,tryouts_inst|
60
+ puts n
61
+ if @global.verbose > 0
62
+ puts " #{tryouts_inst.paths.join("\n ")}"
63
+ end
64
+ tryouts_inst.tryouts.each_pair do |t2,tryout|
65
+ puts " " << tryout.name
66
+ tryout.drills.each do |drill|
67
+ puts " " << drill.name
68
+ end
69
+ end
70
+ end
71
+ ##end
72
+ end
73
+
74
+ private
75
+ def load_available_tryouts_files
76
+ @tryouts_files = []
77
+ # If file paths were given, check those only.
78
+ unless @argv.empty?
79
+ @argv.each do |file|
80
+ file = File.join(file, '**', '*_tryouts.rb') if File.directory?(file)
81
+ @tryouts_files += Dir.glob file
82
+ end
83
+ # Otherwise check the default globs
84
+ else
85
+ @tryouts_globs.each do |glob|
86
+ @tryouts_files += Dir.glob glob
87
+ end
88
+ end
89
+ @tryouts_files.uniq! # Don't load the same file twice
90
+ @tryouts_files.each { |file| Tryouts.parse_file file }
91
+ puts @tryouts_files if @global.verbose > 0
92
+ end
93
+ end
94
+ end; end
@@ -0,0 +1,15 @@
1
+
2
+ class Tryouts
3
+
4
+ # = CLI
5
+ #
6
+ # A namespace for the tryouts executable (bin/tryouts) logic.
7
+ #
8
+ # This convention comes from Drydock (http://github.com/delano/drydock)
9
+ #
10
+ module CLI;end
11
+
12
+ end
13
+
14
+ require 'tryouts/cli/run'
15
+
@@ -0,0 +1,105 @@
1
+
2
+ class Tryouts::Drill
3
+ # = Response
4
+ #
5
+ # A generic base class for Dream and Reality
6
+ #
7
+ class Response
8
+ attr_accessor :output, :format, :rcode, :emsg, :backtrace
9
+ def initialize(output=nil, format=nil, rcode=0)
10
+ @output, @format, @rcode = output, format, (rcode || 0)
11
+ @output = nil if @output.nil?
12
+ normalize!
13
+ end
14
+
15
+ def ==(other)
16
+ return false if other.nil?
17
+ @rcode == other.rcode &&
18
+ @emsg == other.emsg &&
19
+ compare_output(other)
20
+ end
21
+
22
+ def rcode(val=nil); @rcode = val unless val.nil?; normalize!; @rcode; end
23
+ def output(val=nil); @output = val unless val.nil?; normalize!; @output; end
24
+ def emsg(val=nil); @emsg = val unless val.nil?; normalize!; @emsg; end
25
+ def format(val=nil); @format = val unless val.nil?; normalize!; @format; end
26
+
27
+ def output=(val); @output = val; normalize!; @output; end
28
+ def rcode=(val); @rcode = val; normalize!; @rcode; end
29
+ def format=(val); @format = val; normalize!; @format; end
30
+ def emsg=(val); @emsg = val; normalize!; @emsg; end
31
+
32
+ # Enforce the following restrictions on the data fields:
33
+ # * +rcode+ is an Integer
34
+ # * +format+ is a Symbol
35
+ # This method is called automatically any time a field is updated.
36
+ def normalize!
37
+ @rcode = @rcode.to_i if @rcode.is_a?(String)
38
+ @format = @format.to_sym if @format.is_a?(String)
39
+ end
40
+ def compare_output(other)
41
+ #
42
+ # The dream is always on the left (Does your dream match reality?)
43
+ # This check is important so we can support both:
44
+ # @dream == @reality
45
+ # AND
46
+ # @reality == @dream
47
+ #
48
+ if self.is_a? Tryouts::Drill::Dream
49
+ dream, reality = self, other
50
+ elsif self.is_a? Tryouts::Drill::Reality
51
+ dream, reality = other, self
52
+ else
53
+ # If self isn't a Dream or a Reality, then we have a problem
54
+ return false
55
+ end
56
+
57
+ # The matching statement will be the return value.
58
+ if dream.format.nil?
59
+ dream.output == reality.output
60
+ elsif reality.respond_to? dream.format
61
+ reality.output.send(dream.format) == dream.output
62
+ else
63
+ false
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+
71
+ # = Dream
72
+ #
73
+ # Contains the expected response of a Drill
74
+ #
75
+ class Dream < Tryouts::Drill::Response
76
+
77
+ def self.from_block(definition)
78
+ d = Tryouts::Drill::Dream.new
79
+ d.from_block definition
80
+ d
81
+ end
82
+
83
+ def from_block(definition)
84
+ instance_eval &definition
85
+ self.normalize!
86
+ self
87
+ end
88
+
89
+ # Takes a String +val+ and splits the lines into an Array. Each line
90
+ # has
91
+ def inline(val=nil)
92
+ lines = (val.split($/) || [])
93
+ lines.shift if lines.first.strip == ""
94
+ lines.pop if lines.last.strip == ""
95
+ lines
96
+ end
97
+ end
98
+
99
+ # = Reality
100
+ #
101
+ # Contains the actual response of a Drill
102
+ #
103
+ class Reality < Tryouts::Drill::Response; end
104
+
105
+ end
@@ -0,0 +1,49 @@
1
+
2
+
3
+ class Tryouts; class Drill; module Sergeant
4
+
5
+ # = CLI
6
+ #
7
+ # The sergeant responsible for running command-line interface drills.
8
+ #
9
+ class CLI
10
+
11
+ attr_reader :rbox
12
+
13
+ # An Array of arguments to be sent to +rbox.send(*rbox_args)+
14
+ attr_accessor :rbox_args
15
+
16
+ def initialize(*args)
17
+ @rbox_args = args
18
+ @rbox = Rye::Box.new
19
+ end
20
+
21
+ # NOTE: Context is ignored for the CLI Sergeant.
22
+ def run(block, context=nil, &inline)
23
+ # A Proc object takes precedence over an inline block.
24
+ runtime = (block.nil? ? inline : block)
25
+ response = Tryouts::Drill::Reality.new
26
+ begin
27
+ if runtime.nil?
28
+ ret = @rbox.send *rbox_args
29
+ else
30
+ ret = @rbox.instance_eval &runtime
31
+ end
32
+ response.rcode = ret.exit_code
33
+ response.output = ret.stdout.size == 1 ? ret.stdout.first : Array.new(ret.stdout) # Cast the Rye::Rap object
34
+ response.emsg = ret.stderr unless ret.stderr.empty?
35
+ rescue Rye::CommandNotFound => ex
36
+ response.rcode = -2
37
+ response.emsg = "[#{@rbox.host}] Command not found: #{ex.message}"
38
+ response.backtrace = ex.backtrace
39
+ rescue Rye::CommandError => ex
40
+ response.rcode = ex.exit_code
41
+ response.output = ex.stdout
42
+ response.emsg = ex.stderr
43
+ end
44
+ response
45
+ end
46
+
47
+ end
48
+
49
+ end; end; end
@@ -0,0 +1,98 @@
1
+
2
+
3
+ class Tryouts
4
+
5
+ # = Drill
6
+ #
7
+ # This class represents a drill. A drill is single test.
8
+ #
9
+ class Drill
10
+
11
+ require 'tryouts/drill/response'
12
+ require 'tryouts/drill/sergeant/cli'
13
+ require 'tryouts/drill/sergeant/api'
14
+
15
+ class NoSergeant < Tryouts::Exception; end
16
+
17
+ # A symbol specifying the drill type. One of: :cli, :api
18
+ attr_reader :dtype
19
+ # The name of the drill. This should match the name used in the dreams file.
20
+ attr_reader :name
21
+ # A Proc object which contains the drill logic.
22
+ attr_reader :drill
23
+
24
+ # A Sergeant object which executes the drill
25
+ attr_reader :sergeant
26
+ # A Dream object (the expected output of the test)
27
+ attr_reader :dream
28
+ # A Reality object (the actual output of the test)
29
+ attr_reader :reality
30
+
31
+ def initialize(name, dtype, *drill_args, &drill)
32
+ @name, @dtype, @drill = name, dtype, drill
33
+ @sergeant = hire_sergeant *drill_args
34
+ # For CLI drills, a block takes precedence over inline args.
35
+ # A block will contain multiple shell commands (see Rye::Box#batch)
36
+ drill_args = [] if dtype == :cli && drill.is_a?(Proc)
37
+ @reality = Tryouts::Drill::Reality.new
38
+ end
39
+
40
+ def hire_sergeant(*drill_args)
41
+ if @dtype == :cli
42
+ Tryouts::Drill::Sergeant::CLI.new(*drill_args)
43
+ elsif @dtype == :api
44
+ Tryouts::Drill::Sergeant::API.new(drill_args.first)
45
+ else
46
+ raise NoSergeant, "What is #{@dtype}?"
47
+ end
48
+ end
49
+
50
+ def run(context=nil)
51
+ return false if @dream.nil?
52
+ begin
53
+ print Tryouts::DRILL_MSG % @name
54
+ @reality = @sergeant.run @drill, context
55
+ process_reality
56
+ rescue => ex
57
+ @reality.rcode = -2
58
+ @reality.emsg, @reality.backtrace = ex.message, ex.backtrace
59
+ end
60
+ note = @dream ? discrepency.join(', ') : 'nodream'
61
+ puts self.success? ? "PASS" : "FAIL (#{note})"
62
+ self.success?
63
+ end
64
+
65
+ def success?
66
+ return false if @dream.nil? || @reality.nil?
67
+ @dream == @reality
68
+ end
69
+
70
+ def discrepency
71
+ diffs = []
72
+ if @dream
73
+ diffs << "rcode" if @dream.rcode != @reality.rcode
74
+ diffs << "output" if !@dream.compare_output(@reality)
75
+ diffs << "emsg" if @dream.emsg != @reality.emsg
76
+ end
77
+ diffs
78
+ end
79
+
80
+ def add_dream(d)
81
+ @dream = d if d.is_a?(Tryouts::Drill::Dream)
82
+ end
83
+
84
+ private
85
+ # Use the :format provided in the dream to convert the output from reality
86
+ def process_reality
87
+ @reality.normalize!
88
+ return unless @dream && @dream.format
89
+ if @dream.format == :to_yaml
90
+ @reality.output = YAML.load(@reality.output.join("\n"))
91
+ elsif @dream.format == :to_json
92
+ @reality.output = JSON.load(@reality.output.join("\n"))
93
+ end
94
+
95
+ #p [:process, @name, @dream.format, @reality.output]
96
+ end
97
+
98
+ end; end