seeing_is_believing 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ proving_grounds/*
2
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
@@ -0,0 +1,34 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ seeing_is_believing (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ builder (3.1.4)
10
+ cucumber (1.2.1)
11
+ builder (>= 2.1.2)
12
+ diff-lcs (>= 1.1.3)
13
+ gherkin (~> 2.11.0)
14
+ json (>= 1.4.6)
15
+ diff-lcs (1.1.3)
16
+ gherkin (2.11.5)
17
+ json (>= 1.4.6)
18
+ json (1.7.6)
19
+ rspec (2.12.0)
20
+ rspec-core (~> 2.12.0)
21
+ rspec-expectations (~> 2.12.0)
22
+ rspec-mocks (~> 2.12.0)
23
+ rspec-core (2.12.2)
24
+ rspec-expectations (2.12.1)
25
+ diff-lcs (~> 1.1.3)
26
+ rspec-mocks (2.12.1)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ cucumber (~> 1.2.1)
33
+ rspec (~> 2.12.0)
34
+ seeing_is_believing!
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path '../../lib', __FILE__
4
+ require 'seeing_is_believing/example_use'
5
+
6
+ ARGV.each do |filename|
7
+ puts SeeingIsBelieving::ExampleUse.new(File.read filename).call
8
+ end
@@ -0,0 +1,35 @@
1
+ Feature: Running the binary
2
+ They say seeing is believing. So to believe that this works
3
+ I want to see that it works by making a binary to use the lib.
4
+
5
+ It should be approximately like xmpfilter, except that it should
6
+ run against every line.
7
+
8
+ Scenario: Some basic functionality
9
+ Given the file "f.rb":
10
+ """
11
+ a = '12'
12
+ a + a
13
+
14
+ 5.times do |i|
15
+ i * 2
16
+ end
17
+ """
18
+ When I run "seeing_is_believing f.rb"
19
+ And stderr is empty
20
+ Then the exit status is 0
21
+ And stdout is:
22
+ """
23
+ a = '12' # => "12"
24
+ a + a # => "1212"
25
+
26
+ 5.times do |i|
27
+ i * 2 # => 0, 2, 4, 6, 8
28
+ end # => 5
29
+
30
+ """
31
+
32
+ Scenario: Printing within the file
33
+ Scenario: Raising exceptions
34
+ Scenario: Requiring other files
35
+ Scenario: Syntactically invalid file
@@ -0,0 +1,19 @@
1
+ Given 'the file "$filename":' do |filename, body|
2
+ CommandLineHelpers.write_file filename, body
3
+ end
4
+
5
+ When 'I run "$command"' do |command|
6
+ @last_executed = CommandLineHelpers.execute command
7
+ end
8
+
9
+ Then /^(stderr|stdout) is:$/ do |stream_name, output|
10
+ @last_executed.send(stream_name).should == output
11
+ end
12
+
13
+ Then 'the exit status is $status' do |status|
14
+ @last_executed.exitstatus.to_s.should == status
15
+ end
16
+
17
+ Then /^(stderr|stdout) is empty$/ do |stream_name|
18
+ @last_executed.send(stream_name).should == ''
19
+ end
@@ -0,0 +1,54 @@
1
+ require 'fileutils'
2
+ require 'open3'
3
+
4
+
5
+ module CommandLineHelpers
6
+ Invocation = Struct.new :stdout, :stderr, :status do
7
+ def exitstatus
8
+ status.exitstatus
9
+ end
10
+ end
11
+
12
+ extend self
13
+
14
+ def write_file(filename, body)
15
+ in_proving_grounds do
16
+ File.open(filename, 'w') { |file| file.write body }
17
+ end
18
+ end
19
+
20
+ def execute(command)
21
+ in_proving_grounds do
22
+ command = "PATH=#{bin_dir}:$PATH #{command}"
23
+ Invocation.new *Open3.capture3(command)
24
+ end
25
+ end
26
+
27
+ def in_proving_grounds(&block)
28
+ Dir.chdir proving_grounds_dir, &block
29
+ end
30
+
31
+ def proving_grounds_dir
32
+ File.join root_dir, 'proving_grounds'
33
+ end
34
+
35
+ def root_dir
36
+ @root_dir ||= begin
37
+ dir = Dir.pwd
38
+ until Dir.glob("#{dir}/*").map(&File.method(:basename)).include?("features")
39
+ dir = File.expand_path File.dirname dir
40
+ end
41
+ dir
42
+ end
43
+ end
44
+
45
+ def make_proving_grounds
46
+ FileUtils.mkdir_p proving_grounds_dir
47
+ end
48
+
49
+ def bin_dir
50
+ File.join root_dir, "bin"
51
+ end
52
+ end
53
+
54
+ CommandLineHelpers.make_proving_grounds
@@ -0,0 +1,58 @@
1
+ require 'stringio'
2
+
3
+ require 'seeing_is_believing/result'
4
+ require 'seeing_is_believing/expression_list'
5
+
6
+ # might not work on windows b/c of assumptions about line ends
7
+ class SeeingIsBelieving
8
+ def initialize(string_or_stream)
9
+ @stream = to_stream string_or_stream
10
+ @result = Result.new
11
+ end
12
+
13
+ def call
14
+ @memoized_result ||= begin
15
+ program = ''
16
+ program << expression_list.call until stream.eof?
17
+ $seeing_is_believing_current_result = @result # can we make this a threadlocal var on the class?
18
+ TOPLEVEL_BINDING.eval record_exceptions_in(program), 'program.rb', 1
19
+ @result
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :stream
26
+
27
+ def expression_list
28
+ @expression_list ||= ExpressionList.new generator: lambda { stream.gets.chomp },
29
+ on_complete: lambda { |line, children, completions, line_number|
30
+ @result.contains_line_number line_number
31
+ expression = [line, *children, *completions].join("\n")
32
+ if expression == ''
33
+ expression
34
+ else
35
+ record_yahself expression, line_number
36
+ end
37
+ }
38
+ end
39
+
40
+ def to_stream(string_or_stream)
41
+ return string_or_stream if string_or_stream.respond_to? :gets
42
+ StringIO.new string_or_stream
43
+ end
44
+
45
+ def record_yahself(line, line_number)
46
+ "($seeing_is_believing_current_result.record_result(#{line_number}, (#{line})))\n"
47
+ end
48
+
49
+ def record_exceptions_in(code)
50
+ require 'pp'
51
+ "begin;"\
52
+ "#{code};"\
53
+ "rescue Exception;"\
54
+ "line_number = $!.backtrace.first[/:\\d+:/][1..-2].to_i;"\
55
+ "$seeing_is_believing_current_result.record_exception line_number, $!;"\
56
+ "end"
57
+ end
58
+ end
@@ -0,0 +1,40 @@
1
+ require 'seeing_is_believing'
2
+
3
+ class SeeingIsBelieving
4
+ class ExampleUse
5
+ def initialize(body)
6
+ self.body = body
7
+ end
8
+
9
+ def call
10
+ body.each_line.with_index 1 do |line, index|
11
+ write_line line.chomp, results[index], line_length
12
+ end
13
+ output
14
+ end
15
+
16
+ private
17
+
18
+ attr_accessor :body
19
+
20
+ def results
21
+ @results ||= SeeingIsBelieving.new(body).call
22
+ end
23
+
24
+ def output
25
+ @result ||= ''
26
+ end
27
+
28
+ def write_line(line, results, line_length)
29
+ if results.any?
30
+ output << sprintf("%-#{line_length}s# => %s\n", line, results.join(', '))
31
+ else
32
+ output << line << "\n"
33
+ end
34
+ end
35
+
36
+ def line_length
37
+ @line_length ||= body.each_line.map(&:chomp).map(&:length).max + 2
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,74 @@
1
+ require 'open3'
2
+
3
+ class SeeingIsBelieving
4
+ class ExpressionList
5
+ PendingExpression = Struct.new :expression, :children do
6
+ def inspect(debug=false)
7
+ colour1 = colour2 = lambda { |s| s }
8
+ colour1 = lambda { |s| "\e[30;46m#{s}\e[0m" } if debug
9
+ colour2 = lambda { |s| "\e[37;46m#{s}\e[0m" } if debug
10
+ "#{colour1['PE(']}#{colour2[expression.inspect]}#{colour1[',' ]}#{colour2[children.inspect]}#{colour1[')']}"
11
+ end
12
+ end
13
+
14
+ def initialize(options)
15
+ self.debug_stream = options.fetch :debug_stream, $stdout
16
+ self.should_debug = options.fetch :debug, false
17
+ self.generator = options.fetch :generator
18
+ self.on_complete = options.fetch :on_complete
19
+ self.line_number = 0
20
+ self.list = []
21
+ end
22
+
23
+ def call
24
+ expression = nil
25
+ begin
26
+ generate
27
+ expression = reduce_expressions
28
+ end until list.empty?
29
+ expression
30
+ end
31
+
32
+ private
33
+
34
+ attr_accessor :debug_stream, :should_debug, :generator, :on_complete, :line_number, :list
35
+
36
+ def generate
37
+ @line_number += 1
38
+ expression = generator.call
39
+ debug? && debug("GENERATED: #{expression.inspect}, ADDING IT TO #{inspected_list}")
40
+ @list << PendingExpression.new(expression, [])
41
+ end
42
+
43
+ def inspected_list
44
+ "[#{@list.map { |pe| pe.inspect debug? }.join(', ')}]"
45
+ end
46
+
47
+ def debug?
48
+ @should_debug
49
+ end
50
+
51
+ def debug(message)
52
+ @debug_stream.puts message
53
+ end
54
+
55
+ def reduce_expressions
56
+ @list.size.times do |i|
57
+ expression = @list[i..-1].map(&:expression).join("\n") # must use newline otherwise can get expressions like `a\\+b` that should be `a\\\n+b`, former is invalid
58
+ next unless valid_ruby? expression
59
+ result = on_complete.call(@list[i].expression,
60
+ @list[i].children,
61
+ @list[i+1..-1].map { |pe| [pe.expression, pe.children] }.flatten, # hmmm, not sure this is really correct, but it allows it to work for my use cases
62
+ @line_number)
63
+ @list = @list[0, i]
64
+ @list[i-1].children << result unless @list.empty?
65
+ debug? && debug("RESULT: #{result.inspect}, LIST: [#{@list.map { |e| e.inspect debug? }.join(', ')}]")
66
+ return result
67
+ end
68
+ end
69
+
70
+ def valid_ruby?(expression)
71
+ Open3.capture3('ruby -c', stdin_data: expression).last.success?
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,48 @@
1
+ class SeeingIsBelieving
2
+ class Result
3
+ attr_reader :min_line_number, :max_line_number
4
+
5
+ def initialize
6
+ @min_line_number = @max_line_number = 1
7
+ end
8
+
9
+ def record_result(line_number, value)
10
+ contains_line_number line_number
11
+ results[line_number] << value.inspect
12
+ value
13
+ end
14
+
15
+ def record_exception(line_number, exception)
16
+ contains_line_number line_number
17
+ @exception_line_number = line_number
18
+ @exception = exception
19
+ end
20
+
21
+ def [](line_number)
22
+ results[line_number]
23
+ end
24
+
25
+ # uhm, maybe switch to #each and including Enumerable?
26
+ def to_a
27
+ (min_line_number..max_line_number).map do |line_number|
28
+ [line_number, [*self[line_number], *Array(exception_at line_number)]]
29
+ end
30
+ end
31
+
32
+ def contains_line_number(line_number)
33
+ @min_line_number = line_number if line_number < @min_line_number
34
+ @max_line_number = line_number if line_number > @max_line_number
35
+ end
36
+
37
+ private
38
+
39
+ def exception_at(line_number)
40
+ return unless @exception_line_number == line_number
41
+ @exception
42
+ end
43
+
44
+ def results
45
+ @results ||= Hash.new { |hash, line_number| hash[line_number] = [] }
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ class SeeingIsBelieving
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "seeing_is_believing/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "seeing_is_believing"
7
+ s.version = SeeingIsBelieving::VERSION
8
+ s.authors = ["Josh Cheek"]
9
+ s.email = ["josh.cheek@gmail.com"]
10
+ s.homepage = "https://github.com/JoshCheek/seeing_is_believing"
11
+ s.summary = %q{Records results of every line of code in your file}
12
+ s.description = %q{Records the results of every line of code in your file (intended to be like xmpfilter), inspired by Brett Victor's JavaScript example in his talk "Inventing on Principle"}
13
+
14
+ s.rubyforge_project = "seeing_is_believing"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rspec", "~> 2.12.0"
22
+ s.add_development_dependency "cucumber", "~> 1.2.1"
23
+ end
@@ -0,0 +1,107 @@
1
+ require 'seeing_is_believing/expression_list'
2
+
3
+ describe SeeingIsBelieving::ExpressionList do
4
+
5
+ def call(generations, options={}, &block)
6
+ options = { on_complete: block, generator: -> { generations.shift || raise("EMPTY!") } }.merge(options)
7
+ described_class.new(options).call
8
+ end
9
+
10
+ example 'example: multiple children' do
11
+ block_invocations = 0
12
+ result = call %w[a( b+ c x\\ + y )] do |line, children, completions, line_number|
13
+ case line_number
14
+ when 3
15
+ line.should == 'b+'
16
+ children.should == []
17
+ completions.should == ['c']
18
+ block_invocations += 1
19
+ 'b+c'
20
+ when 6
21
+ line.should == 'x\\'
22
+ children.should == []
23
+ completions.should == ['+', 'y']
24
+ block_invocations += 10
25
+ 'x\\+y'
26
+ when 7
27
+ line.should == 'a('
28
+ children.should == ['b+c', 'x\\+y']
29
+ completions.should == [')']
30
+ block_invocations += 100
31
+ 'ALL DONE!'
32
+ else
33
+ raise "line_number: #{line_number.inspect}"
34
+ end
35
+ end
36
+ result.should == 'ALL DONE!'
37
+ block_invocations.should == 111
38
+ end
39
+
40
+
41
+ example 'example: nested children' do
42
+ block_invocations = 0
43
+ expressions = [ '[1].map do |n1|',
44
+ ' [2].map do |n2|',
45
+ ' n1 + n2',
46
+ ' end',
47
+ 'end',
48
+ ]
49
+ result = call expressions do |line, children, completions, line_number|
50
+ case line_number
51
+ when 3
52
+ [line, children, completions].should == [' n1 + n2', [], []]
53
+ block_invocations += 1
54
+ when 4
55
+ [line, children, completions].should == [' [2].map do |n2|', [' n1 + n2'], [' end']]
56
+ block_invocations += 10
57
+ when 5
58
+ [line, children, completions].should == ['[1].map do |n1|',
59
+ [" [2].map do |n2|\n n1 + n2\n end"],
60
+ ['end']]
61
+ block_invocations += 100
62
+ else
63
+ raise "line_number: #{line_number.inspect}"
64
+ end
65
+ [line, *children, *completions].join("\n")
66
+ end
67
+ block_invocations.should == 111
68
+ result.should == "[1].map do |n1|\n"\
69
+ " [2].map do |n2|\n"\
70
+ " n1 + n2\n"\
71
+ " end\n"\
72
+ "end"
73
+ end
74
+
75
+
76
+ example 'example: completions that have children' do
77
+ block_invocations = 0
78
+ expressions = [ "[1].map do |n1|",
79
+ "[2].map do |n2|",
80
+ "n1 + n2",
81
+ "end end",
82
+ ]
83
+ result = call expressions do |line, children, completions, line_number|
84
+ case line_number
85
+ when 3
86
+ [line, children, completions].should == ["n1 + n2", [], []]
87
+ block_invocations += 1
88
+ when 4
89
+ # not really sure what this *should* be like, but if this is the result,
90
+ # then it will work for the use cases I need it for
91
+ [line, *children, *completions].should == ["[1].map do |n1|",
92
+ "[2].map do |n2|",
93
+ "n1 + n2",
94
+ 'end end']
95
+ block_invocations += 10
96
+ else
97
+ raise "line_number: #{line_number.inspect}"
98
+ end
99
+ [line, *children, *completions].join("\n")
100
+ end
101
+ block_invocations.should == 11
102
+ result.should == "[1].map do |n1|\n"\
103
+ "[2].map do |n2|\n"\
104
+ "n1 + n2\n"\
105
+ "end end"\
106
+ end
107
+ end
@@ -0,0 +1,116 @@
1
+ require 'seeing_is_believing'
2
+ require 'stringio'
3
+
4
+ describe SeeingIsBelieving do
5
+ def invoke(input)
6
+ described_class.new(input).call
7
+ end
8
+
9
+ def values_for(input)
10
+ invoke(input).to_a.map(&:last)
11
+ end
12
+
13
+ def stream(string)
14
+ StringIO.new string
15
+ end
16
+
17
+ it 'takes a string or stream and returns a result of the line numbers (counting from 1) and each inspected result from that line' do
18
+ input = "1+1\n'2'+'2'"
19
+ output = [[1, ["2"]], [2, ['"22"']]]
20
+ invoke(input).to_a.should == output
21
+ invoke(stream input).to_a.should == output
22
+ end
23
+
24
+ it 'remembers context of previous lines' do
25
+ values_for("a=12\na*2").should == [['12'], ['24']]
26
+ end
27
+
28
+ it 'can be invoked multiple times, returning the same result' do
29
+ believer = described_class.new("$xyz||=1\n$xyz+=1")
30
+ believer.call.to_a.should == [[1, ['1']], [2, ['2']]]
31
+ believer.call.to_a.should == [[1, ['1']], [2, ['2']]]
32
+ end
33
+
34
+ it 'is evaluated at the toplevel' do
35
+ values_for('self').should == [['main']]
36
+ end
37
+
38
+ it 'records the value immediately, so that it is correct even if the result is mutated' do
39
+ values_for("a = 'a'\na << 'b'").should == [['"a"'], ['"ab"']]
40
+ end
41
+
42
+ it 'records each value when a line is evaluated multiple times' do
43
+ values_for("(1..2).each do |i|\ni\nend").should == [[], ['1', '2'], ['1..2']]
44
+ end
45
+
46
+ it 'evalutes to an empty array for lines that it cannot understand' do
47
+ values_for("[3].map do |n|\n n*2\n end").should == [[], ['6'], ['[6]']]
48
+ values_for("[1].map do |n1|
49
+ [2].map do |n2|
50
+ n1 + n2
51
+ end
52
+ end").should == [[], [], ['3'], ['[3]'], ['[[3]]']]
53
+
54
+ values_for("[1].map do |n1|
55
+ [2].map do |n2| n1 + n2
56
+ end
57
+ end").should == [[], [], ['[3]'], ['[[3]]']]
58
+
59
+ values_for("[1].map do |n1|
60
+ [2].map do |n2|
61
+ n1 + n2 end
62
+ end").should == [[], [], ['[3]'], ['[[3]]']]
63
+
64
+ values_for("[1].map do |n1|
65
+ [2].map do |n2|
66
+ n1 + n2 end end").should == [[], [], ['[[3]]']]
67
+
68
+ values_for("[1].map do |n1|
69
+ [2].map do |n2| n1 + n2 end end").should == [[], ['[[3]]']]
70
+
71
+ values_for("[1].map do |n1| [2].map do |n2| n1 + n2 end end").should == [['[[3]]']]
72
+
73
+ values_for("[1].map do |n1|
74
+ [2].map do |n2|
75
+ n1 + n2
76
+ end end").should == [[], [], ['3'], ['[[3]]']]
77
+
78
+ values_for("[1].map do |n1| [2].map do |n2|
79
+ n1 + n2
80
+ end end").should == [[], ['3'], ['[[3]]']]
81
+
82
+ values_for("[1].map do |n1| [2].map do |n2|
83
+ n1 + n2 end end").should == [[], ['[[3]]']]
84
+
85
+ values_for("[1].map do |n1| [2].map do |n2|
86
+ n1 + n2 end
87
+ end").should == [[], [], ['[[3]]']]
88
+
89
+ values_for("1 +
90
+ 2").should == [[], ['3']]
91
+ end
92
+
93
+ it 'has no output for empty lines' do
94
+ values_for('').should == [[]]
95
+ values_for("1\n\n2").should == [['1'],[],['2']]
96
+ end
97
+
98
+ it 'stops executing on errors and reports them' do
99
+ result = values_for("12\nraise Exception, 'omg!'\n12")
100
+ result[0].should == ['12']
101
+
102
+ result[1].size.should == 1
103
+ exception = result[1].first
104
+ exception.class.should == Exception
105
+ exception.message.should == 'omg!'
106
+
107
+ result[2].should == []
108
+ result.size.should == 3
109
+ end
110
+
111
+ # something about printing to stdout
112
+ # something about printing to stderr
113
+ # something about when the whole input is invalid
114
+ # something about multi-line strings
115
+ # does not fuck up __LINE__ macro
116
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: seeing_is_believing
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Josh Cheek
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70170924125400 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.12.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70170924125400
25
+ - !ruby/object:Gem::Dependency
26
+ name: cucumber
27
+ requirement: &70170924124580 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.2.1
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70170924124580
36
+ description: Records the results of every line of code in your file (intended to be
37
+ like xmpfilter), inspired by Brett Victor's JavaScript example in his talk "Inventing
38
+ on Principle"
39
+ email:
40
+ - josh.cheek@gmail.com
41
+ executables:
42
+ - seeing_is_believing
43
+ extensions: []
44
+ extra_rdoc_files: []
45
+ files:
46
+ - .gitignore
47
+ - Gemfile
48
+ - Gemfile.lock
49
+ - bin/seeing_is_believing
50
+ - features/binary.feature
51
+ - features/step_definitions/steps.rb
52
+ - features/support/env.rb
53
+ - lib/seeing_is_believing.rb
54
+ - lib/seeing_is_believing/example_use.rb
55
+ - lib/seeing_is_believing/expression_list.rb
56
+ - lib/seeing_is_believing/result.rb
57
+ - lib/seeing_is_believing/version.rb
58
+ - seeing_is_believing.gemspec
59
+ - spec/expression_list_spec.rb
60
+ - spec/seeing_is_believing_spec.rb
61
+ homepage: https://github.com/JoshCheek/seeing_is_believing
62
+ licenses: []
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project: seeing_is_believing
81
+ rubygems_version: 1.8.17
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Records results of every line of code in your file
85
+ test_files:
86
+ - features/binary.feature
87
+ - features/step_definitions/steps.rb
88
+ - features/support/env.rb
89
+ - spec/expression_list_spec.rb
90
+ - spec/seeing_is_believing_spec.rb