butterfly_net 0.0.2 → 0.0.3

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