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.
- data/.gitignore +6 -0
- data/Gemfile +15 -0
- data/README.txt +165 -0
- data/Rakefile +2 -0
- data/bin/agent +204 -0
- data/bin/oats +10 -0
- data/bin/occ +29 -0
- data/bin/results_cleanup +6 -0
- data/doc/COPYING +55 -0
- data/doc/LICENSE +55 -0
- data/doc/OATS_Framework.doc +0 -0
- data/doc/classes/ApplicationLogs.html +239 -0
- data/doc/classes/Campaign.html +843 -0
- data/doc/classes/CommandlineOptions.html +131 -0
- data/doc/classes/Driver.html +182 -0
- data/doc/classes/Hash.html +137 -0
- data/doc/classes/Ide.html +194 -0
- data/doc/classes/MapSelenium.html +197 -0
- data/doc/classes/Net.html +107 -0
- data/doc/classes/Oats/OatsFilterError.html +119 -0
- data/doc/classes/Oats.html +998 -0
- data/doc/classes/OatsAssertError.html +119 -0
- data/doc/classes/OatsBadInput.html +119 -0
- data/doc/classes/OatsData.html +290 -0
- data/doc/classes/OatsError.html +117 -0
- data/doc/classes/OatsExit.html +117 -0
- data/doc/classes/OatsLock.html +254 -0
- data/doc/classes/OatsMain.html +182 -0
- data/doc/classes/OatsMysqlError.html +113 -0
- data/doc/classes/OatsMysqlMissingInput.html +113 -0
- data/doc/classes/OatsReportError.html +113 -0
- data/doc/classes/OatsSetupError.html +119 -0
- data/doc/classes/OatsTestError.html +119 -0
- data/doc/classes/OatsTestExit.html +119 -0
- data/doc/classes/OatsTestLocateError.html +120 -0
- data/doc/classes/OatsVerifyError.html +119 -0
- data/doc/classes/Ragent.html +397 -0
- data/doc/classes/Rclient.html +236 -0
- data/doc/classes/Report.html +368 -0
- data/doc/classes/Reports.html +244 -0
- data/doc/classes/RestApi.html +333 -0
- data/doc/classes/RhttpClient.html +236 -0
- data/doc/classes/Rimap.html +170 -0
- data/doc/classes/Rmysql.html +176 -0
- data/doc/classes/Roptions.html +131 -0
- data/doc/classes/Rselenium.html +233 -0
- data/doc/classes/Rssh.html +138 -0
- data/doc/classes/Runnable.html +174 -0
- data/doc/classes/SFTriggers.html +206 -0
- data/doc/classes/Selenium/Client/Driver.html +211 -0
- data/doc/classes/Selenium/Client.html +107 -0
- data/doc/classes/Selenium.html +107 -0
- data/doc/classes/SystemCapture.html +304 -0
- data/doc/classes/TestCase.html +418 -0
- data/doc/classes/TestData.html +235 -0
- data/doc/classes/TestList.html +264 -0
- data/doc/classes/Tools.html +244 -0
- data/doc/classes/Util.html +201 -0
- data/doc/classes/Variation.html +206 -0
- data/doc/fr_class_index.html +92 -0
- data/doc/fr_method_index.html +465 -0
- data/doc/index.html +23 -0
- data/doc/oats_httpd.conf +32 -0
- data/doc/oats_user.yml +25 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/deep_merge/.gitignore +2 -0
- data/lib/deep_merge/core.rb +195 -0
- data/lib/deep_merge/deep_merge.rb +1 -0
- data/lib/deep_merge/deep_merge_hash.rb +28 -0
- data/lib/deep_merge/rails_compat.rb +27 -0
- data/lib/oats/application_logs.rb +163 -0
- data/lib/oats/build_id.rb +58 -0
- data/lib/oats/commandline_options.rb +128 -0
- data/lib/oats/diff.rb +278 -0
- data/lib/oats/driver.rb +492 -0
- data/lib/oats/ide.rb +227 -0
- data/lib/oats/keywords.rb +67 -0
- data/lib/oats/log4r_init.rb +14 -0
- data/lib/oats/mysql.rb +97 -0
- data/lib/oats/oats.rb +637 -0
- data/lib/oats/oats_data.rb +400 -0
- data/lib/oats/oats_exceptions.rb +25 -0
- data/lib/oats/oats_lock.rb +261 -0
- data/lib/oats/oats_selenium_api.rb +639 -0
- data/lib/oats/oselenium.rb +189 -0
- data/lib/oats/ossh.rb +36 -0
- data/lib/oats/patches_for_eventmachine_12.10.rb +66 -0
- data/lib/oats/ragent.rb +321 -0
- data/lib/oats/rclient.rb +42 -0
- data/lib/oats/report.rb +207 -0
- data/lib/oats/roptions.rb +88 -0
- data/lib/oats/test_case.rb +510 -0
- data/lib/oats/test_data.rb +98 -0
- data/lib/oats/test_list.rb +141 -0
- data/lib/oats/unixdiff.rb +75 -0
- data/lib/oats/util.rb +125 -0
- data/lib/oats/version.rb +3 -0
- data/lib/oats.rb +36 -0
- data/nbproject/configs/agent.properties +0 -0
- data/nbproject/configs/gr.properties +0 -0
- data/nbproject/project.properties +10 -0
- data/nbproject/project.xml +17 -0
- data/oats.gemspec +42 -0
- data/oats_ini.yml +258 -0
- data/oats_tests/Gemfile +18 -0
- data/oats_tests/aut_ini.yml +30 -0
- data/oats_tests/bin/oats +8 -0
- data/oats_tests/environments/qa.yml +4 -0
- data/oats_tests/environments/qa_chrome.yml +4 -0
- data/oats_tests/examples/core/coreExamples.yml +8 -0
- data/oats_tests/examples/core/expectedException.rb +39 -0
- data/oats_tests/examples/core/ok_verify.rb +2 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile.txt +1 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile2.txt +1 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/rats_test.log +2 -0
- data/oats_tests/examples/core/unexpectedException.rb +30 -0
- data/oats_tests/examples/examples.yml +13 -0
- data/oats_tests/examples/gui/guiExamples.yml +7 -0
- data/oats_tests/examples/gui/seleniumGoogle.rb +10 -0
- data/oats_tests/examples/gui/webdriverGoogle.rb +9 -0
- data/oats_tests/examples/keywords/SampleXlList-1.xls +0 -0
- data/oats_tests/examples/keywords/SampleXlList-2.xls +0 -0
- data/oats_tests/examples/keywords/SampleXlLists.xls +0 -0
- data/oats_tests/examples/keywords/keywordsDriver.rb +1 -0
- data/oats_tests/examples/keywords/keywordsExamples.yml +8 -0
- data/oats_tests/examples/keywords/keywordsTC1.yml +5 -0
- data/oats_tests/examples/keywords/keywordsTestlist.yml +16 -0
- data/oats_tests/examples/needsWork/addTestDynamically.rb +4 -0
- data/oats_tests/examples/needsWork/emailVerify.rb +34 -0
- data/oats_tests/examples/needsWork/testSql/rtest.sql +6 -0
- data/oats_tests/examples/needsWork/testSql/rtest.yml +11 -0
- data/oats_tests/examples/occTest/occTest.rb +13 -0
- data/oats_tests/examples/occTest/occTest_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_4.rb +1 -0
- data/oats_tests/examples/occTest/occTestlist.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_1.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_2.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_3.yml +9 -0
- data/oats_tests/examples/occTest/variation1.yml +4 -0
- data/oats_tests/examples/occTest/variation2.yml +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/extn_driver.rb +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder1/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder1/t1_1.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/no_yaml.rb +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/post_yaml.rb +1 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1.rb +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1_1.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/unitTestList.yml +36 -0
- data/oats_tests/examples/testFileLocationUnitTests/yml_driver.rb +2 -0
- data/oats_tests/lib/business.rb +28 -0
- data/oats_tests/lib/sample_xl_lists.rb +37 -0
- data/test/common_test_unit_setup.rb +21 -0
- data/test/test_basic.rb +16 -0
- data/test/test_selenium.rb +16 -0
- data/test/test_xl_lists.rb +16 -0
- 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
|