card 1.18.0 → 1.18.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.
- 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
|