butterfly_net 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,169 @@
1
+ Butterfly Net
2
+ =============
3
+
4
+ [Home page and source]: http://butterflynet.org
5
+ [Rubygems page]: http://rubygems.org/gems/butterfly_net
6
+
7
+ Author: Chris Smith (quartzmo -at- gmail.com)
8
+
9
+
10
+ ## DESCRIPTION
11
+
12
+ IRB and Rails console history captured as Test::Unit tests. (RSpec and others hopefully soon to come.)
13
+
14
+
15
+ ## INSTALL
16
+
17
+ Butterfly Net is available as a gem from rubygems.org (http://rubygems.org/gems/butterfly_net), or as source from
18
+ butterflynet.org.
19
+
20
+ sudo gem install butterfly_net
21
+
22
+ To automatically require Butterfly Net on every IRB session, add the following to your ~/.irbrc:
23
+
24
+ require 'rubygems'
25
+ require 'butterfly_net'
26
+
27
+
28
+ ## USAGE
29
+
30
+ ### Command methods
31
+
32
+ The following commands can be used in any IRB-based console.
33
+
34
+ * bn, bn_open- Open a new test case, closing the current test case if one exists. Args: file_name:string (optional; '.rb' will appended if needed)
35
+ * bnc, bn_close - Close the active test case, and write the output to a file.
36
+ * m, bn_method - Close the current test method (or block), naming it with the arg method_name:string (optional)
37
+
38
+ ### Example Usage in IRB
39
+
40
+ $ irb
41
+ irb(main):001:0> bn 'irb_tests'
42
+ => true
43
+ irb(main):002:0> a = 1
44
+ => 1
45
+ irb(main):003:0> a += 2
46
+ => 3
47
+ irb(main):004:0> m 'plusequals'
48
+ => true
49
+ irb(main):005:0> require 'bigdecimal'
50
+ => true
51
+ irb(main):006:0> infinity = BigDecimal('Infinity')
52
+ => #<BigDecimal:114ed34,'Infinity',4(4)>
53
+ irb(main):007:0> BigDecimal.new("1.0") / BigDecimal.new("0.0") == infinity
54
+ => true
55
+ irb(main):008:0> m 'bigdecimal_infinity'
56
+ => true
57
+ irb(main):009:0> exit
58
+ butterfly_net: irb_tests.rb closed
59
+ true
60
+ $ cat irb_tests.rb
61
+ require "test/unit"
62
+
63
+ # IRB test capture courtesy of butterfly_net (butterflynet.org)
64
+ class MyTest < Test::Unit::TestCase
65
+
66
+ def test_plusequals
67
+ a = 1
68
+ assert_equal(3, a += 2)
69
+ end
70
+
71
+ def test_bigdecimal_infinity
72
+ require 'bigdecimal'
73
+ infinity = BigDecimal('Infinity')
74
+ assert(BigDecimal.new("1.0") / BigDecimal.new("0.0") == infinity)
75
+ end
76
+
77
+ end
78
+ $ ruby irb_tests.rb
79
+ Loaded suite irb_tests
80
+ Started
81
+ ..
82
+ Finished in 0.001603 seconds.
83
+
84
+ 2 tests, 2 assertions, 0 failures, 0 errors
85
+
86
+
87
+ ### Ruby on Rails console
88
+
89
+ For repeatable tests, be sure to load the Rails test environment with "./script/console test".
90
+ In a Rails project, you can run all tests with the standard rake command 'rake test',
91
+ or an individual test by adding the test directory to the path with the option -I when you invoke Ruby.
92
+
93
+ chris$ ./script/console test
94
+ Loading test environment (Rails 2.3.4)
95
+ >> bn "test/unit/person_console_test"
96
+ . . .
97
+ >> Person.count
98
+ => 2
99
+ >> exit
100
+ . . .
101
+ chris$ ruby -Itest test/unit/person_console_test.rb
102
+ . . .
103
+ 1 tests, 1 assertions, 0 failures, 0 errors
104
+
105
+
106
+ ## KNOWN ISSUES
107
+
108
+ This section covers issues which may not be resolved quickly. Feel free to lend a hand!
109
+
110
+ ### Object inspect output
111
+
112
+ Butterfly Net relies on an expectation value responding with valid Ruby code to the inspect method, which is the case for core
113
+ classes such as Hash and Array. However, it's not the case with most classes, many of which respond with the familiar
114
+ #<...> notation, which can't be interpreted.
115
+
116
+ For example:
117
+
118
+ assert_equal(#<BigDecimal:11511d8,'Infinity',4(24)>, BigDecimal.new("1.0") / BigDecimal.new("0.0")) # doesn't work
119
+
120
+ The workaround is to assign expected values to a variable. Of course, you have to know what to expect in order to do this,
121
+ which may take a few tries. Sorry.
122
+
123
+
124
+ ### Inline variable assignment
125
+
126
+ Butterfly Net tries to detect simple assignments, such as "a = 1", in order to write them out clearly,
127
+ without enclosing assertions. In some cases this causes it to miss statements that should be tested.
128
+
129
+ For example:
130
+
131
+ irb(main):002:0> a = 1; a + 1
132
+ => 2
133
+ irb(main):003:0> "a=1".split('=')
134
+ => ["a", "1"]
135
+
136
+ results in
137
+
138
+ def test_1
139
+ a = 1; a + 1 # should have been a = 1; assert_equal(2, a + 1)
140
+ "a=1".split('=') # should have been assert_equal(["a", "1"],"a=1".split('='))
141
+ end
142
+
143
+ In order to avoid this issue, just put assignments (and anything that looks like an assignment) on separate lines.
144
+
145
+
146
+ ## LICENSE
147
+
148
+ The MIT License
149
+
150
+ Copyright (c) 2010 Chris Smith
151
+
152
+ Permission is hereby granted, free of charge, to any person obtaining
153
+ a copy of this software and associated documentation files (the
154
+ 'Software'), to deal in the Software without restriction, including
155
+ without limitation the rights to use, copy, modify, merge, publish,
156
+ distribute, sublicense, and/or sell copies of the Software, and to
157
+ permit persons to whom the Software is furnished to do so, subject to
158
+ the following conditions:
159
+
160
+ The above copyright notice and this permission notice shall be
161
+ included in all copies or substantial portions of the Software.
162
+
163
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
164
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
165
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
166
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
167
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
168
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
169
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -21,8 +21,9 @@ module ButterflyNet
21
21
  file_name += ".rb" unless file_name =~ /.rb$/
22
22
  @file = FileWriter.new(file_name, start_index)
23
23
  Kernel.at_exit { puts @file.close if @file; @file = nil }
24
- puts "butterfly_net: #{file_name} opened at Readline::HISTORY ##{start_index}"
25
24
  true
25
+ rescue
26
+ false
26
27
  end
27
28
 
28
29
  def bn_close
@@ -37,9 +38,20 @@ module ButterflyNet
37
38
  end
38
39
  end
39
40
 
41
+ def bn_method(method_name=nil)
42
+ check_for_readline
43
+ if @file
44
+ @file.new_assertion_set(method_name)
45
+ else
46
+ puts "butterfly_net: First invoke 'bn' or 'bn_open' to begin a session"
47
+ false
48
+ end
49
+ end
50
+
40
51
 
41
52
  alias :bn :bn_open
42
53
  alias :bnc :bn_close
54
+ alias :m :bn_method
43
55
 
44
56
  private
45
57
 
@@ -7,33 +7,60 @@ module ButterflyNet
7
7
  def initialize(file_name, start_index)
8
8
  @file_name = file_name
9
9
  @start_index = start_index
10
+ @adapter = TestUnitAdapter.new
10
11
  end
11
12
 
12
- def new_assertion_set
13
-
14
- end
15
-
16
-
17
- def close
13
+ def new_assertion_set(method_name)
18
14
  lines = Readline::HISTORY.to_a
19
15
  @end_index ||= Readline::HISTORY.size - 3 # in case of no call to 'bn_close'
20
16
  if @end_index < 0 || lines[@start_index..@end_index].empty?
21
- puts "butterfly_net: #{@file_name} closed, no file written to disk"
22
17
  false
23
18
  else
24
- adapter = TestUnitAdapter.new
19
+
25
20
 
26
21
  lines[@start_index..@end_index].each do |line|
27
- adapter.add_command(line)
22
+ @adapter.add_command(line)
28
23
  end
29
24
 
30
- adapter.create_file(@file_name)
25
+ @adapter.close_assertion_set(method_name)
26
+ @start_index = Readline::HISTORY.size - 1
27
+ @end_index = nil
31
28
 
32
- puts "butterfly_net: #{@file_name} closed after Readline::HISTORY ##{@end_index}"
33
29
  true
34
30
  end
35
- rescue Exception => msg
36
- puts "butterfly_net: Error generating tests: #{msg}"
31
+ rescue Exception => e
32
+ puts "butterfly_net: Error generating tests: #{e}"
33
+ puts e.backtrace
34
+ false
35
+ end
36
+
37
+
38
+ def close
39
+ lines = Readline::HISTORY.to_a
40
+ @end_index ||= Readline::HISTORY.size - 3 # in case of no call to 'bn_close'
41
+ # if @adapter.empty?
42
+ # puts "butterfly_net: #{@file_name} closed, no file written to disk."
43
+ #
44
+ # false
45
+ #
46
+ # else
47
+ if @end_index < 0 || lines[@start_index..@end_index].empty?
48
+ puts "butterfly_net: #{@file_name} closed"
49
+ else
50
+ lines[@start_index..@end_index].each do |line|
51
+ @adapter.add_command(line)
52
+ end
53
+ puts "butterfly_net: #{@file_name} closed, with #{@end_index - @start_index + 1} lines, from '#{lines[@start_index]}' to '#{lines[@end_index]}'"
54
+
55
+ end
56
+
57
+ @adapter.create_file(@file_name)
58
+
59
+ true
60
+ # end
61
+ rescue Exception => e
62
+ puts "butterfly_net: Error generating tests: #{e}"
63
+ puts e.backtrace
37
64
  false
38
65
  end
39
66
 
@@ -12,22 +12,28 @@ module ButterflyNet
12
12
  @assertion_sets.last << line
13
13
  end
14
14
 
15
- def close_assertion_set
15
+ def close_assertion_set(method_name = nil)
16
+ @assertion_sets.last.name = (method_name ? method_name : @assertion_sets.size)
16
17
  @assertion_sets << TestUnitMethod.new
17
18
  end
18
19
 
20
+ def empty?
21
+ @assertion_sets.empty?
22
+ end
23
+
19
24
  def create_file(filename)
20
- return nil if @assertion_sets.empty?
25
+ return nil if empty?
21
26
 
22
27
  #todo detect existing file, and delete last 'end' line
23
28
  file = File.open(filename, 'a+') # starts at end of file if file exists
24
29
 
25
30
  if defined? ActiveSupport::TestCase # rails # todo support earlier versions of rails
26
- file.puts "require \"test_helper\"\n\nclass TempTest < ActiveSupport::TestCase"
31
+ file.puts "require \"test_helper\"\n\n# script/console test capture courtesy of butterfly_net (butterflynet.org)\nclass MyTest < ActiveSupport::TestCase"
27
32
  else
28
- file.puts "require \"test/unit\"\n\nclass TempTest < Test::Unit::TestCase"
33
+ file.puts "require \"test/unit\"\n\n# IRB test capture courtesy of butterfly_net (butterflynet.org)\nclass MyTest < Test::Unit::TestCase"
29
34
  end
30
35
 
36
+
31
37
  test_methods.each do |test_method|
32
38
  file.puts "\n #{test_method}"
33
39
  end
@@ -41,13 +47,8 @@ module ButterflyNet
41
47
  end
42
48
 
43
49
  def test_methods
44
- method_strings = []
45
- @assertion_sets.each_with_index do |assertions, i|
46
-
47
-
48
- method_strings << assertions.text(i + 1)
49
- end
50
- method_strings
50
+ @assertion_sets.last.name = @assertion_sets.size unless @assertion_sets.last.name # done here for testing
51
+ @assertion_sets.collect {|i| i.text }.compact
51
52
  end
52
53
 
53
54
  end
@@ -1,67 +1,55 @@
1
1
  module ButterflyNet
2
2
  class TestUnitMethod
3
3
 
4
+ attr_accessor :name
5
+
4
6
  def initialize
5
- @lines = []
7
+ @commands = []
6
8
  end
7
9
 
8
10
  def <<(line)
9
- @lines << line
10
- end
11
-
12
- def self.simple_assignment_only?(line) # todo: extract to line class
13
- line =~ /[^=<>!*%\/+-\\|&]=[^=~]/
11
+ @commands << line
14
12
  end
15
13
 
16
- def self.assertion(expected, line) # todo: extract to assertion class
17
- if expected && simple_assignment_only?(line)
18
- line
19
- elsif expected && expected == line # type not supported, assume object inequality
20
- "assert_not_equal((#{expected}), #{line})"
21
- elsif expected == "true" # use simple assert() for true boolean expressions
22
- "assert(#{line})"
23
- elsif expected
24
- "assert_equal(#{expected}, #{line})"
25
- else
26
- nil
27
- end
14
+ def name=(name)
15
+ name = underscore(name)
16
+ @name = name =~ /^test_/ ? name : "test_#{name}"
28
17
  end
29
18
 
30
- def text_from_expression(line, i)
31
- expected_assertion(i)
19
+ def self.assignment_or_require?(line) # todo: extract to line class
20
+ line =~ /require\s*['|"]\w+['|"]|[^=<>!*%\/+-\\|&]=[^=~]/
32
21
  end
33
22
 
34
- def text(method_name)
35
- method_string = "def test_#{method_name}\n"
36
- @lines.each_with_index do |line, i|
37
- text = text_from_expression(line, i)
38
- method_string += " #{text}\n" if text
23
+ def text
24
+ purge_bad_commands
25
+ lines_string = ""
26
+ @commands.each_index do |i|
27
+ text = assertion(i)
28
+ lines_string += " #{text}\n" if text
39
29
  end
40
- method_string += " end"
30
+ lines_string.empty? ? nil : "def #{@name}\n#{lines_string} end"
41
31
  end
42
32
 
43
- def expected_assertion(current_i)
33
+ def assertion(current_i)
44
34
 
45
- current_line = @lines[current_i]
35
+ current_line = @commands[current_i]
46
36
  commands = current_line
47
37
  start_i = current_i
48
38
 
49
39
  begin
50
40
  retval = eval commands
51
- rescue
41
+ rescue Exception
52
42
  start_i -= 1
53
- commands = @lines[start_i..current_i].join("\n")
43
+ commands = @commands[start_i..current_i].join("\n")
54
44
 
55
45
  if start_i < 0
56
- puts "failure evaluating: eval[#{start_i}..#{current_i}] : #{commands}\n"
57
- return nil
46
+ return nil # give up, can't go further back
58
47
  else
59
48
  retry
60
49
  end
61
50
  end
62
- if retval && TestUnitMethod.simple_assignment_only?(current_line)
51
+ if TestUnitMethod.assignment_or_require?(current_line)
63
52
  current_line
64
-
65
53
  elsif instances_equal_by_value?(retval) # expression result supports value equality
66
54
 
67
55
  if retval == true # use simple assert() for true boolean expressions
@@ -84,6 +72,37 @@ module ButterflyNet
84
72
  instance == instance.dup rescue true # can't dup Fixnum, et al...
85
73
  end
86
74
 
75
+ private
76
+
77
+
78
+ def purge_bad_commands
79
+ begin
80
+ commands = ""
81
+ index = 0
82
+ @commands.each_with_index do |current_line, i|
83
+ index = i
84
+ commands += current_line + "\n"
85
+ eval commands
86
+ end
87
+
88
+ rescue Exception
89
+ # delete offender and start again from the beginning
90
+ @commands.delete_at index
91
+ end
92
+ nil
93
+ end
94
+
95
+ # Adapted from ActiveSupport Inflector
96
+ def underscore(name)
97
+ name.to_s.strip.
98
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
99
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
100
+ tr("-", "_").
101
+ tr(" ", "_").
102
+ downcase
103
+ end
104
+
105
+
87
106
 
88
107
  end
89
108
  end
@@ -22,7 +22,6 @@ class TestUnitAdapterTest < Test::Unit::TestCase
22
22
  def test_test_methods_single
23
23
  @adapter.add_command("1 + 1")
24
24
  expected = "def test_1\n assert_equal(2, 1 + 1)\n end"
25
- @adapter.test_methods
26
25
  assert_equal expected, @adapter.test_methods.first
27
26
  end
28
27
 
@@ -30,7 +29,6 @@ class TestUnitAdapterTest < Test::Unit::TestCase
30
29
  @adapter.add_command("1 + 1")
31
30
  @adapter.add_command("1 + 2")
32
31
  expected = "def test_1\n assert_equal(2, 1 + 1)\n assert_equal(3, 1 + 2)\n end"
33
- @adapter.test_methods
34
32
  assert_equal expected, @adapter.test_methods.last
35
33
  end
36
34
 
@@ -38,7 +36,13 @@ class TestUnitAdapterTest < Test::Unit::TestCase
38
36
  @adapter.add_command("a = 1")
39
37
  @adapter.add_command("a + 2")
40
38
  expected = "def test_1\n a = 1\n assert_equal(3, a + 2)\n end"
41
- @adapter.test_methods
39
+ assert_equal expected, @adapter.test_methods.last
40
+ end
41
+
42
+ def test_test_methods_require
43
+ @adapter.add_command("require 'bigdecimal'")
44
+ @adapter.add_command("BigDecimal(\"1.0\") - 0.5")
45
+ expected = "def test_1\n require 'bigdecimal'\n assert_equal(0.5, BigDecimal(\"1.0\") - 0.5)\n end"
42
46
  assert_equal expected, @adapter.test_methods.last
43
47
  end
44
48
 
@@ -46,9 +50,20 @@ class TestUnitAdapterTest < Test::Unit::TestCase
46
50
  @adapter.add_command("1 + 1")
47
51
  @adapter.close_assertion_set
48
52
  @adapter.add_command("1 + 2")
49
- expected = "def test_2\n assert_equal(3, 1 + 2)\n end"
50
- @adapter.test_methods
51
- assert_equal expected, @adapter.test_methods.last
53
+ assert_equal "def test_1\n assert_equal(2, 1 + 1)\n end", @adapter.test_methods.first
54
+ assert_equal "def test_2\n assert_equal(3, 1 + 2)\n end", @adapter.test_methods.last
55
+ end
56
+
57
+ def test_test_methods_naming
58
+ @adapter.add_command("1 + 1")
59
+ @adapter.close_assertion_set 'test_one_plus_one'
60
+ assert_equal "def test_one_plus_one\n assert_equal(2, 1 + 1)\n end", @adapter.test_methods.first
61
+ end
62
+
63
+ def test_test_methods_bad_input
64
+ @adapter.add_command("BADCOMMAND")
65
+ @adapter.close_assertion_set
66
+ assert_nil @adapter.test_methods.first
52
67
  end
53
68
 
54
69
  def test_create_file
@@ -56,7 +71,8 @@ class TestUnitAdapterTest < Test::Unit::TestCase
56
71
  expected = <<-EOF
57
72
  require "test/unit"
58
73
 
59
- class TempTest < Test::Unit::TestCase
74
+ # IRB test capture courtesy of butterfly_net (butterflynet.org)
75
+ class MyTest < Test::Unit::TestCase
60
76
 
61
77
  def test_1
62
78
  assert_equal(2, 1 + 1)
@@ -64,7 +80,7 @@ class TempTest < Test::Unit::TestCase
64
80
 
65
81
  end
66
82
  EOF
67
- @adapter.create_file('temp_test.rb')
83
+ @adapter.create_file('temp_test.rb') # todo: write to memory instead of file...
68
84
  assert_equal expected, File.open('temp_test.rb').readlines.join('')
69
85
  end
70
86
 
@@ -8,174 +8,265 @@ class TestUnitMethodTest < Test::Unit::TestCase
8
8
 
9
9
  def setup
10
10
  @method = TestUnitMethod.new
11
+ @method.name = "1"
11
12
  end
12
13
 
13
- def test_simple_assignment_only_true
14
- assert TestUnitMethod.simple_assignment_only? "a=1"
14
+ def test_assignment_or_require_true
15
+ assert TestUnitMethod.assignment_or_require? "a=1"
15
16
  end
16
17
 
17
- # def test_simple_assignment_only_true_orequals todo: solve orequals in regex
18
- # assert TestUnitMethod.simple_assignment_only? "a ||= 1"
18
+ # def test_assignment_or_require_true_orequals todo: solve orequals in regex
19
+ # assert TestUnitMethod.assignment_or_require? "a ||= 1"
19
20
  # end
20
21
 
21
- def test_simple_assignment_only_true_whitespace
22
- assert TestUnitMethod.simple_assignment_only? "a = 1"
22
+ def test_assignment_or_require_true_whitespace
23
+ assert TestUnitMethod.assignment_or_require? "a = 1"
23
24
  end
24
25
 
25
- def test_simple_assignment_only_true_contains_equals
26
- assert TestUnitMethod.simple_assignment_only? "a = (1 == 1)"
26
+ def test_assignment_or_require_true_contains_equals
27
+ assert TestUnitMethod.assignment_or_require? "a = (1 == 1)"
27
28
  end
28
29
 
29
- def test_simple_assignment_only_false
30
- assert !TestUnitMethod.simple_assignment_only?("a + 1")
30
+ def test_assignment_or_require_true_require_bigdecimal
31
+ assert TestUnitMethod.assignment_or_require? "require 'bigdecimal'"
31
32
  end
32
33
 
33
- def test_simple_assignment_only_false_with_equals
34
- assert !TestUnitMethod.simple_assignment_only?("a == 1")
34
+ def test_assignment_or_require_true_require
35
+ assert TestUnitMethod.assignment_or_require? "require 'rubygems'"
35
36
  end
36
37
 
37
- def test_simple_assignment_only_false_threequals
38
- assert !TestUnitMethod.simple_assignment_only?("a===1")
38
+ def test_assignment_or_require_true_require_no_spaces
39
+ assert TestUnitMethod.assignment_or_require? "require\"rubygems\""
39
40
  end
40
41
 
41
- def test_simple_assignment_only_false_regex
42
- assert !TestUnitMethod.simple_assignment_only?("'a' =~ /a/")
42
+ def test_assignment_or_require_false
43
+ assert !TestUnitMethod.assignment_or_require?("a + 1")
43
44
  end
44
45
 
45
- def test_simple_assignment_only_false_regex
46
- assert !TestUnitMethod.simple_assignment_only?("'a' =~ /a/")
46
+ def test_assignment_or_require_false_with_equals
47
+ assert !TestUnitMethod.assignment_or_require?("a == 1")
47
48
  end
48
49
 
49
- def test_simple_assignment_only_false_lessthanequals
50
- assert !TestUnitMethod.simple_assignment_only?("1 <= 1")
50
+ def test_assignment_or_require_false_threequals
51
+ assert !TestUnitMethod.assignment_or_require?("a===1")
51
52
  end
52
53
 
53
- def test_simple_assignment_only_false_greaterthanequals
54
- assert !TestUnitMethod.simple_assignment_only?("1 >= 1")
54
+ def test_assignment_or_require_false_regex
55
+ assert !TestUnitMethod.assignment_or_require?("'a' =~ /a/")
55
56
  end
56
57
 
57
- def test_simple_assignment_only_false_flyingsaucer
58
- assert !TestUnitMethod.simple_assignment_only?("1 <=> 1")
58
+ def test_assignment_or_require_false_regex
59
+ assert !TestUnitMethod.assignment_or_require?("'a' =~ /a/")
59
60
  end
60
61
 
61
- def test_simple_assignment_only_false_notequal
62
- assert !TestUnitMethod.simple_assignment_only?("1 != 0")
62
+ def test_assignment_or_require_false_lessthanequals
63
+ assert !TestUnitMethod.assignment_or_require?("1 <= 1")
63
64
  end
64
65
 
65
- def test_simple_assignment_only_false_modequal
66
- assert !TestUnitMethod.simple_assignment_only?("a %= 1")
66
+ def test_assignment_or_require_false_greaterthanequals
67
+ assert !TestUnitMethod.assignment_or_require?("1 >= 1")
67
68
  end
68
69
 
69
- def test_simple_assignment_only_false_orequal
70
- assert !TestUnitMethod.simple_assignment_only?("a |= 1")
70
+ def test_assignment_or_require_false_flyingsaucer
71
+ assert !TestUnitMethod.assignment_or_require?("1 <=> 1")
71
72
  end
72
73
 
73
- def test_simple_assignment_only_false_plusequal
74
- assert !TestUnitMethod.simple_assignment_only?("a += 1")
74
+ def test_assignment_or_require_false_notequal
75
+ assert !TestUnitMethod.assignment_or_require?("1 != 0")
75
76
  end
76
77
 
77
- def test_simple_assignment_only_false_minusequal
78
- assert !TestUnitMethod.simple_assignment_only?("a -= 1")
78
+ def test_assignment_or_require_false_modequal
79
+ assert !TestUnitMethod.assignment_or_require?("a %= 1")
79
80
  end
80
81
 
81
- def test_simple_assignment_only_false_divideequal
82
- assert !TestUnitMethod.simple_assignment_only?("a /= 1")
82
+ def test_assignment_or_require_false_orequal
83
+ assert !TestUnitMethod.assignment_or_require?("a |= 1")
83
84
  end
84
85
 
85
- def test_simple_assignment_only_false_andequal
86
- assert !TestUnitMethod.simple_assignment_only?("a &= 1")
86
+ def test_assignment_or_require_false_plusequal
87
+ assert !TestUnitMethod.assignment_or_require?("a += 1")
87
88
  end
88
89
 
89
- def test_simple_assignment_only_false_shiftrightequal
90
- assert !TestUnitMethod.simple_assignment_only?("a >>= 1")
90
+ def test_assignment_or_require_false_minusequal
91
+ assert !TestUnitMethod.assignment_or_require?("a -= 1")
91
92
  end
92
93
 
93
- def test_simple_assignment_only_false_shiftleftequal
94
- assert !TestUnitMethod.simple_assignment_only?("a <<= 1")
94
+ def test_assignment_or_require_false_divideequal
95
+ assert !TestUnitMethod.assignment_or_require?("a /= 1")
95
96
  end
96
97
 
97
- def test_simple_assignment_only_false_timesequal
98
- assert !TestUnitMethod.simple_assignment_only?("a *= 1")
98
+ def test_assignment_or_require_false_andequal
99
+ assert !TestUnitMethod.assignment_or_require?("a &= 1")
99
100
  end
100
101
 
102
+ def test_assignment_or_require_false_shiftrightequal
103
+ assert !TestUnitMethod.assignment_or_require?("a >>= 1")
104
+ end
105
+
106
+ def test_assignment_or_require_false_shiftleftequal
107
+ assert !TestUnitMethod.assignment_or_require?("a <<= 1")
108
+ end
109
+
110
+ def test_assignment_or_require_false_timesequal
111
+ assert !TestUnitMethod.assignment_or_require?("a *= 1")
112
+ end
113
+
114
+ def test_name_uppercase
115
+ @method.name = "MYMETHOD"
116
+ assert_equal("test_mymethod", @method.name)
117
+ end
118
+
119
+ def test_name_camelcase
120
+ @method.name = "MyMethod"
121
+ assert_equal("test_my_method", @method.name)
122
+ end
123
+
124
+ def test_name_hyphenated
125
+ @method.name = "my-Method"
126
+ assert_equal("test_my_method", @method.name)
127
+ end
128
+
129
+ def test_name_spaces
130
+ @method.name = " my Method "
131
+ assert_equal("test_my_method", @method.name)
132
+ end
133
+
134
+ def test_test_methods_naming_no_changes
135
+ @method.name = 'test_one_plus_one'
136
+ assert_equal("test_one_plus_one", @method.name)
137
+ end
138
+
139
+ def test_test_methods_naming_prepends_test
140
+ @method.name = 'one_plus_one'
141
+ assert_equal("test_one_plus_one", @method.name)
142
+ end
143
+
144
+
145
+
146
+ # def test_text_split_statements_into_lines todo
147
+ # @method << "a = 1; a + 1"
148
+ # assert_equal "def test_1\n a = 1\n assert_equal(2, a + 1)\n end", @method.text
149
+ # end
150
+
151
+ def test_purge_unexpected_identifier
152
+ @method << "a = 1"
153
+ @method << "2b" # syntax error, unexpected tIDENTIFIER, expecting $end
154
+ @method << "a += 1"
155
+ assert_equal "def test_1\n a = 1\n assert_equal(2, a += 1)\n end", @method.text
156
+ end
157
+
158
+ def test_purge_unexpected_identifiers
159
+ @method << "a += 1" # undefined method `+' for nil:NilClass
160
+ @method << "a = 1"
161
+ @method << "a += 1"
162
+ assert_equal "def test_1\n a = 1\n assert_equal(2, a += 1)\n end", @method.text
163
+ end
164
+
165
+ def test_text_require
166
+ @method << "require 'rubygems'"
167
+ @method << "require'active_support'"
168
+ @method << "'CamelCase'.underscore"
169
+ assert_equal "def test_1\n require 'rubygems'\n require'active_support'\n assert_equal(\"camel_case\", 'CamelCase'.underscore)\n end", @method.text
170
+ end
101
171
 
102
172
  def test_expected_boolean
103
173
  line = "1 == 1"
104
174
  @method << line
105
- assert_equal("assert(#{line})", @method.expected_assertion(0))
175
+ assert_equal("assert(#{line})", @method.assertion(0))
106
176
  end
107
177
 
108
178
  def test_assertion_fixnum
109
179
  line = "1"
110
180
  @method << line
111
- assert_equal("assert_equal(#{line}, #{line})", @method.expected_assertion(0))
181
+ assert_equal("assert_equal(#{line}, #{line})", @method.assertion(0))
112
182
  end
113
183
 
114
184
  def test_assertion_boolean_false
115
185
  line = "1 != 1"
116
186
  @method << line
117
- assert_equal("assert_equal(false, #{line})", @method.expected_assertion(0))
187
+ assert_equal("assert_equal(false, #{line})", @method.assertion(0))
118
188
  end
119
189
 
120
-
121
-
122
190
  def test_array_add
123
191
  @method << "a = []"
124
192
  line2 = "a << \"1\""
125
193
  @method << line2
126
- assert_equal("assert_equal([\"1\"], #{line2})", @method.expected_assertion(1))
194
+ assert_equal("assert_equal([\"1\"], #{line2})", @method.assertion(1))
127
195
  end
128
196
 
129
197
  def test_butterfly_net
130
198
  @method << "method = TestUnitMethod.new"
131
199
  @method << "method << \"1 + 1\""
132
- assert_equal("assert_equal([\"1 + 1\"], method << \"1 + 1\")", @method.expected_assertion(1))
200
+ assert_equal("assert_equal([\"1 + 1\"], method << \"1 + 1\")", @method.assertion(1))
133
201
  end
134
202
 
135
-
136
-
137
- def test_text_from_expression_boolean
203
+ def test_assertion_boolean
138
204
  line = "1 == 1"
139
205
  @method << line
140
- assert_equal("assert(#{line})", @method.text_from_expression(line, 0))
206
+ assert_equal("assert(#{line})", @method.assertion(0))
141
207
  end
142
208
 
143
- def test_text_from_expression_string
209
+ def test_assertion_string
144
210
  line = "'a' + 'b'"
145
211
  @method << line
146
- assert_equal("assert_equal(\"ab\", #{line})", @method.text_from_expression(line, 0))
212
+ assert_equal("assert_equal(\"ab\", #{line})", @method.assertion(0))
147
213
  end
148
214
 
149
- def test_text_from_expression_nil
215
+ def test_assertion_nil
150
216
  line = "[].first"
151
217
  @method << line
152
- assert_equal("assert_nil(#{line})", @method.text_from_expression(line, 0))
218
+ assert_equal("assert_nil(#{line})", @method.assertion(0))
153
219
  end
154
220
 
155
- def test_text_from_expression_boolean
221
+ def test_assertion_boolean
156
222
  line = "1 == 1"
157
223
  @method << line
158
- assert_equal("assert(#{line})", @method.text_from_expression(line, 0))
224
+ assert_equal("assert(#{line})", @method.assertion(0))
159
225
  end
160
226
 
161
- def test_text_from_expression_object_not_equal
227
+ def test_assertion_object_not_equal
162
228
  line = "Object.new"
163
229
  @method << line
164
- assert_equal("assert_not_equal((#{line}), #{line})", @method.text_from_expression(line, 0))
230
+ assert_equal("assert_not_equal((#{line}), #{line})", @method.assertion(0))
165
231
  end
166
232
 
167
- def test_text_from_expression_array
233
+ def test_assertion_array
168
234
  line = "([1,2,3])[0..0]"
169
235
  @method << line
170
- assert_equal("assert_equal([1], #{line})", @method.text_from_expression(line, 0))
236
+ assert_equal("assert_equal([1], #{line})", @method.assertion(0))
171
237
  end
172
238
 
173
- def test_text_from_expression_illegal_input
174
- line = "BADCOMMAND"
239
+ def test_assertion_illegal_input
240
+ line = "badtext"
175
241
  @method << line
176
- assert_nil @method.text_from_expression(line, 0)
242
+ assert_nil @method.assertion(0)
177
243
  end
178
244
 
245
+ def test_text
246
+ @method << "1 + 1"
247
+ assert_equal "def test_1\n assert_equal(2, 1 + 1)\n end", @method.text
248
+ end
249
+
250
+
251
+
252
+ def test_text_bad_input_constant
253
+ @method << "BADCONSTANT"
254
+ assert_nil @method.text
255
+ end
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+
179
270
  # non-project tests (scratchpad)
180
271
 
181
272
  def test_eval_scope
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: butterfly_net
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Smith
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-20 00:00:00 -07:00
12
+ date: 2010-02-21 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -22,7 +22,7 @@ extensions: []
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
- - README
25
+ - README.md
26
26
  - lib/butterfly_net/commands.rb
27
27
  - lib/butterfly_net/file_writer.rb
28
28
  - lib/butterfly_net/test_unit_adapter.rb
@@ -32,7 +32,7 @@ files:
32
32
  - test/test_unit_adapter_test.rb
33
33
  - test/test_unit_method_test.rb
34
34
  has_rdoc: true
35
- homepage: http://github.com/quartzmo/butterfly_net
35
+ homepage: http://www.butterflynet.org
36
36
  licenses: []
37
37
 
38
38
  post_install_message:
data/README DELETED
@@ -1,71 +0,0 @@
1
- butterfly_net
2
-
3
- Version: 0.0.2
4
-
5
- Author: Chris Smith
6
- Email: quartzmo@gmail.com
7
- Project homepage: http://github.com/quartzmo/butterfly_net
8
-
9
- DESCRIPTION
10
-
11
- IRB history captured as Test::Unit tests. (RSpec and others hopefully soon to come.)
12
-
13
- INSTALL
14
-
15
- 1. gem sources -a http://gemcutter.org
16
- 2. sudo gem install butterfly_net
17
- 3. To automatically require butterfly_net on every IRB session, add the following to your ~/.irbrc:
18
-
19
- require 'rubygems'
20
- require 'butterfly_net'
21
-
22
- USAGE
23
-
24
- Command methods:
25
-
26
- bn, bn_open - Open an active test case, with optional string arg file_name ('.rb' is appended if needed)
27
- bnc, bn_close - Close the active test case, and write the output to a file
28
-
29
- Ruby on Rails console:
30
-
31
- For repeatable tests, be sure to load the Rails test environment with "./script/console test".
32
- In a Rails project, you can run all tests with the standard rake command 'rake test',
33
- or an individual test by adding the test directory to the path with the option -I when you invoke Ruby.
34
-
35
- chris$ ./script/console test
36
- Loading test environment (Rails 2.3.4)
37
- >> bn "test/unit/person_console_test"
38
- . . .
39
- >> Person.count
40
- => 2
41
- >> exit
42
- . . .
43
- chris$ ruby -Itest test/unit/person_console_test.rb
44
- . . .
45
- 1 tests, 1 assertions, 0 failures, 0 errors
46
-
47
-
48
- LICENSE
49
-
50
- (The MIT License)
51
-
52
- Copyright (c) 2010 Chris Smith
53
-
54
- Permission is hereby granted, free of charge, to any person obtaining
55
- a copy of this software and associated documentation files (the
56
- 'Software'), to deal in the Software without restriction, including
57
- without limitation the rights to use, copy, modify, merge, publish,
58
- distribute, sublicense, and/or sell copies of the Software, and to
59
- permit persons to whom the Software is furnished to do so, subject to
60
- the following conditions:
61
-
62
- The above copyright notice and this permission notice shall be
63
- included in all copies or substantial portions of the Software.
64
-
65
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
66
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
67
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
68
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
69
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
70
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
71
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.