oats 0.0.1

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 (181) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +15 -0
  3. data/README.txt +165 -0
  4. data/Rakefile +2 -0
  5. data/bin/agent +204 -0
  6. data/bin/oats +10 -0
  7. data/bin/occ +29 -0
  8. data/bin/results_cleanup +6 -0
  9. data/doc/COPYING +55 -0
  10. data/doc/LICENSE +55 -0
  11. data/doc/OATS_Framework.doc +0 -0
  12. data/doc/classes/ApplicationLogs.html +239 -0
  13. data/doc/classes/Campaign.html +843 -0
  14. data/doc/classes/CommandlineOptions.html +131 -0
  15. data/doc/classes/Driver.html +182 -0
  16. data/doc/classes/Hash.html +137 -0
  17. data/doc/classes/Ide.html +194 -0
  18. data/doc/classes/MapSelenium.html +197 -0
  19. data/doc/classes/Net.html +107 -0
  20. data/doc/classes/Oats/OatsFilterError.html +119 -0
  21. data/doc/classes/Oats.html +998 -0
  22. data/doc/classes/OatsAssertError.html +119 -0
  23. data/doc/classes/OatsBadInput.html +119 -0
  24. data/doc/classes/OatsData.html +290 -0
  25. data/doc/classes/OatsError.html +117 -0
  26. data/doc/classes/OatsExit.html +117 -0
  27. data/doc/classes/OatsLock.html +254 -0
  28. data/doc/classes/OatsMain.html +182 -0
  29. data/doc/classes/OatsMysqlError.html +113 -0
  30. data/doc/classes/OatsMysqlMissingInput.html +113 -0
  31. data/doc/classes/OatsReportError.html +113 -0
  32. data/doc/classes/OatsSetupError.html +119 -0
  33. data/doc/classes/OatsTestError.html +119 -0
  34. data/doc/classes/OatsTestExit.html +119 -0
  35. data/doc/classes/OatsTestLocateError.html +120 -0
  36. data/doc/classes/OatsVerifyError.html +119 -0
  37. data/doc/classes/Ragent.html +397 -0
  38. data/doc/classes/Rclient.html +236 -0
  39. data/doc/classes/Report.html +368 -0
  40. data/doc/classes/Reports.html +244 -0
  41. data/doc/classes/RestApi.html +333 -0
  42. data/doc/classes/RhttpClient.html +236 -0
  43. data/doc/classes/Rimap.html +170 -0
  44. data/doc/classes/Rmysql.html +176 -0
  45. data/doc/classes/Roptions.html +131 -0
  46. data/doc/classes/Rselenium.html +233 -0
  47. data/doc/classes/Rssh.html +138 -0
  48. data/doc/classes/Runnable.html +174 -0
  49. data/doc/classes/SFTriggers.html +206 -0
  50. data/doc/classes/Selenium/Client/Driver.html +211 -0
  51. data/doc/classes/Selenium/Client.html +107 -0
  52. data/doc/classes/Selenium.html +107 -0
  53. data/doc/classes/SystemCapture.html +304 -0
  54. data/doc/classes/TestCase.html +418 -0
  55. data/doc/classes/TestData.html +235 -0
  56. data/doc/classes/TestList.html +264 -0
  57. data/doc/classes/Tools.html +244 -0
  58. data/doc/classes/Util.html +201 -0
  59. data/doc/classes/Variation.html +206 -0
  60. data/doc/fr_class_index.html +92 -0
  61. data/doc/fr_method_index.html +465 -0
  62. data/doc/index.html +23 -0
  63. data/doc/oats_httpd.conf +32 -0
  64. data/doc/oats_user.yml +25 -0
  65. data/doc/rdoc-style.css +208 -0
  66. data/lib/deep_merge/.gitignore +2 -0
  67. data/lib/deep_merge/core.rb +195 -0
  68. data/lib/deep_merge/deep_merge.rb +1 -0
  69. data/lib/deep_merge/deep_merge_hash.rb +28 -0
  70. data/lib/deep_merge/rails_compat.rb +27 -0
  71. data/lib/oats/application_logs.rb +163 -0
  72. data/lib/oats/build_id.rb +58 -0
  73. data/lib/oats/commandline_options.rb +128 -0
  74. data/lib/oats/diff.rb +278 -0
  75. data/lib/oats/driver.rb +492 -0
  76. data/lib/oats/ide.rb +227 -0
  77. data/lib/oats/keywords.rb +67 -0
  78. data/lib/oats/log4r_init.rb +14 -0
  79. data/lib/oats/mysql.rb +97 -0
  80. data/lib/oats/oats.rb +637 -0
  81. data/lib/oats/oats_data.rb +400 -0
  82. data/lib/oats/oats_exceptions.rb +25 -0
  83. data/lib/oats/oats_lock.rb +261 -0
  84. data/lib/oats/oats_selenium_api.rb +639 -0
  85. data/lib/oats/oselenium.rb +189 -0
  86. data/lib/oats/ossh.rb +36 -0
  87. data/lib/oats/patches_for_eventmachine_12.10.rb +66 -0
  88. data/lib/oats/ragent.rb +321 -0
  89. data/lib/oats/rclient.rb +42 -0
  90. data/lib/oats/report.rb +207 -0
  91. data/lib/oats/roptions.rb +88 -0
  92. data/lib/oats/test_case.rb +510 -0
  93. data/lib/oats/test_data.rb +98 -0
  94. data/lib/oats/test_list.rb +141 -0
  95. data/lib/oats/unixdiff.rb +75 -0
  96. data/lib/oats/util.rb +125 -0
  97. data/lib/oats/version.rb +3 -0
  98. data/lib/oats.rb +36 -0
  99. data/nbproject/configs/agent.properties +0 -0
  100. data/nbproject/configs/gr.properties +0 -0
  101. data/nbproject/project.properties +10 -0
  102. data/nbproject/project.xml +17 -0
  103. data/oats.gemspec +42 -0
  104. data/oats_ini.yml +258 -0
  105. data/oats_tests/Gemfile +18 -0
  106. data/oats_tests/aut_ini.yml +30 -0
  107. data/oats_tests/bin/oats +8 -0
  108. data/oats_tests/environments/qa.yml +4 -0
  109. data/oats_tests/environments/qa_chrome.yml +4 -0
  110. data/oats_tests/examples/core/coreExamples.yml +8 -0
  111. data/oats_tests/examples/core/expectedException.rb +39 -0
  112. data/oats_tests/examples/core/ok_verify.rb +2 -0
  113. data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile.txt +1 -0
  114. data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile2.txt +1 -0
  115. data/oats_tests/examples/core/ok_verify.rb_ok/rats_test.log +2 -0
  116. data/oats_tests/examples/core/unexpectedException.rb +30 -0
  117. data/oats_tests/examples/examples.yml +13 -0
  118. data/oats_tests/examples/gui/guiExamples.yml +7 -0
  119. data/oats_tests/examples/gui/seleniumGoogle.rb +10 -0
  120. data/oats_tests/examples/gui/webdriverGoogle.rb +9 -0
  121. data/oats_tests/examples/keywords/SampleXlList-1.xls +0 -0
  122. data/oats_tests/examples/keywords/SampleXlList-2.xls +0 -0
  123. data/oats_tests/examples/keywords/SampleXlLists.xls +0 -0
  124. data/oats_tests/examples/keywords/keywordsDriver.rb +1 -0
  125. data/oats_tests/examples/keywords/keywordsExamples.yml +8 -0
  126. data/oats_tests/examples/keywords/keywordsTC1.yml +5 -0
  127. data/oats_tests/examples/keywords/keywordsTestlist.yml +16 -0
  128. data/oats_tests/examples/needsWork/addTestDynamically.rb +4 -0
  129. data/oats_tests/examples/needsWork/emailVerify.rb +34 -0
  130. data/oats_tests/examples/needsWork/testSql/rtest.sql +6 -0
  131. data/oats_tests/examples/needsWork/testSql/rtest.yml +11 -0
  132. data/oats_tests/examples/occTest/occTest.rb +13 -0
  133. data/oats_tests/examples/occTest/occTest_1.rb +1 -0
  134. data/oats_tests/examples/occTest/occTest_1_1.rb +1 -0
  135. data/oats_tests/examples/occTest/occTest_1_2.rb +1 -0
  136. data/oats_tests/examples/occTest/occTest_1_3.rb +1 -0
  137. data/oats_tests/examples/occTest/occTest_1_4.rb +1 -0
  138. data/oats_tests/examples/occTest/occTest_2.rb +1 -0
  139. data/oats_tests/examples/occTest/occTest_2_1.rb +1 -0
  140. data/oats_tests/examples/occTest/occTest_2_2.rb +1 -0
  141. data/oats_tests/examples/occTest/occTest_2_3.rb +1 -0
  142. data/oats_tests/examples/occTest/occTest_2_4.rb +1 -0
  143. data/oats_tests/examples/occTest/occTest_3.rb +1 -0
  144. data/oats_tests/examples/occTest/occTest_3_1.rb +1 -0
  145. data/oats_tests/examples/occTest/occTest_3_2.rb +1 -0
  146. data/oats_tests/examples/occTest/occTest_3_3.rb +1 -0
  147. data/oats_tests/examples/occTest/occTest_3_4.rb +1 -0
  148. data/oats_tests/examples/occTest/occTest_4.rb +1 -0
  149. data/oats_tests/examples/occTest/occTestlist.yml +9 -0
  150. data/oats_tests/examples/occTest/occTestlist_1.yml +9 -0
  151. data/oats_tests/examples/occTest/occTestlist_2.yml +9 -0
  152. data/oats_tests/examples/occTest/occTestlist_3.yml +9 -0
  153. data/oats_tests/examples/occTest/variation1.yml +4 -0
  154. data/oats_tests/examples/occTest/variation2.yml +4 -0
  155. data/oats_tests/examples/testFileLocationUnitTests/extn_driver.rb +4 -0
  156. data/oats_tests/examples/testFileLocationUnitTests/folder/oats.yml +3 -0
  157. data/oats_tests/examples/testFileLocationUnitTests/folder/t1.rb +2 -0
  158. data/oats_tests/examples/testFileLocationUnitTests/folder1/t1.yml +2 -0
  159. data/oats_tests/examples/testFileLocationUnitTests/folder1/t1_1.yml +3 -0
  160. data/oats_tests/examples/testFileLocationUnitTests/folder2/oats.yml +3 -0
  161. data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.rb +2 -0
  162. data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.yml +2 -0
  163. data/oats_tests/examples/testFileLocationUnitTests/no_yaml.rb +3 -0
  164. data/oats_tests/examples/testFileLocationUnitTests/post_yaml.rb +1 -0
  165. data/oats_tests/examples/testFileLocationUnitTests/t1.rb +4 -0
  166. data/oats_tests/examples/testFileLocationUnitTests/t1.yml +2 -0
  167. data/oats_tests/examples/testFileLocationUnitTests/t1_1.yml +3 -0
  168. data/oats_tests/examples/testFileLocationUnitTests/testDir/oats.yml +3 -0
  169. data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.rb +2 -0
  170. data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.yml +2 -0
  171. data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.rb +2 -0
  172. data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.yml +2 -0
  173. data/oats_tests/examples/testFileLocationUnitTests/unitTestList.yml +36 -0
  174. data/oats_tests/examples/testFileLocationUnitTests/yml_driver.rb +2 -0
  175. data/oats_tests/lib/business.rb +28 -0
  176. data/oats_tests/lib/sample_xl_lists.rb +37 -0
  177. data/test/common_test_unit_setup.rb +21 -0
  178. data/test/test_basic.rb +16 -0
  179. data/test/test_selenium.rb +16 -0
  180. data/test/test_xl_lists.rb +16 -0
  181. metadata +291 -0
@@ -0,0 +1,128 @@
1
+ require 'optparse' # http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/index.html
2
+
3
+ module Oats
4
+
5
+ module CommandlineOptions
6
+
7
+ @@OPTIONS = nil
8
+ def CommandlineOptions.options(argv = nil)
9
+
10
+ # This should be set only once, coming from unit test or command-line
11
+ $oats_execution['input_args'] = $oats_unit_test ? $oats_unit_test['input_args'] : ARGV.dup
12
+
13
+ argv ||= $oats_execution['input_args'].dup
14
+ argv_save = argv.dup
15
+
16
+ begin
17
+
18
+ # Hold all of the options parsed from the command-line by OptionParser.
19
+ options = {}
20
+ optparse = OptionParser.new do|opts|
21
+ opts.banner = "Usage: oats.rb [options] test1 test2 ..."
22
+ opts.separator "Options:"
23
+ opts.on( '--tests t1,t2,t3', Array,
24
+ 'Test files for OATS execution.' ) do |t|
25
+ options['execution:test_files'] = t
26
+ end
27
+ opts.on( '-b', '--browser_type TYPE', ['firefox', 'iexplore','chrome'],
28
+ 'Select test execution browser type (firefox, iexplore, chrome)' ) do |t|
29
+ options['selenium:browser_type'] = t
30
+ end
31
+ opts.on( '-e', '--environments env1,env2,env3', Array,
32
+ 'Environment list for OATS execution.' ) do |t|
33
+ options['execution:environments'] = t
34
+ end
35
+ opts.on( '-t', '--test_dir DIR_TESTS',
36
+ 'Test directory to override environment variable OATS_TESTS.' ) do |t|
37
+ options['_:dir_tests'] = t
38
+ end
39
+ opts.on( '-i', '--ini INI_YAML_FILE',
40
+ 'The oats-user.yml to use.' ) do |t|
41
+ options['_:ini_file'] = t
42
+ end
43
+ opts.on( '-p', '--port PORT', Integer,
44
+ 'Port number for the Oats Agent.' ) do |t|
45
+ options['execution:occ:agent_port'] = t if t
46
+ end
47
+ opts.on( '-n', '--nickname NICKNAME',
48
+ 'Nickname to display on OCC for the Oats Agent.' ) do |t|
49
+ options['execution:occ:agent_nickname'] = t if t
50
+ end
51
+ opts.on( '-o', '--options key11.key12.key13:val1,key21.key22:val2,...', Array,
52
+ 'Options to override values specified in oats.yml as well as other commandline options.' ) do |t|
53
+ options['_:options'] = t
54
+ end
55
+ opts.on( '-j', '--json JSON',
56
+ 'The json hash to merge with oats data.' ) do |t|
57
+ options['_:json'] = t
58
+ end
59
+ opts.on( '-q', '--quiet',
60
+ 'Do not echo anything to the console while running.' ) do |t|
61
+ options['_:quiet'] = true
62
+ end
63
+
64
+ opts.on( '-a', '--agent',
65
+ 'Invokes background agent handling.' ) do |t|
66
+ options['_:agent'] = true
67
+ end
68
+ opts.on( '-u', '--oats_user OATS_USER',
69
+ 'Sets OATS_USER for agent, in conjunction with -a.' ) do |t|
70
+ options['_:oats_user'] = t
71
+ end
72
+ opts.on( '-k', '--kill_agent',
73
+ 'Kill the agent.' ) do |t|
74
+ options['_:kill_agent, in conjunction with -a'] = true
75
+ end
76
+
77
+
78
+ # Development options
79
+ opts.on( '-g', '--gemfile GEMFILE',
80
+ 'Gemfile path to be included.' ) do |t|
81
+ options['_:gemfile'] = t
82
+ end
83
+ opts.on( '-d' , '--d_options unit_test_dir1,unit_test_dir2', Array,
84
+ 'NetBeans passes these d options to TestUnit.' ) do |t|
85
+ options['_:d_options'] = t
86
+ end
87
+ # opts.on( '-s', '--show_result_ide TYPE', [ '0', '1', '2'],
88
+ # 'Select the trigger level to show TestRunner results (0, 1, 2) for (On failure, Never, Always)' ) do |t|
89
+ # options['execution:ide:show_result'] = t.to_f
90
+ # end
91
+ # opts.on( '--log_level_console LEVEL',["DEBUG", "INFO", "WARN", "ERROR", "FATAL"],
92
+ # 'Select logging level ("DEBUG", "INFO", "WARN", "ERROR", "FATAL")' ) do |t|
93
+ # options['execution:log_level_console'] = t
94
+ # end
95
+ # opts.on( '-t', '--tail_logs_ip [HOSTIP]',
96
+ # 'Tail the application logs for errors. Just input YES for the host IP executing OATS.' ) do |t|
97
+ # t = true unless t
98
+ # options['execution:tail_logs_ip'] = t
99
+ # end
100
+ # opts.on( '-r', '--restrict t1,t2,t3,...', Array,
101
+ # 'Restrict test list execution to the listed tests. NOT FULLY IMPLEMENTED YET.' ) do |t|
102
+ # options['execution:restrict_tests'] = t
103
+ # end
104
+ # opts.on( '-c', '--command COMMAND_STRING',
105
+ # 'Command issued by the client.' ) do |t|
106
+ # options['_:command'] = t
107
+ # end
108
+ opts.on_tail( '-h', '--help', 'Display this screen' ) { $stderr.puts opts; exit }
109
+ end
110
+
111
+ optparse.parse!(argv)
112
+ if argv and ! argv.empty?
113
+ options['execution:test_files'] ||= []
114
+ options['execution:test_files'] += argv
115
+ end
116
+
117
+ rescue Exception => e
118
+ raise unless e.class.to_s =~ /^OptionParser::/
119
+ $stderr.puts e.message
120
+ $stderr.puts "Please type 'oats -h' for valid options."
121
+ exit 1
122
+ end
123
+ options['_:args'] = argv_save
124
+ @@OPTIONS = options
125
+ end
126
+
127
+ end
128
+ end
data/lib/oats/diff.rb ADDED
@@ -0,0 +1,278 @@
1
+ class Diff
2
+
3
+ def Diff.lcs(a, b)
4
+ astart = 0
5
+ bstart = 0
6
+ afinish = a.length-1
7
+ bfinish = b.length-1
8
+ mvector = []
9
+
10
+ # First we prune off any common elements at the beginning
11
+ while (astart <= afinish && bstart <= afinish && a[astart] == b[bstart])
12
+ mvector[astart] = bstart
13
+ astart += 1
14
+ bstart += 1
15
+ end
16
+
17
+ # now the end
18
+ while (astart <= afinish && bstart <= bfinish && a[afinish] == b[bfinish])
19
+ mvector[afinish] = bfinish
20
+ afinish -= 1
21
+ bfinish -= 1
22
+ end
23
+
24
+ bmatches = b.reverse_hash(bstart..bfinish)
25
+ thresh = []
26
+ links = []
27
+
28
+ (astart..afinish).each { |aindex|
29
+ aelem = a[aindex]
30
+ next unless bmatches.has_key? aelem
31
+ k = nil
32
+ bmatches[aelem].reverse.each { |bindex|
33
+ if k && (thresh[k] > bindex) && (thresh[k-1] < bindex)
34
+ thresh[k] = bindex
35
+ else
36
+ k = thresh.replacenextlarger(bindex, k)
37
+ end
38
+ links[k] = [ (k==0) ? nil : links[k-1], aindex, bindex ] if k
39
+ }
40
+ }
41
+
42
+ if !thresh.empty?
43
+ link = links[thresh.length-1]
44
+ while link
45
+ mvector[link[1]] = link[2]
46
+ link = link[0]
47
+ end
48
+ end
49
+
50
+ return mvector
51
+ end
52
+
53
+ def makediff(a, b)
54
+ mvector = Diff.lcs(a, b)
55
+ ai = bi = 0
56
+ while ai < mvector.length
57
+ bline = mvector[ai]
58
+ if bline
59
+ while bi < bline
60
+ discardb(bi, b[bi])
61
+ bi += 1
62
+ end
63
+ match(ai, bi)
64
+ bi += 1
65
+ else
66
+ discarda(ai, a[ai])
67
+ end
68
+ ai += 1
69
+ end
70
+ while ai < a.length
71
+ discarda(ai, a[ai])
72
+ ai += 1
73
+ end
74
+ while bi < b.length
75
+ discardb(bi, b[bi])
76
+ bi += 1
77
+ end
78
+ match(ai, bi)
79
+ 1
80
+ end
81
+
82
+ def compactdiffs
83
+ diffs = []
84
+ @diffs.each { |df|
85
+ i = 0
86
+ curdiff = []
87
+ while i < df.length
88
+ whot = df[i][0]
89
+ s = @isstring ? df[i][2].chr : [df[i][2]]
90
+ p = df[i][1]
91
+ last = df[i][1]
92
+ i += 1
93
+ while df[i] && df[i][0] == whot && df[i][1] == last+1
94
+ s << df[i][2]
95
+ last = df[i][1]
96
+ i += 1
97
+ end
98
+ curdiff.push [whot, p, s]
99
+ end
100
+ diffs.push curdiff
101
+ }
102
+ return diffs
103
+ end
104
+
105
+ attr_reader :diffs, :difftype
106
+
107
+ def initialize(diffs_or_a, b = nil, isstring = nil)
108
+ if b.nil?
109
+ @diffs = diffs_or_a
110
+ @isstring = isstring
111
+ else
112
+ @diffs = []
113
+ @curdiffs = []
114
+ makediff(diffs_or_a, b)
115
+ @difftype = diffs_or_a.class
116
+ end
117
+ end
118
+
119
+ def match(ai, bi)
120
+ @diffs.push @curdiffs unless @curdiffs.empty?
121
+ @curdiffs = []
122
+ end
123
+
124
+ def discarda(i, elem)
125
+ @curdiffs.push ['-', i, elem]
126
+ end
127
+
128
+ def discardb(i, elem)
129
+ @curdiffs.push ['+', i, elem]
130
+ end
131
+
132
+ def compact
133
+ return Diff.new(compactdiffs)
134
+ end
135
+
136
+ def compact!
137
+ @diffs = compactdiffs
138
+ end
139
+
140
+ def inspect
141
+ @diffs.inspect
142
+ end
143
+
144
+ end
145
+
146
+ module Diffable
147
+ def diff(b)
148
+ Diff.new(self, b)
149
+ end
150
+
151
+ # Create a hash that maps elements of the array to arrays of indices
152
+ # where the elements are found.
153
+
154
+ def reverse_hash(range = (0...self.length))
155
+ revmap = {}
156
+ range.each { |i|
157
+ elem = self[i]
158
+ if revmap.has_key? elem
159
+ revmap[elem].push i
160
+ else
161
+ revmap[elem] = [i]
162
+ end
163
+ }
164
+ return revmap
165
+ end
166
+
167
+ def replacenextlarger(value, high = nil)
168
+ high ||= self.length
169
+ if self.empty? || value > self[-1]
170
+ push value
171
+ return high
172
+ end
173
+ # binary search for replacement point
174
+ low = 0
175
+ while low < high
176
+ index = (high+low)/2
177
+ found = self[index]
178
+ return nil if value == found
179
+ if value > found
180
+ low = index + 1
181
+ else
182
+ high = index
183
+ end
184
+ end
185
+
186
+ self[low] = value
187
+ # $stderr << "replace #{value} : 0/#{low}/#{init_high} (#{steps} steps) (#{init_high-low} off )\n"
188
+ # $stderr.puts self.inspect
189
+ #gets
190
+ #p length - low
191
+ return low
192
+ end
193
+
194
+ def patch(diff)
195
+ newary = nil
196
+ if diff.difftype == String
197
+ newary = diff.difftype.new('')
198
+ else
199
+ newary = diff.difftype.new
200
+ end
201
+ ai = 0
202
+ bi = 0
203
+ diff.diffs.each { |d|
204
+ d.each { |mod|
205
+ case mod[0]
206
+ when '-'
207
+ while ai < mod[1]
208
+ newary << self[ai]
209
+ ai += 1
210
+ bi += 1
211
+ end
212
+ ai += 1
213
+ when '+'
214
+ while bi < mod[1]
215
+ newary << self[ai]
216
+ ai += 1
217
+ bi += 1
218
+ end
219
+ newary << mod[2]
220
+ bi += 1
221
+ else
222
+ raise "Unknown diff action"
223
+ end
224
+ }
225
+ }
226
+ while ai < self.length
227
+ newary << self[ai]
228
+ ai += 1
229
+ bi += 1
230
+ end
231
+ return newary
232
+ end
233
+ end
234
+
235
+ class Array
236
+ include Diffable
237
+ end
238
+
239
+ class String
240
+ include Diffable
241
+ end
242
+
243
+ =begin
244
+ = Diff
245
+ (({diff.rb})) - computes the differences between two arrays or
246
+ strings. Copyright (C) 2001 Lars Christensen
247
+
248
+ == Synopsis
249
+
250
+ diff = Diff.new(a, b)
251
+ b = a.patch(diff)
252
+
253
+ == Class Diff
254
+ === Class Methods
255
+ --- Diff.new(a, b)
256
+ --- a.diff(b)
257
+ Creates a Diff object which represent the differences between
258
+ ((|a|)) and ((|b|)). ((|a|)) and ((|b|)) can be either be arrays
259
+ of any objects, strings, or object of any class that include
260
+ module ((|Diffable|))
261
+
262
+ == Module Diffable
263
+ The module ((|Diffable|)) is intended to be included in any class for
264
+ which differences are to be computed. Diffable is included into String
265
+ and Array when (({diff.rb})) is (({require}))'d.
266
+
267
+ Classes including Diffable should implement (({[]})) to get element at
268
+ integer indices, (({<<})) to append elements to the object and
269
+ (({ClassName#new})) should accept 0 arguments to create a new empty
270
+ object.
271
+
272
+ === Instance Methods
273
+ --- Diffable#patch(diff)
274
+ Applies the differences from ((|diff|)) to the object ((|obj|))
275
+ and return the result. ((|obj|)) is not changed. ((|obj|)) and
276
+ can be either an array or a string, but must match the object
277
+ from which the ((|diff|)) was created.
278
+ =end