card 1.16.14 → 1.16.15
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/db/migrate_core_cards/20150903130006_attachment_upload_cards.rb +4 -2
- data/lib/card/auth.rb +15 -10
- data/lib/card/codename.rb +25 -21
- data/lib/card/content.rb +100 -68
- data/lib/card/format.rb +158 -129
- data/lib/card/query.rb +15 -9
- data/lib/card/query/attributes.rb +41 -49
- data/lib/card/set.rb +15 -12
- data/lib/card/set_pattern.rb +4 -5
- data/lib/card/spec_helper.rb +54 -16
- data/lib/cardio.rb +43 -25
- data/mod/01_core/chunk/include.rb +1 -1
- data/mod/01_core/set/all/collection.rb +76 -73
- data/mod/01_core/set/all/content.rb +0 -4
- data/mod/01_core/set/all/fetch.rb +35 -42
- data/mod/01_core/set/all/name.rb +17 -7
- data/mod/01_core/set/all/pattern.rb +12 -11
- data/mod/01_core/set/all/permissions.rb +51 -42
- data/mod/01_core/set/all/phases.rb +2 -1
- data/mod/01_core/set/all/references.rb +2 -2
- data/mod/01_core/set/all/rules.rb +28 -35
- data/mod/01_core/set/all/subcards.rb +12 -12
- data/mod/01_core/set/all/tracked_attributes.rb +1 -1
- data/mod/01_core/set/all/type.rb +11 -11
- data/mod/01_core/set/all/utils.rb +6 -1
- data/mod/01_core/spec/set/all/fetch_spec.rb +6 -6
- data/mod/01_core/spec/set/all/permissions_spec.rb +11 -11
- data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +1 -1
- data/mod/01_history/lib/card/action.rb +52 -47
- data/mod/01_history/set/all/actions.rb +20 -16
- data/mod/01_history/set/all/history.rb +18 -13
- data/mod/02_basic_types/set/all/base.rb +23 -2
- data/mod/02_basic_types/set/type/pointer.rb +45 -36
- data/mod/02_basic_types/spec/set/all/base_spec.rb +40 -24
- data/mod/02_basic_types/spec/set/type/pointer_spec.rb +87 -0
- data/mod/03_machines/set/right/machine_output.rb +10 -6
- data/mod/04_settings/set/abstract/permission.rb +10 -5
- data/mod/04_settings/set/type/setting.rb +4 -1
- data/mod/05_email/set/all/follow.rb +39 -44
- data/mod/05_email/set/all/notify.rb +4 -1
- data/mod/05_email/set/right/followers.rb +16 -14
- data/mod/05_email/set/self/follow_defaults.rb +22 -19
- data/mod/05_standard/lib/carrier_wave/cardmount.rb +1 -0
- data/mod/05_standard/set/abstract/attachment.rb +85 -58
- data/mod/05_standard/set/all/comment.rb +35 -19
- data/mod/05_standard/set/all/error.rb +124 -98
- data/mod/05_standard/set/all/list_changes.rb +27 -22
- data/mod/05_standard/set/all/rich_html/editing.rb +96 -70
- data/mod/05_standard/set/all/rich_html/form.rb +123 -81
- data/mod/05_standard/set/all/rich_html/modal.rb +15 -58
- data/mod/05_standard/set/right/account.rb +2 -2
- data/mod/05_standard/set/right/email.rb +3 -2
- data/mod/05_standard/set/rstar/rules.rb +3 -3
- data/mod/05_standard/set/self/search.rb +45 -22
- data/mod/05_standard/set/type/cardtype.rb +13 -11
- data/mod/05_standard/set/type/listed_by.rb +3 -2
- data/mod/05_standard/set/type/set.rb +17 -13
- data/mod/05_standard/set/type/signup.rb +1 -2
- data/mod/05_standard/set/type/user.rb +1 -1
- data/mod/05_standard/spec/set/all/account_spec.rb +1 -1
- data/mod/05_standard/spec/set/all/history_spec.rb +1 -1
- data/mod/05_standard/spec/set/type/email_template_spec.rb +140 -134
- data/mod/05_standard/spec/set/type/image_spec.rb +2 -1
- data/mod/05_standard/spec/set/type/signup_spec.rb +2 -2
- data/spec/models/card/trash_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- metadata +2 -2
data/lib/card/query.rb
CHANGED
@@ -57,41 +57,47 @@ class Card
|
|
57
57
|
conjunction: %w( and or all any ),
|
58
58
|
special: %w( found_by not sort match complete extension_type ),
|
59
59
|
ignore: %w( prepend append view params vars size )
|
60
|
-
}.inject({}) {|h,pair| pair[1].each { |v| h[v.to_sym]=pair[0] }; h }
|
60
|
+
}.inject({}) { |h, pair| pair[1].each { |v| h[v.to_sym] = pair[0] }; h }
|
61
61
|
|
62
62
|
CONJUNCTIONS = { any: :or, in: :or, or: :or, all: :and, and: :and }
|
63
63
|
|
64
64
|
MODIFIERS = %w( conj return sort sort_as group dir limit offset )
|
65
|
-
|
65
|
+
.inject({}) { |h,v| h[v.to_sym] = nil; h }
|
66
66
|
|
67
67
|
OPERATORS = %w( != = =~ < > in ~ ).inject({}) {|h,v| h[v]=v; h }.merge({
|
68
|
-
eq: '=', gt: '>', lt: '<', match: '~', ne: '!=',
|
68
|
+
eq: '=', gt: '>', lt: '<', match: '~', ne: '!=', 'not in' => nil
|
69
69
|
}.stringify_keys)
|
70
70
|
|
71
71
|
DEFAULT_ORDER_DIRS = { :update => "desc", :relevance => "desc" }
|
72
72
|
|
73
73
|
attr_reader :statement, :mods, :conditions, :comment,
|
74
|
-
|
74
|
+
:subqueries, :superquery
|
75
75
|
attr_accessor :joins, :table_seq, :unjoined, :conditions_on_join
|
76
76
|
|
77
77
|
def initialize statement, comment=nil
|
78
|
-
@comment = comment
|
79
78
|
@subqueries = []
|
80
79
|
@conditions = []
|
81
80
|
@joins = []
|
82
81
|
@mods = {}
|
83
82
|
@statement = statement.clone
|
84
83
|
|
85
|
-
@
|
86
|
-
@
|
84
|
+
@context = @statement.delete(:context) || nil
|
85
|
+
@unjoined = @statement.delete(:unjoined) || nil
|
87
86
|
@superquery = @statement.delete(:superquery) || nil
|
88
|
-
@vars = @statement.delete(:vars
|
87
|
+
@vars = @statement.delete(:vars) || {}
|
89
88
|
@vars.symbolize_keys!
|
90
89
|
|
90
|
+
@comment = comment || default_comment
|
91
|
+
|
91
92
|
interpret @statement
|
92
93
|
self
|
93
94
|
end
|
94
95
|
|
96
|
+
def default_comment
|
97
|
+
return if @superquery || !Card.config.sql_comments
|
98
|
+
statement.to_s
|
99
|
+
end
|
100
|
+
|
95
101
|
# Query Execution
|
96
102
|
# By default a query returns card objects. This is accomplished by returning
|
97
103
|
# a card identifier from SQL and then hooking into our caching system (see
|
@@ -185,7 +191,7 @@ class Card
|
|
185
191
|
def normalize_value val
|
186
192
|
case val
|
187
193
|
when Integer, Float, Symbol, Hash then val
|
188
|
-
when String,
|
194
|
+
when String, SmartName then normalize_string_value val
|
189
195
|
when Array then val.map { |v| normalize_value v }
|
190
196
|
else fail BadQuery, "unknown WQL value type: #{val.class}"
|
191
197
|
end
|
@@ -26,12 +26,12 @@ class Card
|
|
26
26
|
def editor_of val
|
27
27
|
act_join = Join.new(
|
28
28
|
from: self,
|
29
|
-
to: ['card_acts', "a#{table_id
|
29
|
+
to: ['card_acts', "a#{table_id true}", 'actor_id']
|
30
30
|
)
|
31
31
|
joins << act_join
|
32
32
|
action_join = Join.new(
|
33
33
|
from: act_join,
|
34
|
-
to: ['card_actions', "an#{table_id
|
34
|
+
to: ['card_actions', "an#{table_id true}", 'card_act_id'],
|
35
35
|
superjoin: act_join
|
36
36
|
)
|
37
37
|
join_cards val, from: action_join, from_field: 'card_id'
|
@@ -40,13 +40,13 @@ class Card
|
|
40
40
|
def edited_by val
|
41
41
|
action_join = Join.new(
|
42
42
|
from: self,
|
43
|
-
to: ['card_actions', "an#{table_id
|
43
|
+
to: ['card_actions', "an#{table_id true}", 'card_id']
|
44
44
|
)
|
45
45
|
joins << action_join
|
46
46
|
act_join = Join.new(
|
47
47
|
from: action_join,
|
48
48
|
from_field: 'card_act_id',
|
49
|
-
to: ['card_acts', "a#{table_id
|
49
|
+
to: ['card_acts', "a#{table_id true}"]
|
50
50
|
)
|
51
51
|
join_cards val, from: act_join, from_field: 'actor_id'
|
52
52
|
end
|
@@ -100,72 +100,68 @@ class Card
|
|
100
100
|
def found_by val
|
101
101
|
found_by_cards(val).compact.each do |c|
|
102
102
|
if c && [SearchTypeID, SetID].include?(c.type_id)
|
103
|
-
#FIXME - move this check to set mods!
|
103
|
+
# FIXME: - move this check to set mods!
|
104
104
|
|
105
105
|
subquery(
|
106
106
|
c.get_query.merge unjoined: true, context: c.name
|
107
107
|
)
|
108
108
|
else
|
109
109
|
raise BadQuery,
|
110
|
-
|
111
|
-
|
110
|
+
'"found_by" value must be valid Search, ' \
|
111
|
+
"but #{c.name} is a #{c.type_name}"
|
112
112
|
end
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
|
117
116
|
def found_by_cards val
|
118
|
-
if Hash
|
117
|
+
if val.is_a? Hash
|
119
118
|
Query.run val
|
120
119
|
else
|
121
120
|
Array.wrap(val).map do |v|
|
122
|
-
Card.fetch
|
121
|
+
Card.fetch v.to_name.to_absolute(context), new: {}
|
123
122
|
end
|
124
123
|
end
|
125
|
-
|
126
124
|
end
|
127
125
|
|
128
|
-
def match
|
126
|
+
def match val
|
129
127
|
cxn, val = match_prep val
|
130
128
|
val.gsub! /[^#{Card::Name::OK4KEY_RE}]+/, ' '
|
131
129
|
return nil if val.strip.empty?
|
132
130
|
|
133
131
|
val_list = val.split(/\s+/).map do |v|
|
134
132
|
name_or_content = [
|
135
|
-
"replace(#{
|
136
|
-
"#{
|
133
|
+
"replace(#{table_alias}.name,'+',' ')",
|
134
|
+
"#{table_alias}.db_content"
|
137
135
|
].map do |field|
|
138
|
-
%{#{field} #{
|
136
|
+
%{#{field} #{cxn.match quote("[[:<:]]#{v}[[:>:]]")}}
|
139
137
|
end
|
140
138
|
"(#{name_or_content.join ' OR '})"
|
141
139
|
end
|
142
140
|
add_condition "(#{val_list.join ' AND '})"
|
143
141
|
end
|
144
142
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
# FIXME -- this should really be more nuanced --
|
143
|
+
def complete val
|
144
|
+
no_plus_card = (val =~ /\+/ ? '' : 'and right_id is null')
|
145
|
+
# FIXME: -- this should really be more nuanced --
|
149
146
|
# it breaks down after one plus
|
150
147
|
|
151
148
|
add_condition(
|
152
|
-
" lower(
|
149
|
+
" lower(#{table_alias}.name) LIKE" \
|
150
|
+
" lower(#{quote(val.to_s + '%')}) #{no_plus_card}"
|
153
151
|
)
|
154
152
|
end
|
155
153
|
|
156
|
-
def extension_type
|
154
|
+
def extension_type _val
|
157
155
|
# DEPRECATED LONG AGO!!!
|
158
|
-
Rails.logger.info
|
159
|
-
interpret :
|
156
|
+
Rails.logger.info 'using DEPRECATED extension_type in WQL'
|
157
|
+
interpret right_plus: AccountID
|
160
158
|
end
|
161
159
|
|
162
|
-
|
163
160
|
# ATTRIBUTE HELPERS
|
164
161
|
|
165
|
-
|
166
162
|
def join_references key, val
|
167
|
-
r = Reference.new(
|
168
|
-
refjoin = Join.new(:
|
163
|
+
r = Reference.new(key, val, self)
|
164
|
+
refjoin = Join.new(from: self, to: r, to_field: r.infield)
|
169
165
|
joins << refjoin
|
170
166
|
if r.cardquery
|
171
167
|
join_cards r.cardquery, from: refjoin, from_field: r.outfield
|
@@ -188,37 +184,35 @@ class Card
|
|
188
184
|
if sort_field == 'count'
|
189
185
|
sort_by_count val, item
|
190
186
|
else
|
191
|
-
if join_field = SORT_JOIN_TO_ITEM_MAP[item.to_sym]
|
192
|
-
sq = join_cards
|
193
|
-
|
194
|
-
|
195
|
-
conditions_on_join: true
|
187
|
+
if (join_field = SORT_JOIN_TO_ITEM_MAP[item.to_sym])
|
188
|
+
sq = join_cards(val, to_field: join_field,
|
189
|
+
side: 'LEFT',
|
190
|
+
conditions_on_join: true)
|
196
191
|
@mods[:sort] ||= "#{sq.table_alias}.#{sort_field}"
|
197
192
|
else
|
198
193
|
raise BadQuery, "sort item: #{item} not yet implemented"
|
199
194
|
end
|
200
195
|
end
|
201
|
-
|
202
196
|
end
|
203
197
|
|
204
198
|
# EXPERIMENTAL!
|
205
199
|
def sort_by_count val, item
|
206
200
|
if item == 'referred_to'
|
207
|
-
@mods[:sort] =
|
201
|
+
@mods[:sort] = 'coalesce(count,0)' # needed for postgres
|
208
202
|
cs = Query.new(
|
209
|
-
:
|
210
|
-
:
|
211
|
-
:
|
203
|
+
return: 'coalesce(count(*), 0) as count',
|
204
|
+
group: 'sort_join_field',
|
205
|
+
superquery: self
|
212
206
|
)
|
213
207
|
subselect = Query.new(val.merge return: 'id', superquery: self)
|
214
208
|
cs.add_condition "referer_id in (#{subselect.sql})"
|
215
|
-
# FIXME - SQL generated before SQL phase
|
209
|
+
# FIXME: - SQL generated before SQL phase
|
216
210
|
cs.joins << Join.new(
|
217
211
|
from: cs,
|
218
|
-
to:['card_references', 'wr', 'referee_id']
|
212
|
+
to: ['card_references', 'wr', 'referee_id']
|
219
213
|
)
|
220
214
|
cs.mods[:sort_join_field] = "#{cs.table_alias}.id as sort_join_field"
|
221
|
-
#HACK!
|
215
|
+
# HACK!
|
222
216
|
|
223
217
|
joins << Join.new(
|
224
218
|
from: self,
|
@@ -261,8 +255,7 @@ class Card
|
|
261
255
|
s
|
262
256
|
end
|
263
257
|
|
264
|
-
|
265
|
-
#~~~~~~~ CONJUNCTION
|
258
|
+
# ~~~~~~~ CONJUNCTION
|
266
259
|
|
267
260
|
def all val
|
268
261
|
conjoin val, :and
|
@@ -276,8 +269,8 @@ class Card
|
|
276
269
|
alias_method :in, :any
|
277
270
|
|
278
271
|
def conjoin val, conj
|
279
|
-
sq = subquery
|
280
|
-
unless Array
|
272
|
+
sq = subquery unjoined: true, conj: conj
|
273
|
+
unless val.is_a? Array
|
281
274
|
val = clause_to_hash(val).map { |key, value| { key => value } }
|
282
275
|
end
|
283
276
|
val.each do |val_item|
|
@@ -291,7 +284,7 @@ class Card
|
|
291
284
|
end
|
292
285
|
|
293
286
|
def restrict id_field, val
|
294
|
-
if id = id_from_val(val)
|
287
|
+
if (id = id_from_val(val))
|
295
288
|
interpret id_field => id
|
296
289
|
else
|
297
290
|
join_cards val, from_field: id_field
|
@@ -300,11 +293,10 @@ class Card
|
|
300
293
|
|
301
294
|
def id_from_val val
|
302
295
|
case val
|
303
|
-
when Integer
|
304
|
-
when String
|
296
|
+
when Integer then val
|
297
|
+
when String then Card.fetch_id(val)
|
305
298
|
end
|
306
299
|
end
|
307
|
-
|
308
300
|
end
|
309
301
|
end
|
310
|
-
end
|
302
|
+
end
|
data/lib/card/set.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
3
|
class Card
|
4
|
-
# remove_const :Set if const_defined?(:Set, false)
|
5
4
|
|
6
5
|
module Set
|
7
6
|
mattr_accessor :modules, :traits
|
@@ -101,16 +100,16 @@ class Card
|
|
101
100
|
else
|
102
101
|
alias_block view, args
|
103
102
|
end
|
104
|
-
define_method "_view_#{
|
103
|
+
define_method "_view_#{view}", view_block
|
105
104
|
end
|
106
105
|
|
107
106
|
def alias_block view, args
|
108
107
|
opts = args[0].is_a?(Hash) ? args.shift : { view: args.shift }
|
109
|
-
opts[:mod]
|
108
|
+
opts[:mod] ||= self
|
110
109
|
opts[:view] ||= view
|
111
110
|
views[opts[:mod]][opts[:view]] || fail
|
112
111
|
rescue
|
113
|
-
raise "cannot find #{
|
112
|
+
raise "cannot find #{opts[:view]} view in #{opts[:mod]}; " \
|
114
113
|
"failed to alias #{view} in #{self}"
|
115
114
|
end
|
116
115
|
end
|
@@ -119,8 +118,8 @@ class Card
|
|
119
118
|
if format_names.empty?
|
120
119
|
format_names = [:base]
|
121
120
|
elsif format_names.first == :all
|
122
|
-
format_names =
|
123
|
-
.reject { |f| Card::Format.aliases[f] }
|
121
|
+
format_names =
|
122
|
+
Card::Format.registered.reject { |f| Card::Format.aliases[f] }
|
124
123
|
end
|
125
124
|
format_names.each do |f|
|
126
125
|
define_on_format f, &block
|
@@ -215,7 +214,6 @@ class Card
|
|
215
214
|
def define_event_method event, call_method, _opts
|
216
215
|
class_eval do
|
217
216
|
define_method event do
|
218
|
-
# Rails.logger.rspec event
|
219
217
|
run_callbacks event do
|
220
218
|
send call_method
|
221
219
|
end
|
@@ -229,7 +227,8 @@ class Card
|
|
229
227
|
# (when the job is executed ActiveJob fetches the card from the database so
|
230
228
|
# all attributes get lost)
|
231
229
|
# @param name [String] the name for the ActiveJob child class
|
232
|
-
# @param final_method [String] the name of the card instance method to be
|
230
|
+
# @param final_method [String] the name of the card instance method to be
|
231
|
+
# queued
|
233
232
|
# @option queue [Symbol] (:default) the name of the queue
|
234
233
|
def define_active_job name, final_method, queue=:default
|
235
234
|
class_name = name.to_s.camelize
|
@@ -240,12 +239,13 @@ class Card
|
|
240
239
|
}
|
241
240
|
Object.const_get(class_name).class_eval do
|
242
241
|
define_method :perform, proc { |card, attributes|
|
243
|
-
attributes.each do |
|
242
|
+
attributes.each do |attname, args|
|
244
243
|
# symbols are not allowed so all symbols arrive here as strings
|
245
244
|
# convert strings that were symbols before back to symbols
|
246
245
|
value = args[:symbol] ? args[:value].to_sym : args[:value]
|
247
|
-
card.instance_variable_set("@#{
|
246
|
+
card.instance_variable_set("@#{attname}", value)
|
248
247
|
end
|
248
|
+
card.include_set_modules
|
249
249
|
card.send final_method
|
250
250
|
}
|
251
251
|
end
|
@@ -480,8 +480,11 @@ EOF
|
|
480
480
|
|
481
481
|
def attachment name, args
|
482
482
|
include Abstract::Attachment
|
483
|
-
set_specific_attributes name,
|
484
|
-
|
483
|
+
set_specific_attributes name,
|
484
|
+
:load_from_mod,
|
485
|
+
:action_id_of_cached_upload,
|
486
|
+
:empty_ok,
|
487
|
+
"remote_#{name}_url".to_sym
|
485
488
|
uploader_class = args[:uploader] || FileUploader
|
486
489
|
mount_uploader name, uploader_class
|
487
490
|
end
|
data/lib/card/set_pattern.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
class Card
|
2
|
-
|
3
2
|
class SetPattern
|
4
|
-
|
5
3
|
class << self
|
6
|
-
attr_accessor :pattern_code, :pattern_id, :junction_only, :assigns_type,
|
4
|
+
attr_accessor :pattern_code, :pattern_id, :junction_only, :assigns_type,
|
5
|
+
:anchorless, :anchor_parts_count
|
7
6
|
|
8
7
|
def card_keys
|
9
8
|
@@card_keys ||= Card.set_patterns.inject({}) do |hash, set_pattern|
|
10
|
-
card_key = Card.
|
11
|
-
hash[
|
9
|
+
card_key = Card.quick_fetch(set_pattern.pattern_code.to_sym).key
|
10
|
+
hash[card_key] = true
|
12
11
|
hash
|
13
12
|
end
|
14
13
|
end
|
data/lib/card/spec_helper.rb
CHANGED
@@ -1,26 +1,23 @@
|
|
1
1
|
module SpecHelper
|
2
2
|
end
|
3
3
|
module Card::SpecHelper
|
4
|
-
|
5
4
|
include Rails::Dom::Testing::Assertions::SelectorAssertions
|
6
|
-
|
5
|
+
# ~~~~~~~~~ HELPER METHODS ~~~~~~~~~~~~~~~#
|
7
6
|
|
8
7
|
def login_as user
|
9
|
-
Card::Auth.current_id = (uc=Card[user.to_s]
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
#warn "(ath)login_as #{user.inspect}, #{Card::Auth.current_id}, #{@request.session[:user]}"
|
8
|
+
Card::Auth.current_id = (uc = Card[user.to_s]) && uc.id
|
9
|
+
return unless @request
|
10
|
+
@request.session[:user] = Card::Auth.current_id
|
11
|
+
# warn "(ath)login_as #{user.inspect}, #{Card::Auth.current_id}, #{@request.session[:user]}"
|
14
12
|
end
|
15
13
|
|
16
|
-
def newcard name, content=
|
14
|
+
def newcard name, content=''
|
17
15
|
#FIXME - misleading name; sounds like it doesn't save.
|
18
16
|
Card.create! name: name, content: content
|
19
17
|
end
|
20
18
|
|
21
|
-
def assert_view_select
|
19
|
+
def assert_view_select view_html, *args, &block
|
22
20
|
node = Nokogiri::HTML::Document.parse(view_html).root
|
23
|
-
#node = HTML::Document.new(view_html).root
|
24
21
|
if block_given?
|
25
22
|
assert_select node, *args, &block
|
26
23
|
else
|
@@ -28,9 +25,9 @@ module Card::SpecHelper
|
|
28
25
|
end
|
29
26
|
end
|
30
27
|
|
31
|
-
def debug_assert_view_select
|
28
|
+
def debug_assert_view_select view_html, *args, &block
|
32
29
|
Rails.logger.rspec %(
|
33
|
-
#{CodeRay.scan(Nokogiri::XML(view_html
|
30
|
+
#{CodeRay.scan(Nokogiri::XML(view_html, &:noblanks).to_s, :html).div}
|
34
31
|
<style>
|
35
32
|
.CodeRay {
|
36
33
|
background-color: #FFF;
|
@@ -43,17 +40,17 @@ module Card::SpecHelper
|
|
43
40
|
assert_view_select view_html, *args, &block
|
44
41
|
end
|
45
42
|
|
46
|
-
def render_editor
|
43
|
+
def render_editor type
|
47
44
|
card = Card.create(name: "my favority #{type} + #{rand(4)}", type: type)
|
48
45
|
card.format.render(:edit)
|
49
46
|
end
|
50
47
|
|
51
48
|
def render_content content, format_args={}
|
52
|
-
render_content_with_args
|
49
|
+
render_content_with_args content, format_args
|
53
50
|
end
|
54
51
|
|
55
52
|
def render_content_with_args content, format_args={}, view_args={}
|
56
|
-
@card ||= Card.new name:
|
53
|
+
@card ||= Card.new name: 'Tempo Rary 2'
|
57
54
|
@card.content = content
|
58
55
|
@card.format(format_args)._render :core, view_args
|
59
56
|
end
|
@@ -67,7 +64,7 @@ module Card::SpecHelper
|
|
67
64
|
if card_args[:name]
|
68
65
|
Card.fetch card_args[:name], new: card_args
|
69
66
|
else
|
70
|
-
Card.new card_args.merge(
|
67
|
+
Card.new card_args.merge(name: 'Tempo Rary')
|
71
68
|
end
|
72
69
|
end
|
73
70
|
card.format(format_args)._render(view, view_args)
|
@@ -76,4 +73,45 @@ module Card::SpecHelper
|
|
76
73
|
def users
|
77
74
|
SharedData::USERS.sort
|
78
75
|
end
|
76
|
+
|
77
|
+
# Make expectations in the event phase.
|
78
|
+
# Takes the usual event options :on and :before/:after/:around
|
79
|
+
# and registers the event_block with these options as an event.
|
80
|
+
# Unknown methods in the event_block are executed in the rspec context
|
81
|
+
# instead of the card's context.
|
82
|
+
# An additionaly :trigger block in opts is expected that is called
|
83
|
+
# to start the event phase.
|
84
|
+
# Example:
|
85
|
+
# in_phase before: :approve, on: :save,
|
86
|
+
# trigger: ->{ test_card.update_attributes! content: '' } do
|
87
|
+
# expect(item_names).to eq []
|
88
|
+
# end
|
89
|
+
def in_phase opts, &event_block
|
90
|
+
$rspec_binding = binding
|
91
|
+
Card.class_eval do
|
92
|
+
def method_missing m, *args
|
93
|
+
begin
|
94
|
+
method = eval('method(%s)' % m.inspect, $rspec_binding)
|
95
|
+
rescue NameError
|
96
|
+
else
|
97
|
+
return method.call(*args)
|
98
|
+
end
|
99
|
+
begin
|
100
|
+
value = eval(m.to_s, $rspec_binding)
|
101
|
+
return value
|
102
|
+
rescue NameError
|
103
|
+
end
|
104
|
+
super
|
105
|
+
# raise NoMethodError
|
106
|
+
end
|
107
|
+
define_method :in_phase_test, event_block
|
108
|
+
end
|
109
|
+
Card.define_callbacks :in_phase_test
|
110
|
+
kind = ([:before, :after, :around] & opts.keys).first
|
111
|
+
name = opts.delete(kind)
|
112
|
+
Card.set_callback name, kind, :in_phase_test, prepend: true
|
113
|
+
opts[:trigger].call
|
114
|
+
ensure
|
115
|
+
Card.skip_callback name, kind, :in_phase_test
|
116
|
+
end
|
79
117
|
end
|