spy-vs-spy 0.0.4 → 0.0.5
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/Change.log +3 -0
- data/LICENSE +19 -0
- data/README +18 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/lib/{spy-vs-spy.rb → spy_vs_spy.rb} +180 -163
- data/test/msie/msie-6.0.txt +0 -1
- data/test/safari/safari.txt +0 -1
- data/test/ss-test.rb +19 -139
- metadata +73 -69
- data/spy-vs-spy.gemspec +0 -76
data/Change.log
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2009 Kristan 'Krispy' Uccello <krispy@soldierofcode.com> - Soldier Of Code
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
=Spy vs Spy
|
2
|
+
|
3
|
+
== Intelligent User Agent parsing for the future! Now in Black & White
|
4
|
+
|
5
|
+
This is user agent parsing with lots and lots of tests. And accurate results. Its awesome
|
6
|
+
|
7
|
+
== Usage
|
8
|
+
|
9
|
+
>> require 'spy-vs-spy'
|
10
|
+
>> agent = SOC::SpyVsSpy.new("Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)")
|
11
|
+
<< #<SoldierOfCode::SpyVsSpy:0x100351a28 @version.major="5", @agent="Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)", @identifier="", @product_token="Mozilla/4.0 ", @mobile=["iPhone", "iPod", "BlackBerry", "Android", "HTC-", "LG", "Motorola", "Nokia", "Treo", "Pre/", "Samsung", "SonyEricsson"], @renderer="", @browser="MSIE", @engine="", @version.minor="5", @ostype="Windows", @platform="Desktop", @detail="(compatible; MSIE 5.5; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)">
|
12
|
+
>> agent.browser
|
13
|
+
<< "MSIE"
|
14
|
+
>> agent.version.to_s
|
15
|
+
<< "5.5"
|
16
|
+
>> agent.version.major
|
17
|
+
>> "5"
|
18
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'jeweler'
|
5
|
+
Jeweler::Tasks.new do |s|
|
6
|
+
s.name = "spy-vs-spy"
|
7
|
+
s.description = s.summary = "Rack middleware to detect and provide more detail on the requesting user agent edit"
|
8
|
+
s.email = "kuccello@gmail.com"
|
9
|
+
s.homepage = "http://github.com/kuccello/Spy-Vs-Spy"
|
10
|
+
s.authors = ['Kristan "Krispy" Uccello']
|
11
|
+
s.files = FileList["[A-Z]*", "{lib,test}/**/*"]
|
12
|
+
end
|
13
|
+
Jeweler::GemcutterTasks.new
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
16
|
+
end
|
17
|
+
|
18
|
+
Rake::TestTask.new do |t|
|
19
|
+
t.libs << "test"
|
20
|
+
t.test_files = FileList['test/*-test.rb']
|
21
|
+
t.verbose = true
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'rake/rdoctask'
|
25
|
+
desc "Generate documentation"
|
26
|
+
Rake::RDocTask.new do |rd|
|
27
|
+
rd.main = "README.rdoc"
|
28
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
29
|
+
rd.rdoc_dir = 'rdoc'
|
30
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.5
|
@@ -33,63 +33,89 @@
|
|
33
33
|
see LICENSE file for details
|
34
34
|
|
35
35
|
=end
|
36
|
-
class String
|
37
|
-
def starts_with?(str)
|
38
|
-
str = str.to_str
|
39
|
-
head = self[0, str.length]
|
40
|
-
head == str
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
36
|
module SoldierOfCode
|
45
37
|
|
46
38
|
class SpyVsSpy
|
47
39
|
|
48
|
-
|
49
|
-
|
50
|
-
|
40
|
+
class Middleware
|
41
|
+
def initialize(app=nil)
|
42
|
+
@app = app
|
43
|
+
end
|
51
44
|
|
52
|
-
|
45
|
+
def call(env)
|
53
46
|
|
54
|
-
|
47
|
+
http_user_agent = env['HTTP_USER_AGENT']
|
55
48
|
|
56
|
-
|
49
|
+
env['soldierofcode.spy-vs-spy'] = SpyVsSpy.new(http_user_agent)
|
50
|
+
|
51
|
+
@app.call(env)
|
52
|
+
end
|
57
53
|
|
58
|
-
@app.call(env)
|
59
|
-
end
|
60
54
|
|
61
|
-
|
62
|
-
|
55
|
+
end
|
56
|
+
|
57
|
+
class Version
|
58
|
+
attr_accessor :major, :minor, :sub
|
59
|
+
|
60
|
+
def to_s
|
61
|
+
[major, minor, sub].compact.join('.')
|
62
|
+
end
|
63
|
+
|
64
|
+
def update(major = nil, minor = nil, sub = nil)
|
65
|
+
@major, @minor, @sub = major, minor, sub
|
66
|
+
end
|
67
|
+
|
63
68
|
end
|
64
69
|
|
65
|
-
|
70
|
+
class OS
|
71
|
+
def initialize(os_string)
|
72
|
+
@os_string = os_string
|
73
|
+
@exact_os = (match = /(Mac OS X|Linux|Windows)/.match(@os_string)) ? match[1] : nil
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_s
|
77
|
+
@os_string
|
78
|
+
end
|
79
|
+
|
80
|
+
def osx?
|
81
|
+
@exact_os == 'Mac OS X'
|
82
|
+
end
|
83
|
+
|
84
|
+
def linux?
|
85
|
+
@exact_os == 'Linux'
|
86
|
+
end
|
87
|
+
|
88
|
+
def windows?
|
89
|
+
@exact_os == 'Windows'
|
90
|
+
end
|
91
|
+
end
|
66
92
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
93
|
+
SafariSpecialCases = {
|
94
|
+
"1.0" => ["85.5", "85.6", "85.7"],
|
95
|
+
"1,0.3" => ["85.8.1", "85.8", "85"],
|
96
|
+
"1.2" => ["125", "125.1"],
|
97
|
+
"1.2.2" => ["85.8", "125.7", "125.8"],
|
98
|
+
"1.2.3" => ["100", "125.9"],
|
99
|
+
"1.2.4" => ["125", "125.11", "125.12", "125.12_Adobe", "125.5.5"],
|
100
|
+
"1.3" => ["312", "312.3.1"],
|
101
|
+
"1.3.1" => ["312.3.3", "312.3.1", "312.3", "125.8", "125.9"],
|
102
|
+
"1.3.2" => ["312.3.3", "312.5", "312.6", "312.5_Adobe"],
|
103
|
+
"2.0" => ["412", "412.2.2", "412.2_Adobe"],
|
104
|
+
"2.0.1" => ["412.5", "412.6", "412.5_Adobe"],
|
105
|
+
"2.0.2" => ["416.13", "416.12", "312", "416.13_Adobe", "416.12_Adobe", "412.5"],
|
106
|
+
"2.0.3" => ["417.9.3", "417.8_Adobe", "417.9.2", "417.8", "412.2"],
|
107
|
+
"2.0.4" => ["419.3"],
|
108
|
+
"3.0" => ["523.13", "522.11.3", "523.12.9", "523.6.1", "522.11.1", "522.11", "522.8.3", "522.7"],
|
109
|
+
"3.0.1" => ["522.12.2"],
|
110
|
+
"3.0.2" => ["522.13.1", "522.12"],
|
111
|
+
"3.0.3" => ["522.15.5", "523.6", "522.12.1"],
|
112
|
+
"3.0.4" => ["523.11", "523.12.2", "523.10", "523.10.6", "523.15", "523.12"],
|
113
|
+
"3.1.1" => ["525.17", "525.18", "525.20"],
|
114
|
+
"3.2.1" => ["525.27.1"]
|
89
115
|
}
|
90
116
|
|
91
|
-
attr_reader :
|
92
|
-
|
117
|
+
attr_reader :browser, :os_version, :version, :mobile_browser, :console_browser, :agent, :os
|
118
|
+
|
93
119
|
#
|
94
120
|
#
|
95
121
|
# =======================================
|
@@ -101,32 +127,31 @@ module SoldierOfCode
|
|
101
127
|
#
|
102
128
|
# returns:
|
103
129
|
# ----------------
|
104
|
-
def
|
130
|
+
def initialize(agent)
|
105
131
|
|
132
|
+
@agent = agent
|
133
|
+
|
106
134
|
pass1 = Regexp.new("^([^\\(]*)?[ ]*?(\\([^\\)]*\\))?[ ]*([^\\(]*)?[ ]*?(\\([^\\)]*\\))?[ ]*(.*)")
|
107
|
-
pass1.match(agent)
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
self
|
135
|
+
if matches = pass1.match(agent)
|
136
|
+
|
137
|
+
@product_token = matches[1] || ''
|
138
|
+
@detail = matches[2] || ''
|
139
|
+
@engine = matches[3] || ''
|
140
|
+
@renderer = matches[4] || ''
|
141
|
+
@identifier = matches[5] || ''
|
142
|
+
|
143
|
+
@platform = identify_platform(agent)
|
144
|
+
@mobile = is_mobile?(agent)
|
145
|
+
@os = OS.new(@detail)
|
146
|
+
@version = Version.new
|
147
|
+
|
148
|
+
[:safari, :firefox, :ie, :opera, :netscape].each do |type|
|
149
|
+
send(:"process_#{type}", agent)
|
150
|
+
break if complete?
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
128
154
|
end
|
129
|
-
|
130
155
|
#
|
131
156
|
#
|
132
157
|
# =======================================
|
@@ -139,11 +164,8 @@ module SoldierOfCode
|
|
139
164
|
# returns:
|
140
165
|
# ----------------
|
141
166
|
def identify_platform(agent)
|
142
|
-
|
143
|
-
|
144
|
-
platform = agt if @platform=="Desktop" && agent.include?(agt)
|
145
|
-
end
|
146
|
-
platform
|
167
|
+
(match = /(PLAYSTATION 3|wii|PlayStation Portable|Xbox|iPhone|iPod|BlackBerry|Android|HTC-|LG|Motorola|Nokia|Treo|Pre\/|Samsung|SonyEricsson)/.match(agent)) ?
|
168
|
+
match[1] : 'Desktop'
|
147
169
|
end
|
148
170
|
|
149
171
|
#
|
@@ -158,29 +180,11 @@ module SoldierOfCode
|
|
158
180
|
# returns:
|
159
181
|
# ----------------
|
160
182
|
def is_mobile?(agent)
|
161
|
-
|
162
|
-
return true if agent.include?(mobile_agt)
|
163
|
-
end
|
183
|
+
/(iPhone|iPod|BlackBerry|Android|HTC-|LG|Motorola|Nokia|Treo|Pre\/|Samsung|SonyEricsson)/.match(agent)
|
164
184
|
end
|
165
185
|
|
166
|
-
|
167
|
-
|
168
|
-
# =======================================
|
169
|
-
# description:
|
170
|
-
# ----------------
|
171
|
-
#
|
172
|
-
# params:
|
173
|
-
# ----------------
|
174
|
-
#
|
175
|
-
# returns:
|
176
|
-
# ----------------
|
177
|
-
def identify_os
|
178
|
-
os_list = ["Mac OS X", "Linux", "Windows"]
|
179
|
-
os = nil
|
180
|
-
os_list.each do |o|
|
181
|
-
os = o if @detail.include?(o)
|
182
|
-
end
|
183
|
-
os
|
186
|
+
def complete?
|
187
|
+
@browser && @version.major
|
184
188
|
end
|
185
189
|
|
186
190
|
#
|
@@ -216,47 +220,78 @@ module SoldierOfCode
|
|
216
220
|
end
|
217
221
|
end
|
218
222
|
|
219
|
-
|
223
|
+
SafariSpecialCases.each do |k, v|
|
220
224
|
version_numbers = k.gsub(",", ".").split(".")
|
221
225
|
v.each do |num|
|
222
226
|
if identifier_sub == num
|
223
|
-
@
|
224
|
-
@browser_version_minor = version_numbers[1] if version_numbers.size > 1
|
225
|
-
@browser_version_sub = version_numbers[2] if version_numbers.size > 2
|
227
|
+
@version.update(*version_numbers)
|
226
228
|
end
|
227
|
-
break if @
|
229
|
+
break if @version.major
|
228
230
|
end
|
229
231
|
# Special case 58.8 - check WebKit numbers
|
230
232
|
# Special case 312 - check AppleWebKit
|
231
233
|
# Special case 419.3 - could me mobile v3 check AppleWebKit for 420+
|
232
234
|
|
233
|
-
|
234
|
-
engine_sub = @engine.sub("AppleWebKit/", "")
|
235
|
-
if engine_sub.include? "416.11" then
|
236
|
-
@browser_version_major = '2'
|
237
|
-
@browser_version_minor = '0'
|
238
|
-
@browser_version_sub = '2'
|
239
|
-
else
|
240
|
-
end
|
241
|
-
end
|
235
|
+
engine_id = @engine[/AppleWebKit\/([0-9.]+)/, 1]
|
242
236
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
237
|
+
case identifier_sub
|
238
|
+
when "85.8"
|
239
|
+
case engine_id
|
240
|
+
when '125.2' then @version.update('1', '2', '2')
|
241
|
+
end
|
242
|
+
when "125"
|
243
|
+
case engine_id
|
244
|
+
when '125.5.5' then @version.update('1', '2', '4')
|
245
|
+
when '124' then @version.update('1', '2')
|
246
|
+
when '312.5.2' then @version.update('1', '3', '1')
|
247
|
+
when '312.1' then @version.update('1', '3')
|
248
|
+
end
|
249
|
+
when '412.5'
|
250
|
+
case engine_id
|
251
|
+
when '416.12' then @version.update('2','0','2')
|
252
|
+
end
|
253
|
+
when '416.13'
|
254
|
+
case engine_id
|
255
|
+
when '417.9' then @version.update('2','0','3')
|
256
|
+
end
|
257
|
+
when '412.2'
|
258
|
+
case engine_id
|
259
|
+
when '412.6' then @version.update('2','0')
|
260
|
+
end
|
261
|
+
when '312.3.1'
|
262
|
+
case engine_id
|
263
|
+
when '312.1' then @version.update('1', '3')
|
264
|
+
when '312.5.1' then @version.update('1', '3', '1')
|
265
|
+
end
|
266
|
+
when "125.8"
|
267
|
+
case engine_id
|
268
|
+
when '312.5.1' then @version.update('1', '3', '1')
|
269
|
+
when '125.2' then @version.update('1', '2', '2')
|
270
|
+
end
|
271
|
+
when "125.9"
|
272
|
+
case engine_id
|
273
|
+
when '125.4' then @version.update('1', '2', '3')
|
274
|
+
when '125.5' then @version.update('1', '2', '3')
|
275
|
+
when '312.5.1' then @version.update('1', '3', '1')
|
276
|
+
end
|
277
|
+
when "312"
|
278
|
+
case engine_id
|
279
|
+
when '416.11' then @version.update('2', '0', '2')
|
280
|
+
end
|
281
|
+
when "312.3.3"
|
282
|
+
case engine_id
|
283
|
+
when '312.8' then @version.update('1', '3', '2')
|
284
|
+
end
|
285
|
+
when "419.3"
|
286
|
+
case engine_id
|
287
|
+
when "420" then @version.update('3', '0')
|
250
288
|
end
|
251
289
|
end
|
252
290
|
|
253
291
|
if (identifier_sub == "Safari") || (@identifier == "Safari/")then
|
254
|
-
|
255
|
-
|
256
|
-
@
|
257
|
-
@browser_version_minor = '0'
|
258
|
-
@browser_version_sub = '4'
|
259
|
-
else
|
292
|
+
case engine_id
|
293
|
+
when "418.9", "418.8"
|
294
|
+
@version.update('2', '0', '4')
|
260
295
|
end
|
261
296
|
end
|
262
297
|
|
@@ -265,30 +300,24 @@ module SoldierOfCode
|
|
265
300
|
@identifier.split(" ").each do |ident|
|
266
301
|
ident_sub = ident.sub("Version\/", "") if ident.include?("Version")
|
267
302
|
if ident_sub then
|
268
|
-
|
269
|
-
@browser_version_major = vs[0] if vs.size > 0
|
270
|
-
@browser_version_minor = vs[1] if vs.size > 1
|
271
|
-
@browser_version_sub = vs[2] if vs.size > 2
|
303
|
+
@version.update(*ident_sub.split(/[.,]/))
|
272
304
|
end
|
273
305
|
end
|
274
306
|
end
|
275
307
|
|
276
308
|
if @identifier == "Safari/412 Privoxy/3.0" then
|
277
|
-
@
|
278
|
-
@
|
279
|
-
@
|
309
|
+
@version.major = '2'
|
310
|
+
@version.minor = '0'
|
311
|
+
@version.sub = nil
|
280
312
|
end
|
281
313
|
|
282
|
-
break if @
|
314
|
+
break if @version.major
|
283
315
|
end
|
284
316
|
end
|
285
317
|
|
286
|
-
if @browser == nil &&
|
318
|
+
if @browser == nil && @os.osx? && agent_string.include?("AppleWebKit")
|
287
319
|
@browser = "Safari"
|
288
320
|
end
|
289
|
-
|
290
|
-
return true if @browser && @browser_version_major
|
291
|
-
false
|
292
321
|
end
|
293
322
|
|
294
323
|
#
|
@@ -309,31 +338,19 @@ module SoldierOfCode
|
|
309
338
|
end
|
310
339
|
if @detail.include?("MSIE")
|
311
340
|
@detail.gsub(/[\\:\?'"%!@#\$\^&\*\(\)\+]/, '').split(";").each do |sec|
|
312
|
-
if sec.strip.
|
313
|
-
|
314
|
-
@browser_version_major = s[0] if s.size > 0
|
315
|
-
@browser_version_minor = s[1] if s.size > 1
|
341
|
+
if sec.strip.index("MSIE ") == 0
|
342
|
+
@version.update(*sec.strip.sub("MSIE ", "").gsub(/0(\d)/, '0.\1').split(/[.,]/))
|
316
343
|
end
|
317
344
|
|
318
|
-
break if @
|
345
|
+
break if @version.major
|
319
346
|
end
|
320
347
|
end
|
321
348
|
|
322
|
-
unless @
|
323
|
-
if
|
324
|
-
@browser = "MSIE"
|
325
|
-
@browser_version_major = '6'
|
326
|
-
@browser_version_minor = '0'
|
327
|
-
end
|
328
|
-
if agent.include?("MSIE 7.0")
|
349
|
+
unless @version.major
|
350
|
+
if match = /MSIE ([6789])\.0/.match(agent)
|
329
351
|
@browser = "MSIE"
|
330
|
-
@
|
331
|
-
@
|
332
|
-
end
|
333
|
-
if agent.include?("MSIE 8.0")
|
334
|
-
@browser = "MSIE"
|
335
|
-
@browser_version_major = '8'
|
336
|
-
@browser_version_minor = '0'
|
352
|
+
@version.major = match[1]
|
353
|
+
@version.minor = '0'
|
337
354
|
end
|
338
355
|
end
|
339
356
|
end
|
@@ -359,35 +376,33 @@ module SoldierOfCode
|
|
359
376
|
if @identifier.include?("Firefox") || @renderer.include?("Firefox") || @engine.include?("Firefox")
|
360
377
|
@browser = "Firefox"
|
361
378
|
|
362
|
-
|
363
379
|
identifier_sub = nil
|
364
|
-
@identifier.gsub(/[\\:\?'"%!@#\$\^&\*\(\)\+]/, '').split(" ").
|
365
|
-
|
366
|
-
|
380
|
+
@identifier.gsub(/[\\:\?'"%!@#\$\^&\*\(\)\+]/, '').split(" ").find do |ident|
|
381
|
+
if ident.include?("Firefox")
|
382
|
+
identifier_sub = ident.sub("Firefox\/", "").sub("Gecko/", "")
|
383
|
+
identifier_sub.gsub!(/[\+]/, '')
|
384
|
+
end
|
385
|
+
identifier_sub
|
367
386
|
end
|
368
|
-
if identifier_sub
|
387
|
+
if identifier_sub.nil? && @renderer.include?("Firefox")
|
369
388
|
renderer_gsub_gsub = @renderer.sub("\(", "").sub("\)", "")
|
370
389
|
renderer_gsub_gsub.strip.split(",").each do |sec|
|
371
390
|
identifier_sub = sec.sub("Firefox\/", "").strip if sec.include?("Firefox")
|
372
391
|
end
|
373
392
|
end
|
374
|
-
if identifier_sub
|
393
|
+
if identifier_sub.nil? && @engine.include?("Firefox")
|
375
394
|
@engine.gsub(/[\\:\?'"%!@#\$\^&\*\(\)\+]/, '').split(" ").each do |ident|
|
376
395
|
identifier_sub = ident.sub("Firefox\/", "").sub("Gecko/", "") if ident.include?("Firefox")
|
377
396
|
identifier_sub.gsub!(/[\+]/, '') if identifier_sub && identifier_sub.include?("+")
|
378
397
|
end
|
379
398
|
end
|
399
|
+
|
400
|
+
identifier_sub.gsub!(/;.*/, '')
|
380
401
|
|
381
402
|
if identifier_sub
|
382
|
-
|
383
|
-
@browser_version_major = version_numbers[0] if version_numbers.size > 0
|
384
|
-
@browser_version_minor = version_numbers[1] if version_numbers.size > 1
|
385
|
-
@browser_version_sub = version_numbers[2] if version_numbers.size > 2
|
403
|
+
@version.update(*identifier_sub.split("."))
|
386
404
|
end
|
387
|
-
|
388
405
|
end
|
389
|
-
return true if @browser && @browser_version_major
|
390
|
-
false
|
391
406
|
end
|
392
407
|
|
393
408
|
#
|
@@ -421,3 +436,5 @@ module SoldierOfCode
|
|
421
436
|
end
|
422
437
|
end
|
423
438
|
end
|
439
|
+
|
440
|
+
SOC = SoldierOfCode
|
data/test/msie/msie-6.0.txt
CHANGED
@@ -15,7 +15,6 @@ Mozilla/4.0 (MSIE 6.0; Windows NT 5.0)
|
|
15
15
|
Mozilla/4.0 (compatible;MSIE 6.0;Windows 98;Q312461)
|
16
16
|
Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
|
17
17
|
Mozilla/4.0 (compatible; U; MSIE 6.0; Windows NT 5.1)
|
18
|
-
Mozilla/4.0 (compatible; MSIE 6.1; Windows XP) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
|
19
18
|
Mozilla/4.0 (compatible; MSIE 6.0; Windows; U; Win98; en-US)
|
20
19
|
Mozilla/4.0 (compatible; MSIE 6.0; Windows XP; InfoPath.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
|
21
20
|
Mozilla/4.0 (compatible; MSIE 6.0; Windows XP; DigExt)
|
data/test/safari/safari.txt
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092816 Mobile Safari 1.1.3
|
2
2
|
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; fi-fi) AppleWebKit/420+ (KHTML, like Gecko) Safari/419.3
|
3
|
-
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/312.8.1 (KHTML, like Gecko) Safari/312.6
|
4
3
|
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/419.2 (KHTML, like Gecko) Safari/419.3
|
5
4
|
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3
|
6
5
|
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-ch) AppleWebKit/85 (KHTML, like Gecko) Safari/85
|
data/test/ss-test.rb
CHANGED
@@ -1,154 +1,34 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "rack/test"
|
3
3
|
require "test/unit"
|
4
|
-
require
|
4
|
+
require 'dirge'
|
5
|
+
require ~"../lib/spy_vs_spy"
|
5
6
|
|
6
7
|
class SpyVsSpyTest < Test::Unit::TestCase
|
7
8
|
include Rack::Test::Methods
|
8
9
|
|
9
10
|
def app
|
10
|
-
|
11
|
+
SOC::SpyVsSpy::Middleware.new(self)
|
11
12
|
end
|
12
13
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
rx = Regexp.new("^safari(\-(([0-9])(.*)))\.txt")
|
30
|
-
rx.match(filename)
|
31
|
-
#puts "#{__FILE__}:#{__LINE__} #{__method__} #{$1} - #{$2} - #{$3} - #{$4} - #{$5} - #{$6} - #{$7}"
|
32
|
-
major_version = $3
|
33
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{major_version}"
|
34
|
-
|
35
|
-
while (line = file.gets)
|
36
|
-
|
37
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{line}"
|
38
|
-
r = SoldierOfCode::SpyVsSpy.new.parse(line)
|
39
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} BROWSER: #{r.browser}"
|
40
|
-
assert r.browser == 'Safari'
|
41
|
-
|
42
|
-
if major_version && major_version.length > 0
|
43
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{line}"
|
44
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{r.browser_version_major} == #{major_version} ? #{r.browser_version_major == major_version}"
|
45
|
-
assert r.browser_version_major == major_version
|
14
|
+
def test_parse
|
15
|
+
|
16
|
+
Dir[~'**/*.txt'].each do |file|
|
17
|
+
browser_name, version_string = File.basename(file)[/^(.*)\.txt$/, 1].split('-')
|
18
|
+
puts ">>> #{browser_name} -- #{version_string}"
|
19
|
+
if version_string
|
20
|
+
major, minor, sub = version_string.split(/[,\.]/)
|
21
|
+
File.open(file) do |f|
|
22
|
+
f.each_line do |line|
|
23
|
+
puts "testing #{line}"
|
24
|
+
r = SoldierOfCode::SpyVsSpy.new(line)
|
25
|
+
assert_equal browser_name.downcase, r.browser.downcase
|
26
|
+
assert_equal major, r.version.major
|
27
|
+
assert_equal minor, r.version.minor
|
28
|
+
assert_equal sub, r.version.sub
|
29
|
+
end
|
46
30
|
end
|
47
|
-
|
48
|
-
ua_count+=1
|
49
|
-
|
50
31
|
end
|
51
|
-
|
52
|
-
|
53
32
|
end
|
54
|
-
|
55
|
-
puts "Number of safari agents tested: #{ua_count}"
|
56
|
-
|
57
|
-
|
58
33
|
end
|
59
|
-
|
60
|
-
def test_firefox_parse
|
61
|
-
|
62
|
-
basedir = File.dirname(__FILE__)+"/firefox"
|
63
|
-
contains = Dir.new(basedir).entries
|
64
|
-
contains.delete(".")
|
65
|
-
contains.delete("..")
|
66
|
-
|
67
|
-
ua_count = 0
|
68
|
-
|
69
|
-
contains.each do |filename|
|
70
|
-
|
71
|
-
file = File.new("#{File.dirname(__FILE__)}/firefox/#{filename}", "r")
|
72
|
-
|
73
|
-
# puts <<-r
|
74
|
-
#filename: #{filename}
|
75
|
-
# r
|
76
|
-
rx = Regexp.new("^firefox(\-(([0-9])(.*)))\.txt")
|
77
|
-
rx.match(filename)
|
78
|
-
#puts "#{__FILE__}:#{__LINE__} #{__method__} #{$1} - #{$2} - #{$3} - #{$4} - #{$5} - #{$6} - #{$7}"
|
79
|
-
major_version = $3
|
80
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{major_version}"
|
81
|
-
|
82
|
-
while (line = file.gets)
|
83
|
-
|
84
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{line}"
|
85
|
-
r = SoldierOfCode::SpyVsSpy.new.parse(line)
|
86
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} BROWSER: #{r.browser}"
|
87
|
-
assert r.browser == 'Firefox'
|
88
|
-
|
89
|
-
if major_version && major_version.length > 0
|
90
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{line}"
|
91
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} [#{r.browser_version_major}] == [#{major_version}] ? #{r.browser_version_major == major_version}"
|
92
|
-
assert r.browser_version_major == major_version
|
93
|
-
end
|
94
|
-
|
95
|
-
ua_count+=1
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
puts "Number of firefox agents tested: #{ua_count}"
|
103
|
-
|
104
|
-
|
105
|
-
end
|
106
|
-
|
107
|
-
def test_msie_parse
|
108
|
-
|
109
|
-
basedir = File.dirname(__FILE__)+"/msie"
|
110
|
-
contains = Dir.new(basedir).entries
|
111
|
-
contains.delete(".")
|
112
|
-
contains.delete("..")
|
113
|
-
|
114
|
-
ua_count = 0
|
115
|
-
|
116
|
-
contains.each do |filename|
|
117
|
-
|
118
|
-
file = File.new("#{File.dirname(__FILE__)}/msie/#{filename}", "r")
|
119
|
-
#
|
120
|
-
# puts <<-r
|
121
|
-
#filename: #{filename}
|
122
|
-
# r
|
123
|
-
rx = Regexp.new("^msie(\-(([0-9])(.*)))\.txt")
|
124
|
-
rx.match(filename)
|
125
|
-
#puts "#{__FILE__}:#{__LINE__} #{__method__} #{$1} - #{$2} - #{$3} - #{$4} - #{$5} - #{$6} - #{$7}"
|
126
|
-
major_version = $3
|
127
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{major_version}"
|
128
|
-
|
129
|
-
while (line = file.gets)
|
130
|
-
|
131
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{line}"
|
132
|
-
r = SoldierOfCode::SpyVsSpy.new.parse(line)
|
133
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} BROWSER: #{r.browser}"
|
134
|
-
assert r.browser == 'MSIE'
|
135
|
-
|
136
|
-
if major_version && major_version.length > 0
|
137
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} #{line}"
|
138
|
-
# puts "#{__FILE__}:#{__LINE__} #{__method__} [#{r.browser_version_major}] == [#{major_version}] ? #{r.browser_version_major == major_version}"
|
139
|
-
assert r.browser_version_major == major_version
|
140
|
-
end
|
141
|
-
|
142
|
-
ua_count+=1
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
puts "Number of internet explorer agents tested: #{ua_count}"
|
150
|
-
|
151
|
-
|
152
|
-
end
|
153
|
-
|
154
34
|
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spy-vs-spy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Kristan
|
7
|
+
- Kristan "Krispy" Uccello
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
@@ -13,26 +13,90 @@ date: 2009-11-23 00:00:00 -05:00
|
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description:
|
17
|
-
email:
|
16
|
+
description: Rack middleware to detect and provide more detail on the requesting user agent edit
|
17
|
+
email: kuccello@gmail.com
|
18
18
|
executables: []
|
19
19
|
|
20
20
|
extensions: []
|
21
21
|
|
22
22
|
extra_rdoc_files:
|
23
|
+
- LICENSE
|
23
24
|
- README
|
24
25
|
files:
|
26
|
+
- Change.log
|
27
|
+
- LICENSE
|
25
28
|
- README
|
26
|
-
-
|
27
|
-
-
|
29
|
+
- Rakefile
|
30
|
+
- VERSION
|
31
|
+
- lib/spy_vs_spy.rb
|
32
|
+
- test/firefox/firefox-3.1b2.txt
|
33
|
+
- test/firefox/firefox-3.1b2pre.txt
|
34
|
+
- test/firefox/firefox-3.1b3.txt
|
35
|
+
- test/firefox/firefox-3.1b3pre.txt
|
36
|
+
- test/firefox/firefox-3.5.1.txt
|
37
|
+
- test/firefox/firefox-3.5.12.txt
|
38
|
+
- test/firefox/firefox-3.5.2.txt
|
39
|
+
- test/firefox/firefox-3.5.3.txt
|
40
|
+
- test/firefox/firefox-3.5.3pre.txt
|
41
|
+
- test/firefox/firefox-3.5.4.txt
|
42
|
+
- test/firefox/firefox-3.5.5.txt
|
43
|
+
- test/firefox/firefox-3.5.txt
|
44
|
+
- test/firefox/firefox-3.5b4.txt
|
45
|
+
- test/firefox/firefox-3.5b4pre.txt
|
46
|
+
- test/firefox/firefox-3.6.txt
|
47
|
+
- test/firefox/firefox-3.6a1pre.txt
|
48
|
+
- test/firefox/firefox-3.6b1.txt
|
49
|
+
- test/firefox/firefox-3.8.txt
|
50
|
+
- test/msie/msie-5.5.txt
|
51
|
+
- test/msie/msie-5.5b1.txt
|
52
|
+
- test/msie/msie-6,0.txt
|
53
|
+
- test/msie/msie-6.0.1.txt
|
54
|
+
- test/msie/msie-6.0.txt
|
55
|
+
- test/msie/msie-6.0b.txt
|
56
|
+
- test/msie/msie-6.1.txt
|
57
|
+
- test/msie/msie-7.0.txt
|
58
|
+
- test/msie/msie-7.0b.txt
|
59
|
+
- test/msie/msie-8.0.txt
|
60
|
+
- test/safari/safari-1.0.3.txt
|
61
|
+
- test/safari/safari-1.0.txt
|
62
|
+
- test/safari/safari-1.2.2.txt
|
63
|
+
- test/safari/safari-1.2.3.txt
|
64
|
+
- test/safari/safari-1.2.4.txt
|
65
|
+
- test/safari/safari-1.2.txt
|
66
|
+
- test/safari/safari-1.3.1.txt
|
67
|
+
- test/safari/safari-1.3.2.txt
|
68
|
+
- test/safari/safari-1.3.txt
|
69
|
+
- test/safari/safari-2.0.1.txt
|
70
|
+
- test/safari/safari-2.0.2.txt
|
71
|
+
- test/safari/safari-2.0.3.txt
|
72
|
+
- test/safari/safari-2.0.4.txt
|
73
|
+
- test/safari/safari-2.0.txt
|
74
|
+
- test/safari/safari-3.0.1.txt
|
75
|
+
- test/safari/safari-3.0.2.txt
|
76
|
+
- test/safari/safari-3.0.3.txt
|
77
|
+
- test/safari/safari-3.0.4.txt
|
78
|
+
- test/safari/safari-3.0.txt
|
79
|
+
- test/safari/safari-3.1.1.txt
|
80
|
+
- test/safari/safari-3.1.2.txt
|
81
|
+
- test/safari/safari-3.1.txt
|
82
|
+
- test/safari/safari-3.2.1.txt
|
83
|
+
- test/safari/safari-3.2.2.txt
|
84
|
+
- test/safari/safari-3.2.3.txt
|
85
|
+
- test/safari/safari-3.2.txt
|
86
|
+
- test/safari/safari-4.0.1.txt
|
87
|
+
- test/safari/safari-4.0.2.txt
|
88
|
+
- test/safari/safari-4.0.3.txt
|
89
|
+
- test/safari/safari-4.0.txt
|
90
|
+
- test/safari/safari-4.0dp1.txt
|
91
|
+
- test/safari/safari.txt
|
92
|
+
- test/ss-test.rb
|
28
93
|
has_rdoc: true
|
29
94
|
homepage: http://github.com/kuccello/Spy-Vs-Spy
|
30
95
|
licenses: []
|
31
96
|
|
32
97
|
post_install_message:
|
33
98
|
rdoc_options:
|
34
|
-
- --
|
35
|
-
- README
|
99
|
+
- --charset=UTF-8
|
36
100
|
require_paths:
|
37
101
|
- lib
|
38
102
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -53,66 +117,6 @@ rubyforge_project:
|
|
53
117
|
rubygems_version: 1.3.5
|
54
118
|
signing_key:
|
55
119
|
specification_version: 3
|
56
|
-
summary:
|
120
|
+
summary: Rack middleware to detect and provide more detail on the requesting user agent edit
|
57
121
|
test_files:
|
58
122
|
- test/ss-test.rb
|
59
|
-
- test/msie/msie-5.5.txt
|
60
|
-
- test/msie/msie-5.5b1.txt
|
61
|
-
- test/msie/msie-6,0.txt
|
62
|
-
- test/msie/msie-6.0.1.txt
|
63
|
-
- test/msie/msie-6.0.txt
|
64
|
-
- test/msie/msie-6.0b.txt
|
65
|
-
- test/msie/msie-6.1.txt
|
66
|
-
- test/msie/msie-7.0.txt
|
67
|
-
- test/msie/msie-7.0b.txt
|
68
|
-
- test/msie/msie-8.0.txt
|
69
|
-
- test/safari/safari-1.0.3.txt
|
70
|
-
- test/safari/safari-1.2.3.txt
|
71
|
-
- test/safari/safari-1.3.1.txt
|
72
|
-
- test/safari/safari-2.0.1.txt
|
73
|
-
- test/safari/safari-2.0.4.txt
|
74
|
-
- test/safari/safari-3.0.2.txt
|
75
|
-
- test/safari/safari-3.0.txt
|
76
|
-
- test/safari/safari-3.1.txt
|
77
|
-
- test/safari/safari-3.2.3.txt
|
78
|
-
- test/safari/safari-4.0.2.txt
|
79
|
-
- test/safari/safari-4.0dp1.txt
|
80
|
-
- test/safari/safari-1.0.txt
|
81
|
-
- test/safari/safari-1.2.4.txt
|
82
|
-
- test/safari/safari-1.3.2.txt
|
83
|
-
- test/safari/safari-2.0.2.txt
|
84
|
-
- test/safari/safari-2.0.txt
|
85
|
-
- test/safari/safari-3.0.3.txt
|
86
|
-
- test/safari/safari-3.1.1.txt
|
87
|
-
- test/safari/safari-3.2.1.txt
|
88
|
-
- test/safari/safari-3.2.txt
|
89
|
-
- test/safari/safari-4.0.3.txt
|
90
|
-
- test/safari/safari.txt
|
91
|
-
- test/safari/safari-1.2.2.txt
|
92
|
-
- test/safari/safari-1.2.txt
|
93
|
-
- test/safari/safari-1.3.txt
|
94
|
-
- test/safari/safari-2.0.3.txt
|
95
|
-
- test/safari/safari-3.0.1.txt
|
96
|
-
- test/safari/safari-3.0.4.txt
|
97
|
-
- test/safari/safari-3.1.2.txt
|
98
|
-
- test/safari/safari-3.2.2.txt
|
99
|
-
- test/safari/safari-4.0.1.txt
|
100
|
-
- test/safari/safari-4.0.txt
|
101
|
-
- test/firefox/firefox-3.1b2.txt
|
102
|
-
- test/firefox/firefox-3.1b3.txt
|
103
|
-
- test/firefox/firefox-3.5.1.txt
|
104
|
-
- test/firefox/firefox-3.5.2.txt
|
105
|
-
- test/firefox/firefox-3.5.3pre.txt
|
106
|
-
- test/firefox/firefox-3.5.5.txt
|
107
|
-
- test/firefox/firefox-3.5b4.txt
|
108
|
-
- test/firefox/firefox-3.6.txt
|
109
|
-
- test/firefox/firefox-3.6b1.txt
|
110
|
-
- test/firefox/firefox-3.1b2pre.txt
|
111
|
-
- test/firefox/firefox-3.1b3pre.txt
|
112
|
-
- test/firefox/firefox-3.5.12.txt
|
113
|
-
- test/firefox/firefox-3.5.3.txt
|
114
|
-
- test/firefox/firefox-3.5.4.txt
|
115
|
-
- test/firefox/firefox-3.5.txt
|
116
|
-
- test/firefox/firefox-3.5b4pre.txt
|
117
|
-
- test/firefox/firefox-3.6a1pre.txt
|
118
|
-
- test/firefox/firefox-3.8.txt
|
data/spy-vs-spy.gemspec
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
Gem::Specification.new do |s|
|
2
|
-
s.name = "spy-vs-spy"
|
3
|
-
s.version = "0.0.4"
|
4
|
-
s.date = "2009-11-23"
|
5
|
-
s.summary = "UserAgent Detection Middleware for Rack."
|
6
|
-
s.email = "kaptiankrispy@soldierofcode.com"
|
7
|
-
s.homepage = "http://github.com/kuccello/Spy-Vs-Spy"
|
8
|
-
s.description = ""
|
9
|
-
s.has_rdoc = true
|
10
|
-
s.authors = ["Kristan 'Krispy' Uccello"]
|
11
|
-
s.files = ["README",
|
12
|
-
"spy-vs-spy.gemspec",
|
13
|
-
"lib/spy-vs-spy.rb"]
|
14
|
-
s.test_files = ["test/ss-test.rb", "test/msie/msie-5.5.txt",
|
15
|
-
"test/msie/msie-5.5b1.txt",
|
16
|
-
"test/msie/msie-6,0.txt",
|
17
|
-
"test/msie/msie-6.0.1.txt",
|
18
|
-
"test/msie/msie-6.0.txt",
|
19
|
-
"test/msie/msie-6.0b.txt",
|
20
|
-
"test/msie/msie-6.1.txt",
|
21
|
-
"test/msie/msie-7.0.txt",
|
22
|
-
"test/msie/msie-7.0b.txt",
|
23
|
-
"test/msie/msie-8.0.txt",
|
24
|
-
"test/safari/safari-1.0.3.txt",
|
25
|
-
"test/safari/safari-1.2.3.txt",
|
26
|
-
"test/safari/safari-1.3.1.txt",
|
27
|
-
"test/safari/safari-2.0.1.txt",
|
28
|
-
"test/safari/safari-2.0.4.txt",
|
29
|
-
"test/safari/safari-3.0.2.txt",
|
30
|
-
"test/safari/safari-3.0.txt",
|
31
|
-
"test/safari/safari-3.1.txt",
|
32
|
-
"test/safari/safari-3.2.3.txt",
|
33
|
-
"test/safari/safari-4.0.2.txt",
|
34
|
-
"test/safari/safari-4.0dp1.txt",
|
35
|
-
"test/safari/safari-1.0.txt",
|
36
|
-
"test/safari/safari-1.2.4.txt",
|
37
|
-
"test/safari/safari-1.3.2.txt",
|
38
|
-
"test/safari/safari-2.0.2.txt",
|
39
|
-
"test/safari/safari-2.0.txt",
|
40
|
-
"test/safari/safari-3.0.3.txt",
|
41
|
-
"test/safari/safari-3.1.1.txt",
|
42
|
-
"test/safari/safari-3.2.1.txt",
|
43
|
-
"test/safari/safari-3.2.txt",
|
44
|
-
"test/safari/safari-4.0.3.txt",
|
45
|
-
"test/safari/safari.txt",
|
46
|
-
"test/safari/safari-1.2.2.txt",
|
47
|
-
"test/safari/safari-1.2.txt",
|
48
|
-
"test/safari/safari-1.3.txt",
|
49
|
-
"test/safari/safari-2.0.3.txt",
|
50
|
-
"test/safari/safari-3.0.1.txt",
|
51
|
-
"test/safari/safari-3.0.4.txt",
|
52
|
-
"test/safari/safari-3.1.2.txt",
|
53
|
-
"test/safari/safari-3.2.2.txt",
|
54
|
-
"test/safari/safari-4.0.1.txt",
|
55
|
-
"test/safari/safari-4.0.txt",
|
56
|
-
"test/firefox/firefox-3.1b2.txt",
|
57
|
-
"test/firefox/firefox-3.1b3.txt",
|
58
|
-
"test/firefox/firefox-3.5.1.txt",
|
59
|
-
"test/firefox/firefox-3.5.2.txt",
|
60
|
-
"test/firefox/firefox-3.5.3pre.txt",
|
61
|
-
"test/firefox/firefox-3.5.5.txt",
|
62
|
-
"test/firefox/firefox-3.5b4.txt",
|
63
|
-
"test/firefox/firefox-3.6.txt",
|
64
|
-
"test/firefox/firefox-3.6b1.txt",
|
65
|
-
"test/firefox/firefox-3.1b2pre.txt",
|
66
|
-
"test/firefox/firefox-3.1b3pre.txt",
|
67
|
-
"test/firefox/firefox-3.5.12.txt",
|
68
|
-
"test/firefox/firefox-3.5.3.txt",
|
69
|
-
"test/firefox/firefox-3.5.4.txt",
|
70
|
-
"test/firefox/firefox-3.5.txt",
|
71
|
-
"test/firefox/firefox-3.5b4pre.txt",
|
72
|
-
"test/firefox/firefox-3.6a1pre.txt",
|
73
|
-
"test/firefox/firefox-3.8.txt"]
|
74
|
-
s.rdoc_options = ["--main", "README"]
|
75
|
-
s.extra_rdoc_files = ["README"]
|
76
|
-
end
|