card 1.18.0 → 1.18.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/card.gemspec +20 -16
- data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
- data/db/schema.rb +110 -92
- data/lib/card.rb +1 -0
- data/lib/card/content.rb +4 -73
- data/lib/card/content/chunk.rb +119 -0
- data/lib/card/content/parser.rb +75 -0
- data/lib/card/diff.rb +25 -398
- data/lib/card/diff/lcs.rb +247 -0
- data/lib/card/diff/result.rb +131 -0
- data/lib/card/director_register.rb +5 -0
- data/lib/card/query/attributes.rb +19 -13
- data/lib/card/set/event.rb +2 -1
- data/lib/card/set_pattern.rb +4 -2
- data/lib/card/spec_helper.rb +7 -1
- data/lib/card/stage_director.rb +33 -5
- data/lib/card/subcards.rb +11 -3
- data/lib/card/subdirector_array.rb +14 -1
- data/lib/cardio.rb +8 -5
- data/mod/01_core/chunk/include.rb +2 -2
- data/mod/01_core/chunk/link.rb +3 -3
- data/mod/01_core/chunk/literal.rb +20 -14
- data/mod/01_core/chunk/query_reference.rb +2 -2
- data/mod/01_core/chunk/reference.rb +47 -38
- data/mod/01_core/chunk/uri.rb +17 -13
- data/mod/01_core/format/html_format.rb +0 -2
- data/mod/01_core/set/all/actify.rb +12 -1
- data/mod/01_core/set/all/collection.rb +4 -4
- data/mod/01_core/set/all/fetch.rb +0 -27
- data/mod/01_core/set/all/name.rb +33 -12
- data/mod/01_core/set/all/pattern.rb +2 -6
- data/mod/01_core/set/all/phases.rb +0 -1
- data/mod/01_core/set/all/references.rb +2 -2
- data/mod/01_core/set/all/rules.rb +10 -3
- data/mod/01_core/set/all/tracked_attributes.rb +0 -1
- data/mod/01_core/set/all/type.rb +0 -14
- data/mod/01_core/spec/chunk/literal_spec.rb +1 -1
- data/mod/01_core/spec/chunk/uri_spec.rb +204 -201
- data/mod/01_core/spec/set/all/type_spec.rb +3 -1
- data/mod/01_history/lib/card/action.rb +7 -9
- data/mod/01_history/set/all/history.rb +6 -1
- data/mod/02_basic_types/set/all/all_csv.rb +1 -1
- data/mod/02_basic_types/set/type/pointer.rb +20 -9
- data/mod/03_machines/lib/javascript/wagn.js.coffee +1 -1
- data/mod/04_settings/set/right/structure.rb +7 -1
- data/mod/05_email/set/right/follow.rb +22 -22
- data/mod/05_email/set/type_plus_right/user/follow.rb +25 -26
- data/mod/05_standard/set/all/rich_html/wrapper.rb +12 -6
- data/mod/05_standard/set/rstar/rules_editor.rb +6 -4
- data/mod/05_standard/set/self/all.rb +0 -10
- data/mod/05_standard/set/self/stats.rb +6 -15
- data/mod/05_standard/set/type/set.rb +0 -6
- data/mod/05_standard/spec/chunk/include_spec.rb +2 -2
- data/mod/05_standard/spec/chunk/link_spec.rb +1 -1
- data/mod/05_standard/spec/chunk/query_reference_spec.rb +5 -4
- data/spec/lib/card/chunk_spec.rb +7 -5
- data/spec/lib/card/content_spec.rb +11 -11
- data/spec/lib/card/diff_spec.rb +4 -4
- data/spec/lib/card/stage_director_spec.rb +56 -0
- data/spec/lib/card/subcards_spec.rb +0 -1
- data/spec/models/card/type_transition_spec.rb +5 -42
- metadata +12 -23
- data/lib/card/chunk.rb +0 -122
@@ -17,7 +17,6 @@ def abort status, msg='action canceled'
|
|
17
17
|
end
|
18
18
|
raise Card::Abort.new(status, msg)
|
19
19
|
end
|
20
|
-
|
21
20
|
module ClassMethods
|
22
21
|
def create! opts
|
23
22
|
card = Card.new opts
|
@@ -48,6 +47,18 @@ def delete!
|
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
50
|
+
def save!(*)
|
51
|
+
act do
|
52
|
+
super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def save(*)
|
57
|
+
act do
|
58
|
+
super
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
51
62
|
def update_attributes opts
|
52
63
|
act do
|
53
64
|
super opts
|
@@ -177,14 +177,14 @@ format do
|
|
177
177
|
|
178
178
|
def each_reference_with_args args={}
|
179
179
|
content_object = Card::Content.new _render_raw(args), card
|
180
|
-
content_object.find_chunks(Card::Chunk::Reference).each do |chunk|
|
180
|
+
content_object.find_chunks(Card::Content::Chunk::Reference).each do |chunk|
|
181
181
|
yield chunk.referee_name.to_s, nest_args(args, chunk)
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
185
|
def each_nested_chunk args={}
|
186
186
|
content_object = Card::Content.new(_render_raw(args), card)
|
187
|
-
content_object.find_chunks(Card::Chunk::Include).each do |chunk|
|
187
|
+
content_object.find_chunks(Card::Content::Chunk::Include).each do |chunk|
|
188
188
|
yield(chunk) if chunk.referee_name # filter commented nests
|
189
189
|
end
|
190
190
|
end
|
@@ -237,9 +237,9 @@ format do
|
|
237
237
|
r_args.merge! @nest_opts.clone if @nest_opts
|
238
238
|
|
239
239
|
case chunk
|
240
|
-
when Card::Chunk::Include
|
240
|
+
when Card::Content::Chunk::Include
|
241
241
|
r_args.merge!(chunk.options)
|
242
|
-
when Card::Chunk::Link
|
242
|
+
when Card::Content::Chunk::Link
|
243
243
|
r_args.reverse_merge!(view: :link)
|
244
244
|
r_args.reverse_merge!(title: chunk.link_text) if chunk.link_text
|
245
245
|
end
|
@@ -108,33 +108,6 @@ module ClassMethods
|
|
108
108
|
Card.cache.delete "~#{card.id}" if card.id
|
109
109
|
end
|
110
110
|
|
111
|
-
# set_names reverse map (cached)
|
112
|
-
# FIXME: move to set handling
|
113
|
-
def cached_set_members key
|
114
|
-
set_cache_list = Card.cache.read "$#{key}"
|
115
|
-
set_cache_list.nil? ? [] : set_cache_list.keys
|
116
|
-
end
|
117
|
-
|
118
|
-
# updates the members hash for all sets self is a member of
|
119
|
-
# QUESTION: why map and not each?
|
120
|
-
# I don't see where that array is useful. It contains
|
121
|
-
# nil for all sets for which self was already cached as a member
|
122
|
-
def set_members set_names, key
|
123
|
-
set_names.compact.map do |set_name|
|
124
|
-
# dollar sign avoids conflict with card keys
|
125
|
-
skey = "$#{set_name.to_name.key}"
|
126
|
-
h = Card.cache.read skey
|
127
|
-
if h.nil?
|
128
|
-
h = {}
|
129
|
-
elsif h[key]
|
130
|
-
next
|
131
|
-
end
|
132
|
-
h = h.dup if h.frozen?
|
133
|
-
h[key] = true
|
134
|
-
Card.cache.write skey, h
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
111
|
def validate_fetch_opts! opts
|
139
112
|
return unless opts[:new] && opts[:skip_virtual]
|
140
113
|
raise Card::Error, 'fetch called with new args and skip_virtual'
|
data/mod/01_core/set/all/name.rb
CHANGED
@@ -30,21 +30,42 @@ def name= newname
|
|
30
30
|
end
|
31
31
|
|
32
32
|
newkey = cardname.key
|
33
|
-
if key != newkey
|
34
|
-
|
35
|
-
# reset the old name - should be handled in tracked_attributes!!
|
36
|
-
reset_patterns_if_rule
|
37
|
-
reset_patterns
|
38
|
-
end
|
39
|
-
if @director
|
40
|
-
subcards.each do |subcard|
|
41
|
-
subcard.name = subcard.cardname.replace_part name, newname
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
33
|
+
self.key = newkey if key != newkey
|
34
|
+
update_subcard_names cardname
|
45
35
|
write_attribute :name, cardname.s
|
46
36
|
end
|
47
37
|
|
38
|
+
def key= newkey
|
39
|
+
was_in_cache = Card.cache.soft.delete key
|
40
|
+
write_attribute :key, newkey
|
41
|
+
# keep the soft cache up-to-date
|
42
|
+
Card.write_to_soft_cache self if was_in_cache
|
43
|
+
# reset the old name - should be handled in tracked_attributes!!
|
44
|
+
reset_patterns_if_rule
|
45
|
+
reset_patterns
|
46
|
+
newkey
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_subcard_names cardname
|
50
|
+
return unless @subcards
|
51
|
+
subcards.each do |subcard|
|
52
|
+
# if subcard has a relative name like +C
|
53
|
+
# and self is a subcard as well that changed from +B to A+B then
|
54
|
+
# +C should change to A+B+C. #replace_part doesn't work in this case
|
55
|
+
# because the old name +B is not a part of +C
|
56
|
+
# name_to_replace =
|
57
|
+
name_to_replace =
|
58
|
+
if subcard.cardname.junction? &&
|
59
|
+
subcard.cardname.parts.first.empty? &&
|
60
|
+
cardname.parts.first.present?
|
61
|
+
''.to_name
|
62
|
+
else
|
63
|
+
name
|
64
|
+
end
|
65
|
+
subcard.name = subcard.cardname.replace_part name_to_replace, cardname.s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
48
69
|
def cardname
|
49
70
|
name.to_name
|
50
71
|
end
|
@@ -24,7 +24,7 @@ def reset_patterns_if_rule saving=false
|
|
24
24
|
|
25
25
|
# FIXME: should be in right/read.rb
|
26
26
|
if saving && right.id == Card::ReadID
|
27
|
-
add_to_read_rule_update_queue
|
27
|
+
add_to_read_rule_update_queue set.item_cards(limit: 0)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -47,14 +47,10 @@ def set_format_modules klass
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def set_names
|
50
|
-
if @set_names.nil?
|
51
|
-
@set_names = patterns.map(&:to_s)
|
52
|
-
Card.set_members @set_names, key
|
53
|
-
end
|
50
|
+
@set_names = patterns.map(&:to_s) if @set_names.nil?
|
54
51
|
@set_names
|
55
52
|
end
|
56
53
|
|
57
54
|
def rule_set_keys
|
58
|
-
set_names # this triggers set_members cache. need better solution!
|
59
55
|
@rule_set_keys ||= patterns.map(&:rule_set_key).compact
|
60
56
|
end
|
@@ -44,7 +44,7 @@ end
|
|
44
44
|
# replace references in card content
|
45
45
|
def replace_reference_syntax old_name, new_name
|
46
46
|
obj_content = Card::Content.new raw_content, self
|
47
|
-
obj_content.find_chunks(Card::Chunk::Reference).select do |chunk|
|
47
|
+
obj_content.find_chunks(Card::Content::Chunk::Reference).select do |chunk|
|
48
48
|
next unless (old_ref_name = chunk.referee_name)
|
49
49
|
next unless (new_ref_name = old_ref_name.replace_part old_name, new_name)
|
50
50
|
chunk.referee_name = chunk.replace_reference old_name, new_name
|
@@ -66,7 +66,7 @@ end
|
|
66
66
|
def create_references_out
|
67
67
|
ref_hash = {}
|
68
68
|
content_obj = Card::Content.new raw_content, self
|
69
|
-
content_obj.find_chunks(Card::Chunk::Reference).each do |chunk|
|
69
|
+
content_obj.find_chunks(Card::Content::Chunk::Reference).each do |chunk|
|
70
70
|
interpret_reference ref_hash, chunk.referee_name, chunk.reference_code
|
71
71
|
end
|
72
72
|
return if ref_hash.empty?
|
@@ -209,14 +209,21 @@ module ClassMethods
|
|
209
209
|
end
|
210
210
|
end
|
211
211
|
|
212
|
-
def
|
212
|
+
def preference_names user_name, setting_code
|
213
213
|
Card.search(
|
214
214
|
{ right: { codename: setting_code },
|
215
|
-
left: {
|
216
|
-
|
215
|
+
left: {
|
216
|
+
left: { type_id: SetID }, right: user_name
|
217
|
+
},
|
218
|
+
return: :name
|
219
|
+
}, "preference cards for user: #{user_name}"
|
217
220
|
)
|
218
221
|
end
|
219
222
|
|
223
|
+
def preference_cards user_name, setting_code
|
224
|
+
preference_names(user_name, setting_code).map { |name| Card.fetch name }
|
225
|
+
end
|
226
|
+
|
220
227
|
def rule_cache
|
221
228
|
Card.cache.read('RULES') || begin
|
222
229
|
@rule_hash = {}
|
data/mod/01_core/set/all/type.rb
CHANGED
@@ -51,17 +51,3 @@ event :validate_type, :validate, changed: :type_id do
|
|
51
51
|
"to #{rt.type_name}"
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
55
|
-
event :reset_type_specific_fields, :finalize do
|
56
|
-
# Example: if you save a card of type Phrase
|
57
|
-
# then reset set patterns for update all
|
58
|
-
# "Phrase+Something+*type plus right" cards
|
59
|
-
wql = { left: { left_id: type_id },
|
60
|
-
right: { codename: 'type_plus_right' }
|
61
|
-
}
|
62
|
-
wql_comment = "sets with a type_plus_right rule for #{name}"
|
63
|
-
|
64
|
-
Auth.as_bot do
|
65
|
-
Card.search(wql, wql_comment).each &:reset_set_patterns
|
66
|
-
end
|
67
|
-
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
|
-
describe Card::Chunk::EscapedLiteral, 'literal chunk tests' do
|
3
|
+
describe Card::Content::Chunk::EscapedLiteral, 'literal chunk tests' do
|
4
4
|
it 'should handle escaped link' do
|
5
5
|
expect(render_content('write this: \[[text]]'))
|
6
6
|
.to eq('write this: <span>[</span>[text]]')
|
@@ -1,263 +1,256 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
|
-
describe Card::Chunk::URI, 'URI chunk tests' do
|
3
|
+
describe Card::Content::Chunk::URI, 'URI chunk tests' do
|
4
4
|
it 'should test_non_matches' do
|
5
|
-
|
6
|
-
|
7
|
-
'One gemstone is the garnet:reddish in colour, like ruby')
|
5
|
+
no_match_uri 'There is no URI here'
|
6
|
+
no_match_uri 'One gemstone is the garnet:reddish in colour, like ruby'
|
8
7
|
end
|
9
8
|
|
10
|
-
it '
|
9
|
+
it 'works with simple uri' do
|
11
10
|
# Simplest case
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
it '
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
match_chunk(Card::Chunk::URI, 'www.example.com',
|
49
|
-
scheme: 'http', host: 'www.example.com', text: 'www.example.com', link_text: 'http://www.example.com'
|
50
|
-
)
|
51
|
-
match_chunk(Card::Chunk::URI, 'example.com',
|
52
|
-
scheme: 'http', host: 'example.com', text: 'example.com', link_text: 'http://example.com'
|
53
|
-
)
|
11
|
+
match_http_uri 'http://www.example.com',
|
12
|
+
host: 'www.example.com', path: ''
|
13
|
+
end
|
14
|
+
it 'works with trailing slash' do
|
15
|
+
match_http_uri 'http://www.example.com/',
|
16
|
+
host: 'www.example.com', path: '/'
|
17
|
+
end
|
18
|
+
it 'works with trailing slash inside html tags' do
|
19
|
+
match_http_uri '<p>http://www.example.com/</p>',
|
20
|
+
host: 'www.example.com', path: '/',
|
21
|
+
link_text: 'http://www.example.com/'
|
22
|
+
end
|
23
|
+
it 'works with trailing period (no longer suppressed .. spec?)' do
|
24
|
+
match_http_uri 'http://www.example.com/. ',
|
25
|
+
host: 'www.example.com', path: '/',
|
26
|
+
link_text: 'http://www.example.com/'
|
27
|
+
end
|
28
|
+
it 'works with trailing period inside html tags (dot change?)' do
|
29
|
+
match_http_uri '<p>http://www.example.com/.</p>',
|
30
|
+
host: 'www.example.com', path: '/',
|
31
|
+
link_text: 'http://www.example.com/'
|
32
|
+
end
|
33
|
+
it 'works with trailing ' do
|
34
|
+
match_http_uri 'http://www.example.com/ ',
|
35
|
+
host: 'www.example.com', path: '/',
|
36
|
+
link_text: 'http://www.example.com/'
|
37
|
+
end
|
38
|
+
it 'works without http://' do
|
39
|
+
match_http_uri 'www.example.com',
|
40
|
+
host: 'www.example.com',
|
41
|
+
text: 'www.example.com',
|
42
|
+
link_text: 'http://www.example.com'
|
43
|
+
match_http_uri 'example.com',
|
44
|
+
host: 'example.com',
|
45
|
+
text: 'example.com',
|
46
|
+
link_text: 'http://example.com'
|
54
47
|
end
|
55
48
|
it 'should match "unusual" base domain (was a bug in an early version)' do
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
it '
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
match_chunk(Card::Chunk::URI, 'irc://irc.freenode.net#recentchangescamp',
|
111
|
-
scheme: 'irc', host: 'irc.freenode.net',
|
112
|
-
fragment: 'recentchangescamp',
|
113
|
-
link_text: 'irc://irc.freenode.net#recentchangescamp')
|
49
|
+
match_http_uri 'http://example.com.au/',
|
50
|
+
host: 'example.com.au'
|
51
|
+
end
|
52
|
+
it 'works with "unusual" base domain without http://' do
|
53
|
+
match_http_uri 'example.com.au',
|
54
|
+
host: 'example.com.au',
|
55
|
+
text: 'example.com.au',
|
56
|
+
link_text: 'http://example.com.au'
|
57
|
+
end
|
58
|
+
it 'works with another "unusual" base domain' do
|
59
|
+
match_http_uri 'http://www.example.co.uk/',
|
60
|
+
host: 'www.example.co.uk'
|
61
|
+
match_http_uri 'example.co.uk',
|
62
|
+
host: 'example.co.uk',
|
63
|
+
text: 'example.co.uk',
|
64
|
+
link_text: 'http://example.co.uk'
|
65
|
+
end
|
66
|
+
it 'works with some path at the end' do
|
67
|
+
match_http_uri 'http://moinmoin.wikiwikiweb.de/HelpOnNavigation',
|
68
|
+
host: 'moinmoin.wikiwikiweb.de',
|
69
|
+
path: '/HelpOnNavigation'
|
70
|
+
end
|
71
|
+
it 'works with some path at the end, and without http:// prefix (@link_text has prefix added)' do
|
72
|
+
match_http_uri 'moinmoin.wikiwikiweb.de/HelpOnNavigation',
|
73
|
+
host: 'moinmoin.wikiwikiweb.de',
|
74
|
+
path: '/HelpOnNavigation',
|
75
|
+
text: 'moinmoin.wikiwikiweb.de/HelpOnNavigation',
|
76
|
+
link_text: 'http://moinmoin.wikiwikiweb.de/HelpOnNavigation'
|
77
|
+
end
|
78
|
+
it 'works with a port number' do
|
79
|
+
match_http_uri 'http://www.example.com:80',
|
80
|
+
host: 'www.example.com', port: 80,
|
81
|
+
path: ''
|
82
|
+
end
|
83
|
+
it 'works with a port number and a path' do
|
84
|
+
match_http_uri 'http://www.example.com.tw:80/HelpOnNavigation',
|
85
|
+
host: 'www.example.com.tw', port: 80,
|
86
|
+
path: '/HelpOnNavigation'
|
87
|
+
end
|
88
|
+
it 'works with a query' do
|
89
|
+
match_http_uri 'http://www.example.com.tw:80/HelpOnNavigation?arg=val',
|
90
|
+
host: 'www.example.com.tw', port: 80,
|
91
|
+
path: '/HelpOnNavigation', query: 'arg=val'
|
92
|
+
end
|
93
|
+
it 'works on Query with two arguments' do
|
94
|
+
match_http_uri 'http://www.example.com.tw:80/HelpOnNavigation?arg=val&arg2=val2',
|
95
|
+
host: 'www.example.com.tw', port: 80,
|
96
|
+
path: '/HelpOnNavigation', query: 'arg=val&arg2=val2'
|
97
|
+
end
|
98
|
+
it 'works with IRC' do
|
99
|
+
match_uri 'irc://irc.freenode.net#recentchangescamp',
|
100
|
+
scheme: 'irc', host: 'irc.freenode.net',
|
101
|
+
fragment: 'recentchangescamp',
|
102
|
+
link_text: 'irc://irc.freenode.net#recentchangescamp'
|
114
103
|
end
|
115
104
|
|
116
105
|
it 'should see HTTPS' do
|
117
|
-
|
118
|
-
|
119
|
-
|
106
|
+
match_uri 'https://www.example.com',
|
107
|
+
scheme: 'https', host: 'www.example.com', port: 443,
|
108
|
+
path: '', query: nil
|
120
109
|
end
|
121
110
|
it 'should see FTP' do
|
122
|
-
|
123
|
-
|
124
|
-
|
111
|
+
match_uri 'ftp://www.example.com',
|
112
|
+
scheme: 'ftp', host: 'www.example.com', port: 21,
|
113
|
+
path: '', query: nil
|
125
114
|
end
|
126
115
|
it 'should handle mailto:' do
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
# match_chunk(Card::Chunk::URI, 'foobar://www.example.com',
|
133
|
-
# scheme: 'foobar', host: 'www.example.com', port: '', path: '', query: nil,
|
134
|
-
# link_text: 'foobar://www.example.com')
|
116
|
+
match_uri 'mailto:jdoe123@example.com',
|
117
|
+
scheme: 'mailto', host: nil, port: nil,
|
118
|
+
path: nil, query: nil,
|
119
|
+
to: 'jdoe123@example.com'
|
120
|
+
end
|
135
121
|
|
136
122
|
it 'should run more basic cases' do
|
137
123
|
# from *css (with () around the URI)
|
138
124
|
# so, now this doesn't even match because I fixed the suspiciou* stuff
|
139
|
-
|
125
|
+
no_match_uri(
|
126
|
+
"background: url('http://dl.dropbox.com/u/4657397/wikirate/" \
|
127
|
+
"wikirate_files/wr-bg-menu-line.gif') repeat-x;"
|
128
|
+
)
|
140
129
|
|
141
|
-
# Soap opera (the most complex case imaginable... well, not really, there
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
130
|
+
# Soap opera (the most complex case imaginable... well, not really, there
|
131
|
+
# should be more evil)
|
132
|
+
match_http_uri(
|
133
|
+
'http://www.example.com.tw:80/~jdoe123/Help%20Me%20?arg=val&arg2=val2',
|
134
|
+
host: 'www.example.com.tw', port: 80,
|
135
|
+
path: '/~jdoe123/Help%20Me%20', query: 'arg=val&arg2=val2')
|
146
136
|
|
147
137
|
# from 0.9 bug reports
|
148
|
-
|
149
|
-
|
150
|
-
|
138
|
+
match_uri 'http://www2.pos.to/~tosh/ruby/rdtool/en/doc/rd-draft.html',
|
139
|
+
scheme: 'http', host: 'www2.pos.to',
|
140
|
+
path: '/~tosh/ruby/rdtool/en/doc/rd-draft.html'
|
151
141
|
|
152
|
-
|
153
|
-
|
154
|
-
|
142
|
+
match_uri 'http://support.microsoft.com/default.aspx?scid=kb;en-us;234562',
|
143
|
+
scheme: 'http', host: 'support.microsoft.com',
|
144
|
+
path: '/default.aspx', query: 'scid=kb;en-us;234562'
|
155
145
|
end
|
156
146
|
|
157
147
|
it 'should test_email_uri' do
|
158
|
-
|
159
|
-
|
160
|
-
|
148
|
+
match_uri 'mail@example.com',
|
149
|
+
to: 'mail@example.com', host: nil,
|
150
|
+
text: 'mail@example.com',
|
151
|
+
link_text: 'mailto:mail@example.com'
|
161
152
|
end
|
162
153
|
|
163
154
|
it 'should test_non_email' do
|
164
155
|
# The @ is part of the normal text, but 'example.com' is marked up.
|
165
|
-
|
156
|
+
match_uri 'Not an email: @example.com', uri: 'http://example.com'
|
166
157
|
end
|
167
158
|
|
168
159
|
it 'should test_textile_image' do
|
169
|
-
|
170
|
-
'This !http://hobix.com/sample.jpg! is a Textile image link.')
|
160
|
+
no_match_uri 'This !http://hobix.com/sample.jpg! is a Textile image link.'
|
171
161
|
end
|
172
162
|
|
173
163
|
it 'should test_textile_link' do
|
174
|
-
|
175
|
-
|
164
|
+
no_match_uri(
|
165
|
+
'This "hobix (hobix)":http://hobix.com/sample.jpg is a Textile link.'
|
166
|
+
)
|
176
167
|
# just to be sure ...
|
177
|
-
|
178
|
-
|
168
|
+
match_uri 'This http://hobix.com/sample.jpg should match',
|
169
|
+
link_text: 'http://hobix.com/sample.jpg'
|
179
170
|
end
|
180
171
|
|
181
172
|
it 'should test_inline_html' do
|
182
|
-
|
183
|
-
|
173
|
+
no_match_uri "<img src='http://hobix.com/sample.jpg'/>"
|
174
|
+
no_match_uri '<IMG SRC="http://hobix.com/sample.jpg">'
|
184
175
|
end
|
185
176
|
|
186
177
|
it 'should test_non_uri' do
|
187
178
|
# "so" is a valid country code; "libproxy.so" is a valid url
|
188
|
-
|
179
|
+
match_uri 'libproxy.so', host: 'libproxy.so',
|
180
|
+
text: 'libproxy.so',
|
181
|
+
link_text: 'http://libproxy.so'
|
189
182
|
|
190
|
-
|
183
|
+
no_match_uri 'httpd.conf'
|
191
184
|
# THIS ONE'S BUSTED.. Ethan fix??
|
192
|
-
#
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
185
|
+
# no_match_uri 'ld.so.conf'
|
186
|
+
no_match_uri 'index.jpeg'
|
187
|
+
no_match_uri 'index.jpg'
|
188
|
+
no_match_uri 'file.txt'
|
189
|
+
no_match_uri 'file.doc'
|
190
|
+
no_match_uri 'file.pdf'
|
191
|
+
no_match_uri 'file.png'
|
192
|
+
no_match_uri 'file.ps'
|
200
193
|
end
|
201
194
|
|
202
195
|
it 'should test_uri_in_text' do
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
196
|
+
match_uri 'Go to: http://www.example.com/',
|
197
|
+
host: 'www.example.com', path: '/'
|
198
|
+
match_uri 'http://www.example.com/ is a link.', host: 'www.example.com'
|
199
|
+
match_uri 'Email david@loudthinking.com',
|
200
|
+
scheme: 'mailto', to: 'david@loudthinking.com', host: nil
|
208
201
|
# check that trailing punctuation is not included in the hostname
|
209
|
-
|
202
|
+
match_uri 'Hey dude, http://fake.link.com.',
|
203
|
+
scheme: 'http', host: 'fake.link.com'
|
210
204
|
# this is a textile link, no match please.
|
211
|
-
|
205
|
+
no_match_uri '"link":http://fake.link.com.'
|
212
206
|
end
|
213
207
|
|
214
208
|
it 'should test_uri_in_parentheses' do
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
209
|
+
match_uri 'URI (http://brackets.com.de) in brackets',
|
210
|
+
host: 'brackets.com.de'
|
211
|
+
match_uri 'because (as shown at research.net) the results',
|
212
|
+
host: 'research.net'
|
213
|
+
match_uri 'A wiki (http://wiki.org/wiki.cgi?WhatIsWiki) card',
|
214
|
+
scheme: 'http', host: 'wiki.org', path: '/wiki.cgi',
|
215
|
+
query: 'WhatIsWiki'
|
221
216
|
end
|
222
217
|
|
223
218
|
it 'should test_uri_list_item' do
|
224
219
|
match_chunk(
|
225
|
-
Card::Chunk::URI,
|
220
|
+
Card::Content::Chunk::URI,
|
226
221
|
'* http://www.btinternet.com/~mail2minh/SonyEricssonP80xPlatform.sis',
|
227
222
|
path: '/~mail2minh/SonyEricssonP80xPlatform.sis'
|
228
223
|
)
|
229
224
|
end
|
230
225
|
|
231
226
|
it 'should test_interesting_uri_with__comma' do
|
232
|
-
# Counter-intuitively, this URL matches, but the query part includes the
|
227
|
+
# Counter-intuitively, this URL matches, but the query part includes the
|
228
|
+
# trailing comma.
|
233
229
|
# It has no way to know that the query does not include the comma.
|
234
230
|
# The trailing , addition breaks this test, but is this test actually valid?
|
235
231
|
# It seems better to exclude the comma from the uri, YMMV
|
236
|
-
|
237
|
-
|
238
|
-
"
|
239
|
-
scheme: 'http', host: 'someplace.org', port: 8080,
|
240
|
-
query: 'arg=val')
|
232
|
+
match_uri(
|
233
|
+
'This text contains a URL http://someplace.org:8080/~person/stuff.cgi' \
|
234
|
+
"?arg=val, doesn't it?",
|
235
|
+
scheme: 'http', host: 'someplace.org', port: 8080,
|
236
|
+
path: '/~person/stuff.cgi', query: 'arg=val')
|
241
237
|
end
|
242
238
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
port: 2500, query: 'WhatIsWiki')
|
259
|
-
end
|
260
|
-
end
|
239
|
+
describe Card::Content::Chunk::URI, 'URI chunk tests' do
|
240
|
+
it 'should test_local_urls' do
|
241
|
+
# normal
|
242
|
+
match_http_uri 'http://perforce:8001/toto.html',
|
243
|
+
host: 'perforce', port: 8001
|
244
|
+
# in parentheses
|
245
|
+
match_uri 'URI (http://localhost:2500) in brackets',
|
246
|
+
host: 'localhost', port: 2500
|
247
|
+
match_uri 'because (as shown at http://perforce:8001) the results',
|
248
|
+
host: 'perforce', port: 8001
|
249
|
+
match_uri 'A wiki (http://localhost:2500/wiki.cgi?WhatIsWiki) card',
|
250
|
+
scheme: 'http', host: 'localhost', path: '/wiki.cgi',
|
251
|
+
port: 2500, query: 'WhatIsWiki'
|
252
|
+
end
|
253
|
+
end
|
261
254
|
|
262
255
|
private
|
263
256
|
|
@@ -265,19 +258,11 @@ describe Card::Chunk::URI, 'URI chunk tests' do
|
|
265
258
|
|
266
259
|
# Asserts a number of tests for the given type and text.
|
267
260
|
def no_match type, test_text
|
268
|
-
|
269
|
-
expect(((test_cont.respond_to? :each) ? test_cont : [test_cont]).find { |ck| type === ck }).to be_nil
|
270
|
-
end
|
271
|
-
|
272
|
-
def aa_match type, test_text
|
273
|
-
test_cont = Card::Content.new(test_text, DUMMY_CARD)
|
274
|
-
expect(((test_cont.respond_to? :each) ? test_cont : [test_cont]).find { |ck| type === ck }).not_to be_nil
|
261
|
+
expect(get_chunk(type, test_text)).to be_nil
|
275
262
|
end
|
276
263
|
|
277
264
|
def match_chunk type, test_text, expected
|
278
|
-
|
279
|
-
chunk = ((test_cont.respond_to? :each) ? test_cont : [test_cont]).find { |ck| type === ck }
|
280
|
-
# warn "chunk? #{chunk.inspect}"
|
265
|
+
chunk = get_chunk(type, test_text)
|
281
266
|
expect(chunk).not_to be_nil
|
282
267
|
|
283
268
|
expected.each_pair do |method_sym, value|
|
@@ -287,4 +272,22 @@ describe Card::Chunk::URI, 'URI chunk tests' do
|
|
287
272
|
assert_equal(value, cvalue, "Checking value of '#{method_sym}'")
|
288
273
|
end
|
289
274
|
end
|
275
|
+
|
276
|
+
def match_uri uri, opts
|
277
|
+
match_chunk Card::Content::Chunk::URI, uri, opts
|
278
|
+
end
|
279
|
+
|
280
|
+
def no_match_uri text
|
281
|
+
no_match Card::Content::Chunk::URI, text
|
282
|
+
end
|
283
|
+
|
284
|
+
def match_http_uri uri, opts
|
285
|
+
match_uri uri, opts.reverse_merge(link_text: uri, scheme: 'http')
|
286
|
+
end
|
287
|
+
|
288
|
+
def get_chunk type, test_text
|
289
|
+
cont = Card::Content.new(test_text, DUMMY_CARD)
|
290
|
+
cont = [cont] unless cont.respond_to?(:each)
|
291
|
+
cont.find { |ck| ck.is_a? type }
|
292
|
+
end
|
290
293
|
end
|