assay 0.3.0 → 0.4.0

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.
Files changed (97) hide show
  1. data/.ruby +46 -41
  2. data/COPYING.rdoc +38 -0
  3. data/HISTORY.rdoc +18 -1
  4. data/QED.rdoc +1100 -0
  5. data/README.rdoc +139 -16
  6. data/lib/assay.rb +82 -29
  7. data/lib/assay.yml +46 -41
  8. data/lib/assay/{adapters → adapter}/minitest.rb +0 -0
  9. data/lib/assay/{adapters → adapter}/testunit.rb +0 -0
  10. data/lib/assay/assertable.rb +174 -0
  11. data/lib/assay/assertion.rb +98 -124
  12. data/lib/assay/assertor.rb +187 -0
  13. data/lib/assay/boolean_assay.rb +15 -0
  14. data/lib/assay/case_assay.rb +17 -0
  15. data/lib/assay/compare_assay.rb +38 -0
  16. data/lib/assay/core_ext/kernel.rb +52 -0
  17. data/lib/assay/core_ext/na.rb +9 -0
  18. data/lib/assay/directory_assay.rb +20 -0
  19. data/lib/assay/empty_assay.rb +17 -0
  20. data/lib/assay/equal_assay.rb +35 -0
  21. data/lib/assay/equality_assay.rb +18 -0
  22. data/lib/assay/execution_assay.rb +59 -0
  23. data/lib/assay/false_assay.rb +17 -0
  24. data/lib/assay/file_assay.rb +17 -0
  25. data/lib/assay/identity_assay.rb +49 -0
  26. data/lib/assay/include_assay.rb +17 -0
  27. data/lib/assay/instance_assay.rb +17 -0
  28. data/lib/assay/kind_assay.rb +18 -0
  29. data/lib/assay/less_assay.rb +18 -0
  30. data/lib/assay/less_equal_assay.rb +25 -0
  31. data/lib/assay/like_assay.rb +17 -0
  32. data/lib/assay/match_assay.rb +17 -0
  33. data/lib/assay/more_assay.rb +18 -0
  34. data/lib/assay/more_equal_assay.rb +25 -0
  35. data/lib/assay/nil_assay.rb +15 -0
  36. data/lib/assay/nomatch_assay.rb +17 -0
  37. data/lib/assay/output_assay.rb +35 -0
  38. data/lib/assay/path_assay.rb +17 -0
  39. data/lib/assay/raise_assay.rb +109 -0
  40. data/lib/assay/rescue_assay.rb +55 -0
  41. data/lib/assay/respond_assay.rb +17 -0
  42. data/lib/assay/return_assay.rb +46 -0
  43. data/lib/assay/silent_assay.rb +59 -0
  44. data/lib/assay/stderr_assay.rb +30 -0
  45. data/lib/assay/stdout_assay.rb +30 -0
  46. data/lib/assay/throw_assay.rb +89 -0
  47. data/lib/assay/true_assay.rb +20 -0
  48. data/lib/assay/unequal_assay.rb +37 -0
  49. data/lib/assay/within_assay.rb +39 -0
  50. data/test/case_compare_assay.rb +59 -0
  51. data/test/case_empty_assay.rb +51 -0
  52. data/test/case_equal_assay.rb +53 -0
  53. data/test/case_equality_assay.rb +55 -0
  54. data/test/case_false_assay.rb +48 -0
  55. data/test/case_identity_assay.rb +51 -0
  56. data/test/case_include_assay.rb +51 -0
  57. data/test/case_instance_assay.rb +51 -0
  58. data/test/case_kind_assay.rb +51 -0
  59. data/test/case_less_assay.rb +53 -0
  60. data/test/case_less_equal_assay.rb +53 -0
  61. data/test/case_like_assay.rb +57 -0
  62. data/test/case_match_assay.rb +45 -0
  63. data/test/case_more_assay.rb +53 -0
  64. data/test/case_more_equal_assay.rb +53 -0
  65. data/test/case_nil_assay.rb +48 -0
  66. data/test/case_nomatch_assay.rb +47 -0
  67. data/test/case_raise_assay.rb +51 -0
  68. data/test/case_respond_assay.rb +51 -0
  69. data/test/case_throw_assay.rb +51 -0
  70. data/test/case_true_assay.rb +48 -0
  71. data/test/case_unequal_assay.rb +55 -0
  72. data/test/case_within_assay.rb +61 -0
  73. data/test/helper.rb +36 -0
  74. metadata +135 -108
  75. data/APACHE2.txt +0 -205
  76. data/NOTICE.rdoc +0 -18
  77. data/lib/assay/assertions/compare_failure.rb +0 -61
  78. data/lib/assay/assertions/delta_failure.rb +0 -80
  79. data/lib/assay/assertions/empty_failure.rb +0 -76
  80. data/lib/assay/assertions/equality_failure.rb +0 -100
  81. data/lib/assay/assertions/execution_failure.rb +0 -90
  82. data/lib/assay/assertions/false_failure.rb +0 -72
  83. data/lib/assay/assertions/identity_failure.rb +0 -85
  84. data/lib/assay/assertions/instance_failure.rb +0 -76
  85. data/lib/assay/assertions/kind_failure.rb +0 -80
  86. data/lib/assay/assertions/match_failure.rb +0 -85
  87. data/lib/assay/assertions/nil_failure.rb +0 -75
  88. data/lib/assay/assertions/raise_failure.rb +0 -134
  89. data/lib/assay/assertions/response_failure.rb +0 -86
  90. data/lib/assay/assertions/same_failure.rb +0 -82
  91. data/lib/assay/assertions/throw_failure.rb +0 -122
  92. data/lib/assay/assertions/true_failure.rb +0 -79
  93. data/lib/assay/matcher.rb +0 -48
  94. data/qed/01_failure_classes.rdoc +0 -75
  95. data/qed/02_assertives.rdoc +0 -118
  96. data/qed/03_matchers.rdoc +0 -118
  97. data/qed/04_lookup.rdoc +0 -10
@@ -1,5 +1,11 @@
1
1
  = Assay
2
2
 
3
+ {Website}[http://rubyworks.github.com/assay] /
4
+ {Report Issue}[http://github.com/rubyworks/assay/issues] /
5
+ {Source Code}[http://github.com/rubyworks/assay] /
6
+ {Mailing List}[http://groups.google.com/group/rubyworks-mailinglist]
7
+
8
+
3
9
  == DESCRIPTION
4
10
 
5
11
  Assay defines assertions in the same way that Ruby defines
@@ -8,26 +14,21 @@ extended Exception class. Assay provides a complete set
8
14
  of these assertion classes for the most common assertion types.
9
15
  It also provides both TestUnit-style assertion methods and
10
16
  RSpec-compatiable matchers built from these assertion classes
11
- for use in your preferred test harness. Assay works with
17
+ for use in your preferred test harness. Assay is compatible with
12
18
  TestUnit, MiniTest, RSpec and other test frameworks.
13
19
 
14
20
 
15
21
  == FEATURES
16
22
 
17
- * Mirrors the Ruby Exception system.
18
- * Assertions get their own specialized error messages.
19
-
20
-
21
- == RESOURCES
23
+ * Patterned after the Ruby exception system.
24
+ * Allows assertions specialized error messages.
25
+ * Supports any variety of assertion "grammers".
26
+ * Can be used with almost any test framework.
22
27
 
23
- * home: http://rubyworks.github.com/assay
24
- * code: http://github.com/rubyworks/assay
25
- * mail: http://groups.google.com/group/rubyworks-mailinglist
26
28
 
29
+ == LIMITATIONS
27
30
 
28
- == SYNOPSIS
29
-
30
- See QED documentation.
31
+ * Assay is Ruby 1.9+ only!
31
32
 
32
33
 
33
34
  == INSTALLATION
@@ -40,11 +41,133 @@ Site installation with the tarball can be done with Ruby Setup
40
41
  (gem install setup). See http://rubyworks.github.com/setup.
41
42
 
42
43
 
43
- == COPYING
44
+ == UTILIZATION
45
+
46
+ === Assay Classes
47
+
48
+ Assay consists of a set of Assertion subclasses known as *assays*. They
49
+ are akin to Ruby's Exception subclasses, indeed the +Assertion+ base class
50
+ is a subclass of Exception. But assays have special class methods that are
51
+ used to make assertions.
52
+
53
+ Consider the +EqualityAssay+ class. It defines methods for asserting equality
54
+ via the `#==` method.
55
+
56
+ EqualityAssay.assert!(1,1)
57
+
58
+ Additionally, we can check the assertion's test without actually raising the
59
+ assertion if it fails using the query method.
60
+
61
+ EqualityAssay.pass?(1,1) #=> true
62
+
63
+ Assays also provide the opposite method `#refute!` along with `#fail?`.
64
+
65
+ EqualityAssay.refute!(1,2)
66
+
67
+ EqualityAssay.fail?(1,2) #=> true
68
+
69
+ Assay instances are test matchers, which can be conveniently defined with `#[]`.
70
+
71
+ EqualityAssay[1] =~ 1
72
+
73
+ Notice in the example we have used `#=~` to apply the matcher which makes
74
+ the `#assert!` call to the Assay object. Likewise `#!~` can be used to
75
+ call `#refute!` instead. And note that `#===` is also an alias for `#=~`.
76
+
77
+ EqualityAssay[1] === 1
78
+
79
+ Which means assay matchers can be used in case statments.
80
+
81
+ case 10
82
+ when InstanceAssay[Fixnum]
83
+ when EqualityAssay[10.0]
84
+ end
85
+
86
+ Pretty neat.
87
+
88
+ === Framework Adapters
89
+
90
+ Assay follows a standard practice of defining assertion error classes with
91
+ an `#assertion?` method that returns +true+. This can be used by any test
92
+ framework to easily detect when a raised error is an assertion rather than
93
+ an ordinary error. To add support for this to common test frameworks Assay
94
+ provides adapters.
95
+
96
+ For example, to use assay with MiniTest framework add to your test helper
97
+ script:
98
+
99
+ require 'assay/adapter/minitest'
100
+
101
+ Likewise for TestUnit.
102
+
103
+ require 'assay/adapter/testunit'
104
+
105
+ An RSpec adadpter is in the works, and should be out with the next release.
106
+
107
+ Note that even without the adapter, you can still use Assay with other test
108
+ frameworks. They will simply count Assay's assertions as regular errors.
109
+
110
+ === Customized Grammars
111
+
112
+ Of course the classes are interesting and clearly make for a sound foundation,
113
+ but in the end we want to write assertions more easily and concisely. For this
114
+ we turn to separate "grammar" projects that depend on Assay's classes. The
115
+ first of these, created as a spin-off project to demonstrate Assay's prowess,
116
+ is {Fluidity}[http://rubyworks.github.com/fluidity]. Here is a quick taste of
117
+ that gem's functionality.
118
+
119
+ require 'fluidity'
120
+
121
+ 10.should.be.kind_of(Integer)
122
+
123
+ But is you are acustom to MiniTest's spec methods, you might prefer `must`.
124
+
125
+ 10.must.be.kind_of(Integer)
126
+
127
+ And to satisfy all those technical aficionados (like yours truly) there is `assert`.
128
+
129
+ 10.assert.kind_of(Integer)
130
+
131
+ Thre are also compatibility grammar projects available, spun-off from Assay, that
132
+ provide compatability with legacy test frameworks which can serve as transition
133
+ to Assay from these other frameworks. Follow the links below for each:
134
+
135
+ * {Assay TestUnit}[http://github.com/rubyworks/assay-testunit]
136
+ * {Assay MiniTest}[http://github.com/rubyworks/assay-minitest]
137
+ * {Assay RSpec}[http://github.com/rubyworks/assay-rspec]
138
+
139
+ Usage is essentially the same for any one of them. For example,
140
+
141
+ require 'assay/rspec'
142
+
143
+ include Assay::Matchers
144
+
145
+ 10.should be_kind_of(Integer)
146
+
147
+ Note that the compatibility modules are not yet 100% compatable, lacking some
148
+ of the more esoteric and complex features. But they are very nearly so, and
149
+ will become more so in time.
150
+
151
+ These are just a few possible grammars. There is no reason not to build
152
+ your own grammar on top of Assay's classes if you have another approach in mind.
153
+ Indeed, please do! That, after all, is the main purpose of having such
154
+ a set of reusable assertion classes!
155
+
156
+ === Learning More
157
+
158
+ There's more learn about Assay, mainly the variety of assay classes available,
159
+ but also a few other bits of functionality not comvered here. To learn
160
+ about these check out the {QED documentation}[http://github.com/rubyworks/assay]
161
+ which provides an overiew of functionality with working examples, and the
162
+ the {API documentation}[http://rubydoc.info/gems/asasy] for a more in depth look
163
+ under the hood.
164
+
165
+
166
+ == COPYRIGHTS
44
167
 
45
- Copyright (c) 2009 Thomas Sawyer
168
+ Copyright (c) 2009 Rubyworks
46
169
 
47
- This program is ditributed under the terms of the Apache 2.0 license.
170
+ This program is ditributed under the terms of the *BSD-2-Cluase* license.
48
171
 
49
- See NOTICE.rdoc and APACHE2.txt file for details.
172
+ See COPYING.rdoc file for details.
50
173
 
@@ -1,44 +1,97 @@
1
- module Assay
2
- #VERSION="1.0.0"
3
-
4
- # Returns a Hash table of failure classes indexed by
5
- # asserton operator.
6
- def self.failure_classes_by_operator
7
- @_failure_classes_by_operator ||= (
8
- c = {}
9
- ObjectSpace.each_object(Class) do |fc|
10
- next unless fc < Assay::Assertion
11
- if fc.respond_to?(:assertion_operator)
12
- c[fc.assertion_operator.to_sym] = fc
13
- end
14
- end
15
- c
16
- )
17
- end
1
+ # Load Assay's assertion classes.
2
+ require_relative 'assay/assertion'
3
+ dir = File.dirname(__FILE__) + '/assay'
4
+ Dir.entries(dir).each do |file|
5
+ next if File.extname(file) != '.rb'
6
+ require_relative 'assay/' + file
7
+ end
18
8
 
19
- # Lookup failure class by operator.
20
- def self.lookup(operator)
21
- failure_classes_by_operator[operator.to_sym]
22
- end
9
+ module Assay
23
10
 
11
+ #
24
12
  # Returns Hash table of project metadata.
25
- def self.meta
13
+ #
14
+ def self.metadata
26
15
  @spec ||= (
27
16
  require 'yaml'
28
17
  YAML.load(File.new(File.dirname(__FILE__) + '/assay.yml'))
29
18
  )
30
19
  end
31
20
 
21
+ #
32
22
  # Check metadata for missing constants.
23
+ #
33
24
  def self.const_missing(name)
34
- meta[name.to_s.downcase] || super(name)
25
+ metadata[name.to_s.downcase] || super(name)
35
26
  end
36
- end
37
27
 
38
- # Load Assay's failure classes.
39
- dir = File.dirname(__FILE__)
40
- glob = File.join(dir, 'assay', 'assertions', '*.rb')
41
- Dir[glob].each do |rb|
42
- require 'assay/assertions/' + File.basename(rb)
28
+ #
29
+ # Returns a list of Assertion subclasses.
30
+ #
31
+ def self.assertions
32
+ Assertion.subclasses
33
+ end
34
+
35
+ #
36
+ # Set ANSI color mode. Default is false, so set to `true` to get ANSI color
37
+ # in some error messages.
38
+ #
39
+ # @example
40
+ # Assay.color = true
41
+ #
42
+ def self.color=(boolean)
43
+ if boolean
44
+ require 'ansi/diff'
45
+ $ansi = true
46
+ else
47
+ $ansi = false
48
+ end
49
+ end
50
+
51
+ #
52
+ # Lookup assay class by operator or name.
53
+ #
54
+ def self.lookup(symbol)
55
+ lookup_by_operator(symbol) || lookup_by_name(symbol)
56
+ end
57
+
58
+ #
59
+ # If operator is not given, returns a hash table of assertion classes
60
+ # indexed by operator.
61
+ #
62
+ def self.lookup_by_operator(operator=nil)
63
+ Assertion.by_operator(operator)
64
+ end
65
+
66
+ #
67
+ # If operator is not given, returns a hash table of assertion classes
68
+ # indexed by assertive name.
69
+ #
70
+ def self.lookup_by_name(name=nil)
71
+ Assertion.by_name(name)
72
+ end
73
+
74
+ # This module serves as the primary container for traditonal style assertion
75
+ # methods, which can be mixed in to one's testing scope (e.g. World).
76
+ #
77
+ module Assertions
78
+ end
79
+
80
+ # This module holds the subject matcher methods, which can be mixin
81
+ # to one's testing scope (e.g. World).
82
+ #
83
+ module Matchers
84
+ end
85
+
86
+ # This module holds the assertion extension mehods, which are mixed into
87
+ # the Object class.
88
+ #
89
+ module Extensions
90
+ end
91
+
92
+ #class ::Object
93
+ # include Assay::Extensions
94
+ #end
95
+
43
96
  end
44
97
 
@@ -1,44 +1,49 @@
1
- ---
2
- spec_version: 1.0.0
3
- replaces: []
4
-
5
- loadpath:
6
- - lib
7
- name: assay
8
- repositories: {}
9
-
10
- conflicts: []
11
-
12
- engine_check: []
13
-
14
- title: Assay
15
- resources:
16
- code: http://github.com/rubyworks/assay
17
- docs: http://rubydoc.info/gems/assay
18
- home: http://rubydoc.info/gems/assay
19
- maintainers: []
20
-
21
- requires:
22
- - group: []
23
-
24
- name: ansi
25
- version: ">=1.2.5"
26
- - group:
1
+ ---
2
+ source:
3
+ - meta
4
+ authors:
5
+ - name: Thomas Sawyer
6
+ email: transfire@gmail.com
7
+ copyrights:
8
+ - holder: Thomas Sawyer
9
+ year: '2009'
10
+ license: BSD-2-Clause
11
+ replacements: []
12
+ alternatives: []
13
+ requirements:
14
+ - name: ansi
15
+ - name: brass
16
+ - name: detroit
17
+ groups:
27
18
  - build
28
- name: redline
29
- version: 0+
30
- - group:
19
+ development: true
20
+ - name: qed
21
+ groups:
31
22
  - test
32
- name: qed
33
- version: 0+
34
- suite: rubyworks
35
- manifest: MANIFEST.txt
36
- version: 0.2.0
37
- licenses:
38
- - Apache 2.0
39
- copyright: Copyright (c) 2007 Thomas Sawyer
40
- authors:
41
- - Thomas Sawyer
42
- description: The Assay project defines Assertions in the same way that Ruby defines Exceptions. An asserition then simply becomes an extension to an Exception class.
23
+ development: true
24
+ dependencies: []
25
+ conflicts: []
26
+ repositories:
27
+ - uri: git@github.com:rubyworks/assay.git
28
+ scm: git
29
+ name: upstream
30
+ resources:
31
+ home: http://rubydoc.info/gems/assay
32
+ docs: http://rubydoc.info/gems/assay
33
+ code: http://github.com/rubyworks/assay
34
+ mail: http://groups.google.com/groups/rubyworks-mailinglist
35
+ extra: {}
36
+ load_path:
37
+ - lib
38
+ revision: 0
39
+ created: '2009-08-21'
43
40
  summary: Class-based Assertions Framework
44
- created: 2009-08-21
41
+ title: Assay
42
+ version: 0.4.0
43
+ name: assay
44
+ description: ! 'The Assay project defines Assertions in the same way that Ruby defines
45
+ Exceptions.
46
+
47
+ An asserition then simply becomes an extension to an Exception class.'
48
+ organization: Rubyworks
49
+ date: '2012-01-25'
@@ -0,0 +1,174 @@
1
+ require_relative 'assertor'
2
+
3
+ module Assay
4
+
5
+ module Assertable
6
+
7
+ $ASSERTION_COUNTS ||= Hash.new{ |h,k| h[k] = 0 } #{:total=>0,:pass=>0,:fail=>0}
8
+
9
+ #
10
+ # When displaying errors, use this as a rule of thumb
11
+ # for determining when the inspected object will be too
12
+ # big for a single line message.
13
+ #
14
+ SIZE_LIMIT = 13
15
+
16
+ # TODO: There's really no point to the defaults for #operator and
17
+ # assertive name b/c `register` is now reauired which set them.
18
+ # But that's in Assertion not Assertable, so something's not quite
19
+ # right in that regard.
20
+
21
+ #
22
+ # If the assertion coresponds to a regular method, particular a symbolic
23
+ # operator (hence the name of this method) then it should be specified via
24
+ # this interface. Otherwise, it should be given a fitting "make believe"
25
+ # method name and specified here. If not overridden it will be assumed
26
+ # to be the same as the `assertion_name` appended by `?`.
27
+ #
28
+ def operator
29
+ @operator ||= (name.split('::').last.chomp('Assay').downcase + '?').to_sym
30
+ end
31
+
32
+ #
33
+ # The assertive name is used for the construction of assertive nomenclatures
34
+ # such as `assert_equal`.
35
+ #
36
+ def assertive_name
37
+ @assertive_name ||= (
38
+ if operator.to_s.end_with?('?')
39
+ operator.to_s.chomp('?').to_sym
40
+ else
41
+ name.split('::').last.chomp('Assay').downcase.to_sym
42
+ end
43
+ )
44
+ end
45
+
46
+ #
47
+ # Create an assertor for the assay class, given +criteria+.
48
+ #
49
+ def assertor(*criteria, &block)
50
+ Assertor.new(self, *criteria, &block)
51
+ end
52
+
53
+ #
54
+ # Alias for `#assertor`.
55
+ #
56
+ def [](*criteria, &block)
57
+ assertor(*criteria, &block)
58
+ end
59
+
60
+ #
61
+ # Check the assertion, return `true` if passing, `false` otherwise.
62
+ #
63
+ def pass?(subject, *criteria, &block)
64
+ subject
65
+ end
66
+
67
+ #
68
+ # Check the assertion, return `true` if failing, `false` otherwise.
69
+ #
70
+ def fail?(subject, *criteria, &block)
71
+ ! pass?(subject, *criteria, &block)
72
+ end
73
+
74
+ #
75
+ # Test the assertion, raising the exception if failing.
76
+ #
77
+ def assert!(*arguments, &block)
78
+ options = (Hash === arguments.last ? arguments.pop : {})
79
+
80
+ backtrace = options[:backtrace] || caller
81
+ message = options[:message] || assert_message(*arguments, &block)
82
+
83
+ pass = pass?(*arguments, &block)
84
+
85
+ assert pass, self, message, backtrace
86
+
87
+ #if pass?(*arguments, &block)
88
+ # increment(:pass)
89
+ #else
90
+ # increment(:fail)
91
+ # fail self, message, backtrace
92
+ #end
93
+ end
94
+
95
+ #
96
+ # Test the refutation of the assertion.
97
+ #
98
+ # Test the inverse assertion, raising the exception if not failing.
99
+ #
100
+ def refute!(*arguments, &block)
101
+ options = (Hash === arguments.last ? arguments.pop : {})
102
+
103
+ backtrace = options[:backtrace] || caller
104
+ message = options[:message] || refute_message(*arguments, &block)
105
+
106
+ fail = fail?(*arguments, &block)
107
+
108
+ assert fail, self, message, backtrace
109
+
110
+ #if fail?(*arguments, &block)
111
+ # increment(:pass)
112
+ #else
113
+ # increment(:fail)
114
+ # fail self, message, backtrace
115
+ #end
116
+ end
117
+
118
+ ##
119
+ ##
120
+ ##
121
+ #def get_message(subject, fail=false)
122
+ # @not ^ fail ? refute_message(subject) : assert_message(subject)
123
+ #end
124
+
125
+ #
126
+ #
127
+ #
128
+ def assert_message(*arguments, &block)
129
+ standard_message(*arguments, &block)
130
+ end
131
+
132
+ #
133
+ #
134
+ #
135
+ def refute_message(*arguments, &block)
136
+ "! " + assert_message(*arguments, &block)
137
+ end
138
+
139
+ private
140
+
141
+ ##
142
+ ## Increment global `$ASSERTION_COUNTS` variable.
143
+ ##
144
+ #def increment(which)
145
+ # $ASSERTION_COUNTS[:total] += 1
146
+ # $ASSERTION_COUNTS[which.to_sym] += 1
147
+ #end
148
+
149
+ #
150
+ # Construct a standard error message.
151
+ #
152
+ def standard_message(*arguments, &block)
153
+ args_inspect = arguments.map{ |o| o.inspect }
154
+
155
+ op = self.operator.to_s
156
+ op = (/\w/ =~ op) ? ".#{op} " : " #{op} "
157
+
158
+ if args_inspect.any?{ |o| o.size > SIZE_LIMIT }
159
+ vars = ['b']
160
+ t = args_inspect.size - 2
161
+ t.times{ vars << vars.last.succ }
162
+
163
+ msg = ''
164
+ msg << "a#{op} " + vars.join(',') + "\n"
165
+ msg << args_inspect.join("\n")
166
+ msg
167
+ else
168
+ args_inspect.first + "#{op}" + args_inspect[1..-1].join(', ') + ""
169
+ end
170
+ end
171
+
172
+ end
173
+
174
+ end