conflict 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/conflict/core.rb +41 -17
- data/lib/conflict/domain.rb +13 -8
- data/lib/conflict/parsers.rb +58 -14
- data/test/common.rb +132 -132
- data/test/negative_test.rb +10 -9
- data/test/parser_test.rb +14 -14
- data/test/round_trip/expiration_test.rb +56 -56
- data/test/round_trip/happy_path_test.rb +105 -105
- data/test/round_trip/multi_diff_test.rb +67 -67
- data/test/round_trip/multiple_actions_test.rb +82 -82
- data/test/round_trip/negative_test.rb +109 -79
- data/test/round_trip/relative_path_test.rb +63 -63
- metadata +20 -19
data/Rakefile
CHANGED
data/lib/conflict/core.rb
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
module Conflict
|
19
19
|
|
20
20
|
DIFF_URL = "/diff"
|
21
|
+
DIFF_CVS_URL = "/diff.cvs"
|
21
22
|
STATUS_URL = "/status.xml"
|
22
23
|
PORT = 80 # tcp/ip
|
23
24
|
TTL = 43200 # event staleness, 12 hours in secs
|
@@ -40,7 +41,15 @@ class Server
|
|
40
41
|
RequestValidator::new().validate request
|
41
42
|
client = request.query['client'].to_s.strip
|
42
43
|
events = RequestParser::new(@cfg[:ttl]).parse request.query['diff'], request.query['info'], client
|
43
|
-
conflicts = @db.find_conflicts(client, events)
|
44
|
+
conflicts = @db.find_conflicts(client, events).sort_by {|c| c.remote_client}
|
45
|
+
res.body = conflicts.to_yaml
|
46
|
+
}
|
47
|
+
|
48
|
+
@s.mount_proc(DIFF_CVS_URL){|request, res|
|
49
|
+
RequestValidator::new().validate_cvs request
|
50
|
+
client = request.query['client'].to_s.strip
|
51
|
+
events = RequestParser::new(@cfg[:ttl]).parse_cvs request.query['diff'], client
|
52
|
+
conflicts = @db.find_conflicts(client, events).sort_by {|c| c.remote_client}
|
44
53
|
res.body = conflicts.to_yaml
|
45
54
|
}
|
46
55
|
|
@@ -72,26 +81,41 @@ end
|
|
72
81
|
class RequestValidator
|
73
82
|
|
74
83
|
def validate request
|
84
|
+
|
85
|
+
validate_common request
|
75
86
|
|
76
|
-
|
87
|
+
info = request.query['info']
|
77
88
|
|
89
|
+
raise "info parameter cannot be nil or empty" if info.nil? || info.empty?
|
90
|
+
|
91
|
+
diff = request.query['diff']
|
92
|
+
|
93
|
+
raise "diff count " + diff.list.size.to_s + " != info count " + info.list.size.to_s if diff.list.size != info.list.size
|
94
|
+
end
|
95
|
+
|
96
|
+
def validate_cvs request
|
97
|
+
|
98
|
+
validate_common request
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
def validate_common request
|
104
|
+
|
105
|
+
request_method = request.request_method
|
106
|
+
|
78
107
|
raise "only POST HTTP requests supported, not " + request_method if ! "POST".eql?(request_method)
|
79
|
-
|
108
|
+
|
80
109
|
client = request.query['client'].to_s.strip
|
81
|
-
|
82
|
-
raise "client parameter is nil or empty" if nil
|
83
|
-
|
110
|
+
|
111
|
+
raise "client parameter is nil or empty" if client.nil? || client.empty?
|
112
|
+
|
84
113
|
diff = request.query['diff']
|
85
|
-
|
86
|
-
raise "diff parameter is nil" if nil
|
87
|
-
|
88
|
-
info = request.query['info']
|
89
|
-
|
90
|
-
raise "info parameter cannot be nil or empty" if nil.eql?(info) || info.empty?
|
114
|
+
|
115
|
+
raise "diff parameter is nil" if diff.nil?
|
91
116
|
|
92
|
-
raise "diff count " + diff.list.size.to_s + " != info count " + info.list.size.to_s if diff.list.size != info.list.size
|
93
117
|
end
|
94
|
-
|
118
|
+
|
95
119
|
end
|
96
120
|
|
97
121
|
class DataBase
|
@@ -145,8 +169,8 @@ class DataBase
|
|
145
169
|
|
146
170
|
def validate_input client, events
|
147
171
|
|
148
|
-
raise ConflictException::new("client cannot be empty") if nil
|
149
|
-
raise ConflictException::new("events cannot be nil") if nil
|
172
|
+
raise ConflictException::new("client cannot be empty") if client.nil? || client.empty?
|
173
|
+
raise ConflictException::new("events cannot be nil") if events.nil?
|
150
174
|
|
151
175
|
resources = []
|
152
176
|
|
@@ -167,4 +191,4 @@ class ConflictException < Exception
|
|
167
191
|
end
|
168
192
|
end
|
169
193
|
|
170
|
-
end
|
194
|
+
end
|
data/lib/conflict/domain.rb
CHANGED
@@ -22,16 +22,20 @@ class Conflict
|
|
22
22
|
attr_reader :local, :remote
|
23
23
|
|
24
24
|
def initialize local, remote
|
25
|
-
raise ConflictException::new("local event cannot be nil") if nil
|
26
|
-
raise ConflictException::new("remote event cannot be nil") if nil
|
25
|
+
raise ConflictException::new("local event cannot be nil") if local.nil?
|
26
|
+
raise ConflictException::new("remote event cannot be nil") if remote.nil?
|
27
27
|
raise ConflictException::new("local resource '" + local.resource + "' does not match remote resource '" + remote.resource + "'") if ! local.resource.eql?(remote.resource)
|
28
28
|
raise ConflictException::new("local and remote cannot have the same identity") if local == remote
|
29
29
|
#what about = names, not = resources?
|
30
30
|
raise ConflictException::new("local and remote cannot be eql") if local.eql?(remote)
|
31
|
-
# using clone because
|
31
|
+
# using clone because I may have to write a parser in .net
|
32
32
|
@local, @remote = local.clone, remote.clone
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
|
+
def remote_client
|
36
|
+
remote.client
|
37
|
+
end
|
38
|
+
|
35
39
|
def eql? other
|
36
40
|
@local.eql?(other.local) and @remote.eql?(other.remote)
|
37
41
|
end
|
@@ -48,15 +52,16 @@ class Event
|
|
48
52
|
def initialize client, action, resource, created=Time.now, ttl=TTL
|
49
53
|
|
50
54
|
raise ConflictException::new("invalid action '" + action.to_s + "'") if ! ['added', 'changed', 'deleted'].index(action)
|
51
|
-
raise ConflictException::new("client must not be empty value") if nil
|
52
|
-
raise ConflictException::new("resource must not be empty value") if nil
|
55
|
+
raise ConflictException::new("client must not be empty value") if client.nil? or client.empty?
|
56
|
+
raise ConflictException::new("resource must not be empty value") if resource.nil? or resource.empty?
|
53
57
|
raise ConflictException::new("ttl cannot be negative") if ttl < 0
|
54
58
|
@client, @action, @resource = client, action, resource
|
55
59
|
# kept around for staleness expiration
|
56
60
|
@created_time = created
|
57
61
|
# rendered in YAML
|
58
|
-
@created =
|
62
|
+
@created = created.year.to_s + "/" + created.month.to_s + "/" + created.day.to_s + " " + created.hour.to_s + ":" + created.min.to_s
|
59
63
|
@ttl = ttl
|
64
|
+
@reserved = ''
|
60
65
|
end
|
61
66
|
|
62
67
|
def eql? other
|
@@ -71,7 +76,7 @@ class Event
|
|
71
76
|
fields = self.instance_variables.clone
|
72
77
|
fields.delete "@created_time" # keep data/time out of integration point ( ruby != java != .net )
|
73
78
|
fields.delete "@ttl"
|
74
|
-
fields
|
79
|
+
fields.sort
|
75
80
|
end
|
76
81
|
|
77
82
|
yaml_as "tag:java.yaml.org,2002:object:com.thoughtworks.conflict.Event"
|
data/lib/conflict/parsers.rb
CHANGED
@@ -34,18 +34,35 @@ class RequestParser
|
|
34
34
|
diff_data = diff.list[i].to_s.strip
|
35
35
|
info_data = info.list[i].to_s.strip
|
36
36
|
|
37
|
-
raise "no value for info @ index " + i.to_s if nil
|
37
|
+
raise "no value for info @ index " + i.to_s if info_data.nil? or info_data.empty?
|
38
38
|
|
39
39
|
lambda {
|
40
40
|
infos = InfoParser::new().parse(info_data)
|
41
|
-
events = events | DiffParser::new(infos.merge({:ttl=>@ttl})).parse(diff_data, client)
|
42
|
-
}.call if ! nil
|
41
|
+
events = events | DiffParser::new(infos.merge({:ttl=>@ttl})).parse(diff_data, client, infos[:url], infos[:path])
|
42
|
+
}.call if ! diff_data.nil? && ! diff_data.empty?
|
43
43
|
|
44
44
|
end
|
45
45
|
|
46
46
|
events
|
47
47
|
|
48
48
|
end
|
49
|
+
|
50
|
+
def parse_cvs diffs, client
|
51
|
+
|
52
|
+
events = []
|
53
|
+
|
54
|
+
diffs.each do | diff |
|
55
|
+
|
56
|
+
d = diff.to_s.strip
|
57
|
+
lambda{
|
58
|
+
events = events | DiffParser::new({:ttl=>@ttl}).parse_cvs(d, client)
|
59
|
+
}.call if ! d.nil? && ! d.empty?
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
events
|
64
|
+
|
65
|
+
end
|
49
66
|
|
50
67
|
end
|
51
68
|
|
@@ -55,7 +72,7 @@ class InfoParser
|
|
55
72
|
|
56
73
|
def parse info
|
57
74
|
|
58
|
-
raise ConflictException::new("info cannot be nil or empty") if nil
|
75
|
+
raise ConflictException::new("info cannot be nil or empty") if info.nil? || info.empty?
|
59
76
|
|
60
77
|
properties = {}
|
61
78
|
|
@@ -72,20 +89,24 @@ end
|
|
72
89
|
class DiffParser
|
73
90
|
|
74
91
|
@@key = "Index: "
|
75
|
-
|
92
|
+
@@key_cvs = 'RCS file: '
|
93
|
+
|
76
94
|
def initialize cfg
|
77
|
-
raise ConflictException::new("cfg cannot be nil") if nil
|
78
|
-
raise ConflictException::new("
|
79
|
-
raise ConflictException::new("path value cannot be nil or empty") if nil.eql?(cfg[:path]) or cfg[:path].empty?
|
80
|
-
raise ConflictException::new("ttl value cannot be nil") if nil.eql?(cfg[:ttl])
|
95
|
+
raise ConflictException::new("cfg cannot be nil") if cfg.nil?
|
96
|
+
raise ConflictException::new("ttl value cannot be nil") if cfg[:ttl].nil?
|
81
97
|
raise ConflictException::new("ttl cannot be negative") if cfg[:ttl] < 0
|
82
98
|
@cfg = cfg
|
83
99
|
end
|
84
100
|
|
85
|
-
def parse diff, client
|
101
|
+
def parse diff, client, url, path
|
102
|
+
|
103
|
+
# would be nice to just get a 3rd party for this
|
86
104
|
|
87
|
-
raise ConflictException::new("client cannot by empty") if nil
|
88
|
-
raise ConflictException::new("diff cannot by empty") if nil
|
105
|
+
raise ConflictException::new("client cannot by empty") if client.nil? || client.empty?
|
106
|
+
raise ConflictException::new("diff cannot by empty") if diff.nil? || diff.empty?
|
107
|
+
raise ConflictException::new("url value cannot be nil or empty") if url.nil? or url.empty?
|
108
|
+
raise ConflictException::new("path value cannot be nil or empty") if path.nil? or path.empty?
|
109
|
+
|
89
110
|
events = []
|
90
111
|
resource = ""
|
91
112
|
lines = diff.split(%r{\n})
|
@@ -101,7 +122,7 @@ class DiffParser
|
|
101
122
|
else
|
102
123
|
if line.to_s.index("@@ ") == 0
|
103
124
|
action = infer_action line
|
104
|
-
resource_full = infer_resource(
|
125
|
+
resource_full = infer_resource(url.to_s, path, resource)
|
105
126
|
events << Event::new(client, action, resource_full, now, @cfg[:ttl])
|
106
127
|
bit = ! bit
|
107
128
|
end
|
@@ -111,6 +132,29 @@ class DiffParser
|
|
111
132
|
events
|
112
133
|
end
|
113
134
|
|
135
|
+
def parse_cvs diff, client
|
136
|
+
|
137
|
+
raise ConflictException::new("client cannot by empty") if client.nil? || client.empty?
|
138
|
+
raise ConflictException::new("diff cannot by empty") if diff.nil? || diff.empty?
|
139
|
+
|
140
|
+
events = []
|
141
|
+
|
142
|
+
lines = diff.split(%r{\n})
|
143
|
+
now = Time.now
|
144
|
+
|
145
|
+
lines.each do |line|
|
146
|
+
|
147
|
+
if line.to_s.index(@@key_cvs) == 0
|
148
|
+
resource = line.to_s.sub(@@key_cvs, '')
|
149
|
+
events << Event::new(client, 'changed', resource.slice!(0..(resource.index(",") - 1)), now, @cfg[:ttl])
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
events
|
155
|
+
|
156
|
+
end
|
157
|
+
|
114
158
|
private
|
115
159
|
def infer_action numbers # we are assuming a lot about unified diff here
|
116
160
|
tokens = numbers.split(' ')
|
@@ -127,4 +171,4 @@ class DiffParser
|
|
127
171
|
|
128
172
|
end
|
129
173
|
|
130
|
-
end
|
174
|
+
end
|
data/test/common.rb
CHANGED
@@ -1,132 +1,132 @@
|
|
1
|
-
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
-
# or more contributor license agreements. See the NOTICE file
|
3
|
-
# distributed with this work for additional information
|
4
|
-
# regarding copyright ownership. The ASF licenses this file
|
5
|
-
# to you under the Apache License, Version 2.0 (the
|
6
|
-
# "License"); you may not use this file except in compliance
|
7
|
-
# with the License. You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing,
|
12
|
-
# software distributed under the License is distributed on an
|
13
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
-
# KIND, either express or implied. See the License for the
|
15
|
-
# specific language governing permissions and limitations
|
16
|
-
# under the License.
|
17
|
-
|
18
|
-
require 'test/unit'
|
19
|
-
require 'net/http'
|
20
|
-
module Conflict
|
21
|
-
|
22
|
-
class DataBase
|
23
|
-
def presence_of item
|
24
|
-
@db.index(item)
|
25
|
-
end
|
26
|
-
def insert item
|
27
|
-
@db << item
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class Client
|
32
|
-
|
33
|
-
def initialize cfg={}
|
34
|
-
@cfg = {}
|
35
|
-
@cfg[:command] = cfg[:command] ||= "svn diff"
|
36
|
-
@cfg[:id] = cfg[:id] ||= "Conflict Ruby client"
|
37
|
-
@cfg[:ip] = cfg[:ip] ||= "127.0.0.1"
|
38
|
-
@cfg[:port] = cfg[:port] ||= PORT
|
39
|
-
@cfg[:poll] = cfg[:poll] ||= 3
|
40
|
-
end
|
41
|
-
|
42
|
-
def resend
|
43
|
-
raise ConflictException::new('do not call resend before calling send') if ! defined?(@last_diff) or ! defined?(@last_info)
|
44
|
-
diff @last_diff, @last_info
|
45
|
-
end
|
46
|
-
|
47
|
-
def diff diff, info
|
48
|
-
|
49
|
-
raise ConflictException::new('info cannot be nil or empty') if nil.eql?(info) || info.empty?
|
50
|
-
|
51
|
-
response = multi_diff [diff], [info] # a multi diff of one
|
52
|
-
@last_diff, @last_info = diff, info
|
53
|
-
response
|
54
|
-
end
|
55
|
-
|
56
|
-
def multi_diff diff, info
|
57
|
-
body = {"client" => @cfg[:id]}
|
58
|
-
diff.each do | d | body = body.merge("diff"=>d, "path"=>".") end
|
59
|
-
info.each do | i | body = body.merge("info"=>i) end
|
60
|
-
YAML.load send(DIFF_URL, body)
|
61
|
-
end
|
62
|
-
|
63
|
-
def revert info
|
64
|
-
diff("", info)
|
65
|
-
end
|
66
|
-
|
67
|
-
#make this static?
|
68
|
-
def count
|
69
|
-
body = send(STATUS_URL, {})
|
70
|
-
document = REXML::Document.new(body)
|
71
|
-
document.root.elements['events'].size
|
72
|
-
end
|
73
|
-
|
74
|
-
def poll
|
75
|
-
|
76
|
-
while true
|
77
|
-
diff = `#{@cfg[:command]}`
|
78
|
-
info = `svn info`
|
79
|
-
puts multi_diff([diff], [info]).to_yaml
|
80
|
-
sleep @cfg[:poll]
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
def to_s
|
86
|
-
self.class.to_s + " " + @cfg.to_s
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
def send url, body
|
91
|
-
req = Net::HTTP::Post.new(url)
|
92
|
-
req.set_form_data(body)
|
93
|
-
http = Net::HTTP.new(@cfg[:ip],@cfg[:port])
|
94
|
-
res = http.request(req)
|
95
|
-
res.body
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
module ConflictConstants
|
103
|
-
|
104
|
-
CLIENT_ONE = "unit test"
|
105
|
-
CLIENT_TWO = "unit test 2"
|
106
|
-
CLIENT_THREE = "unit test 3"
|
107
|
-
NO_CONFLICT = [].to_yaml
|
108
|
-
CONTROLLER = "com.thoughtworks.Controller.java"
|
109
|
-
VIEW = "com.thoughtworks.View.java"
|
110
|
-
MODEL = "com.thoughtworks.Model.java"
|
111
|
-
DATA_DIR = './test/data/'
|
112
|
-
STOMP_DIR = DATA_DIR + 'stomp/'
|
113
|
-
STOMP_1_INFO_PATH = STOMP_DIR + 'stomp.1.info.txt'
|
114
|
-
STOMP_2_INFO_PATH = STOMP_DIR + 'stomp.2.info.txt'
|
115
|
-
STOMP_1_DIFF_PATH = STOMP_DIR + 'stomp.1.diff.txt'
|
116
|
-
STOMP_2_DIFF_PATH = STOMP_DIR + 'stomp.2.diff.txt'
|
117
|
-
STOMP_1_URL = 'http://svn.codehaus.org/stomp/ruby/trunk'
|
118
|
-
STOMP_2_URL = 'http://svn.codehaus.org/stomp/ruby/trunk/lib'
|
119
|
-
STOMP_RESOURCE = STOMP_2_URL + "/stomp.rb"
|
120
|
-
CONFLICT_URL = 'https://conflict.svn.sourceforge.net/svnroot/conflict/src/ruby'
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
class File
|
125
|
-
def to_s
|
126
|
-
string = ""
|
127
|
-
self.each do | line | string += line.to_s end
|
128
|
-
self.close
|
129
|
-
string
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
require 'test/unit'
|
19
|
+
require 'net/http'
|
20
|
+
module Conflict
|
21
|
+
|
22
|
+
class DataBase
|
23
|
+
def presence_of item
|
24
|
+
@db.index(item)
|
25
|
+
end
|
26
|
+
def insert item
|
27
|
+
@db << item
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Client
|
32
|
+
|
33
|
+
def initialize cfg={}
|
34
|
+
@cfg = {}
|
35
|
+
@cfg[:command] = cfg[:command] ||= "svn diff"
|
36
|
+
@cfg[:id] = cfg[:id] ||= "Conflict Ruby client"
|
37
|
+
@cfg[:ip] = cfg[:ip] ||= "127.0.0.1"
|
38
|
+
@cfg[:port] = cfg[:port] ||= PORT
|
39
|
+
@cfg[:poll] = cfg[:poll] ||= 3
|
40
|
+
end
|
41
|
+
|
42
|
+
def resend
|
43
|
+
raise ConflictException::new('do not call resend before calling send') if ! defined?(@last_diff) or ! defined?(@last_info)
|
44
|
+
diff @last_diff, @last_info
|
45
|
+
end
|
46
|
+
|
47
|
+
def diff diff, info
|
48
|
+
|
49
|
+
raise ConflictException::new('info cannot be nil or empty') if nil.eql?(info) || info.empty?
|
50
|
+
|
51
|
+
response = multi_diff [diff], [info] # a multi diff of one
|
52
|
+
@last_diff, @last_info = diff, info
|
53
|
+
response
|
54
|
+
end
|
55
|
+
|
56
|
+
def multi_diff diff, info
|
57
|
+
body = {"client" => @cfg[:id]}
|
58
|
+
diff.each do | d | body = body.merge("diff"=>d, "path"=>".") end
|
59
|
+
info.each do | i | body = body.merge("info"=>i) end
|
60
|
+
YAML.load send(DIFF_URL, body)
|
61
|
+
end
|
62
|
+
|
63
|
+
def revert info
|
64
|
+
diff("", info)
|
65
|
+
end
|
66
|
+
|
67
|
+
#make this static?
|
68
|
+
def count
|
69
|
+
body = send(STATUS_URL, {})
|
70
|
+
document = REXML::Document.new(body)
|
71
|
+
document.root.elements['events'].size
|
72
|
+
end
|
73
|
+
|
74
|
+
def poll
|
75
|
+
|
76
|
+
while true
|
77
|
+
diff = `#{@cfg[:command]}`
|
78
|
+
info = `svn info`
|
79
|
+
puts multi_diff([diff], [info]).to_yaml
|
80
|
+
sleep @cfg[:poll]
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_s
|
86
|
+
self.class.to_s + " " + @cfg.to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def send url, body
|
91
|
+
req = Net::HTTP::Post.new(url)
|
92
|
+
req.set_form_data(body)
|
93
|
+
http = Net::HTTP.new(@cfg[:ip],@cfg[:port])
|
94
|
+
res = http.request(req)
|
95
|
+
res.body
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
module ConflictConstants
|
103
|
+
|
104
|
+
CLIENT_ONE = "unit test"
|
105
|
+
CLIENT_TWO = "unit test 2"
|
106
|
+
CLIENT_THREE = "unit test 3"
|
107
|
+
NO_CONFLICT = [].to_yaml
|
108
|
+
CONTROLLER = "com.thoughtworks.Controller.java"
|
109
|
+
VIEW = "com.thoughtworks.View.java"
|
110
|
+
MODEL = "com.thoughtworks.Model.java"
|
111
|
+
DATA_DIR = './test/data/'
|
112
|
+
STOMP_DIR = DATA_DIR + 'stomp/'
|
113
|
+
STOMP_1_INFO_PATH = STOMP_DIR + 'stomp.1.info.txt'
|
114
|
+
STOMP_2_INFO_PATH = STOMP_DIR + 'stomp.2.info.txt'
|
115
|
+
STOMP_1_DIFF_PATH = STOMP_DIR + 'stomp.1.diff.txt'
|
116
|
+
STOMP_2_DIFF_PATH = STOMP_DIR + 'stomp.2.diff.txt'
|
117
|
+
STOMP_1_URL = 'http://svn.codehaus.org/stomp/ruby/trunk'
|
118
|
+
STOMP_2_URL = 'http://svn.codehaus.org/stomp/ruby/trunk/lib'
|
119
|
+
STOMP_RESOURCE = STOMP_2_URL + "/stomp.rb"
|
120
|
+
CONFLICT_URL = 'https://conflict.svn.sourceforge.net/svnroot/conflict/src/ruby'
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
class File
|
125
|
+
def to_s
|
126
|
+
string = ""
|
127
|
+
self.each do | line | string += line.to_s end
|
128
|
+
self.close
|
129
|
+
string
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|