card 1.18.0 → 1.18.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +20 -16
  4. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
  5. data/db/schema.rb +110 -92
  6. data/lib/card.rb +1 -0
  7. data/lib/card/content.rb +4 -73
  8. data/lib/card/content/chunk.rb +119 -0
  9. data/lib/card/content/parser.rb +75 -0
  10. data/lib/card/diff.rb +25 -398
  11. data/lib/card/diff/lcs.rb +247 -0
  12. data/lib/card/diff/result.rb +131 -0
  13. data/lib/card/director_register.rb +5 -0
  14. data/lib/card/query/attributes.rb +19 -13
  15. data/lib/card/set/event.rb +2 -1
  16. data/lib/card/set_pattern.rb +4 -2
  17. data/lib/card/spec_helper.rb +7 -1
  18. data/lib/card/stage_director.rb +33 -5
  19. data/lib/card/subcards.rb +11 -3
  20. data/lib/card/subdirector_array.rb +14 -1
  21. data/lib/cardio.rb +8 -5
  22. data/mod/01_core/chunk/include.rb +2 -2
  23. data/mod/01_core/chunk/link.rb +3 -3
  24. data/mod/01_core/chunk/literal.rb +20 -14
  25. data/mod/01_core/chunk/query_reference.rb +2 -2
  26. data/mod/01_core/chunk/reference.rb +47 -38
  27. data/mod/01_core/chunk/uri.rb +17 -13
  28. data/mod/01_core/format/html_format.rb +0 -2
  29. data/mod/01_core/set/all/actify.rb +12 -1
  30. data/mod/01_core/set/all/collection.rb +4 -4
  31. data/mod/01_core/set/all/fetch.rb +0 -27
  32. data/mod/01_core/set/all/name.rb +33 -12
  33. data/mod/01_core/set/all/pattern.rb +2 -6
  34. data/mod/01_core/set/all/phases.rb +0 -1
  35. data/mod/01_core/set/all/references.rb +2 -2
  36. data/mod/01_core/set/all/rules.rb +10 -3
  37. data/mod/01_core/set/all/tracked_attributes.rb +0 -1
  38. data/mod/01_core/set/all/type.rb +0 -14
  39. data/mod/01_core/spec/chunk/literal_spec.rb +1 -1
  40. data/mod/01_core/spec/chunk/uri_spec.rb +204 -201
  41. data/mod/01_core/spec/set/all/type_spec.rb +3 -1
  42. data/mod/01_history/lib/card/action.rb +7 -9
  43. data/mod/01_history/set/all/history.rb +6 -1
  44. data/mod/02_basic_types/set/all/all_csv.rb +1 -1
  45. data/mod/02_basic_types/set/type/pointer.rb +20 -9
  46. data/mod/03_machines/lib/javascript/wagn.js.coffee +1 -1
  47. data/mod/04_settings/set/right/structure.rb +7 -1
  48. data/mod/05_email/set/right/follow.rb +22 -22
  49. data/mod/05_email/set/type_plus_right/user/follow.rb +25 -26
  50. data/mod/05_standard/set/all/rich_html/wrapper.rb +12 -6
  51. data/mod/05_standard/set/rstar/rules_editor.rb +6 -4
  52. data/mod/05_standard/set/self/all.rb +0 -10
  53. data/mod/05_standard/set/self/stats.rb +6 -15
  54. data/mod/05_standard/set/type/set.rb +0 -6
  55. data/mod/05_standard/spec/chunk/include_spec.rb +2 -2
  56. data/mod/05_standard/spec/chunk/link_spec.rb +1 -1
  57. data/mod/05_standard/spec/chunk/query_reference_spec.rb +5 -4
  58. data/spec/lib/card/chunk_spec.rb +7 -5
  59. data/spec/lib/card/content_spec.rb +11 -11
  60. data/spec/lib/card/diff_spec.rb +4 -4
  61. data/spec/lib/card/stage_director_spec.rb +56 -0
  62. data/spec/lib/card/subcards_spec.rb +0 -1
  63. data/spec/models/card/type_transition_spec.rb +5 -42
  64. metadata +12 -23
  65. data/lib/card/chunk.rb +0 -122
@@ -1,6 +1,6 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
- describe Card::Chunk::Link do
3
+ describe Card::Content::Chunk::Link do
4
4
  def assert_link target, args
5
5
  text = args.delete(:text)
6
6
  format_args = args.delete(:format_args)
@@ -1,14 +1,14 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
- describe Card::Chunk::QueryReference, 'QueryReference' do
3
+ describe Card::Content::Chunk::QueryReference, 'QueryReference' do
4
4
  context 'syntax parsing' do
5
5
  before do
6
- @class = Card::Chunk::QueryReference
6
+ @class = Card::Content::Chunk::QueryReference
7
7
  end
8
8
 
9
9
  let :query_refs do
10
10
  content = Card::Content.new @content, Card.new(type: 'Search')
11
- content.find_chunks(Card::Chunk::QueryReference)
11
+ content.find_chunks(Card::Content::Chunk::QueryReference)
12
12
  end
13
13
 
14
14
  subject { query_refs.first.name }
@@ -34,7 +34,8 @@ describe Card::Chunk::QueryReference, 'QueryReference' do
34
34
  end
35
35
 
36
36
  it 'handles nested query structures' do
37
- @content = '{"any":{"content":"Where", "right_plus":["is",{"name":"Waldo"}]}}'
37
+ @content = '{"any":{"content":"Where", ' \
38
+ '"right_plus":["is",{"name":"Waldo"}]}}'
38
39
  expect(query_refs[0].name).to eq 'Where'
39
40
  expect(query_refs[1].name).to eq 'is'
40
41
  expect(query_refs[2].name).to eq 'Waldo'
@@ -1,15 +1,17 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'card/chunk'
2
+ require 'card/content/chunk'
3
3
 
4
- describe Card::Chunk, 'Chunk' do
4
+ describe Card::Content::Chunk, 'Chunk' do
5
5
  context 'Class' do
6
6
  it 'should populate prefix map on load' do
7
- expect(Card::Chunk.prefix_map.keys.size).to be > 0
8
- expect(Card::Chunk.prefix_map['{'][:class]).to eq(Card::Chunk::Include)
7
+ expect(Card::Content::Chunk.prefix_map.keys.size).to be > 0
8
+ expect(Card::Content::Chunk.prefix_map['{'][:class])
9
+ .to eq(Card::Content::Chunk::Include)
9
10
  end
10
11
 
11
12
  it 'should find Chunk classes using matched prefix' do
12
- expect(Card::Chunk.find_class_by_prefix('{{')).to eq(Card::Chunk::Include)
13
+ expect(Card::Content::Chunk.find_class_by_prefix('{{'))
14
+ .to eq(Card::Content::Chunk::Include)
13
15
  end
14
16
  end
15
17
  end
@@ -184,7 +184,7 @@ EXAMPLES = {
184
184
  EXAMPLES.each_value do |val|
185
185
  next unless val[:classes]
186
186
  val[:classes] = val[:classes].map do |klass|
187
- Class === klass ? klass : Card::Chunk.const_get(klass)
187
+ klass.is_a?(Class) ? klass : Card::Content::Chunk.const_get(klass)
188
188
  end
189
189
  end
190
190
 
@@ -401,16 +401,16 @@ describe Card::Content do
401
401
  )
402
402
  end
403
403
 
404
- it "doesn't fix regular nbsp order with setting" do
405
- # manually configure this setting, then make this one live
406
- # (test above will then fail)
407
- pending "Can't set Card.config.space_last_in_multispace= false "\
408
- 'for one test'
409
- assert_equal 'space  test  two   space',
410
- Card::Content.clean!(
411
- 'space  test  two   space'
412
- )
413
- end
404
+ # it "doesn't fix regular nbsp order with setting" do
405
+ # # manually configure this setting, then make this one live
406
+ # # (test above will then fail)
407
+ # pending "Can't set Card.config.space_last_in_multispace= false "\
408
+ # 'for one test'
409
+ # assert_equal 'space  test  two   space',
410
+ # Card::Content.clean!(
411
+ # 'space  test  two   space'
412
+ # )
413
+ # end
414
414
  end
415
415
  end
416
416
  end
@@ -35,28 +35,28 @@ describe Card::Diff do
35
35
  it 'is green for addition' do
36
36
  a = 'a'
37
37
  b = 'a b'
38
- db = Card::Diff::DiffBuilder.new(a, b)
38
+ db = Card::Diff.new(a, b)
39
39
  expect(db.green?).to be_truthy
40
40
  expect(db.red?).to be_falsey
41
41
  end
42
42
  it 'is red for deletion' do
43
43
  a = 'a'
44
44
  b = ''
45
- db = Card::Diff::DiffBuilder.new(a, b)
45
+ db = Card::Diff.new(a, b)
46
46
  expect(db.green?).to be_falsey
47
47
  expect(db.red?).to be_truthy
48
48
  end
49
49
  it 'is green and red for change' do
50
50
  a = 'a'
51
51
  b = 'b'
52
- db = Card::Diff::DiffBuilder.new(a, b)
52
+ db = Card::Diff.new(a, b)
53
53
  expect(db.green?).to be_truthy
54
54
  expect(db.red?).to be_truthy
55
55
  end
56
56
  it 'is off for no change' do
57
57
  a = 'a'
58
58
  b = 'a'
59
- db = Card::Diff::DiffBuilder.new(a, b)
59
+ db = Card::Diff.new(a, b)
60
60
  expect(db.green?).to be_falsey
61
61
  expect(db.red?).to be_falsey
62
62
  end
@@ -215,4 +215,60 @@ describe Card::StageDirector do
215
215
  end
216
216
  end
217
217
  end
218
+
219
+ describe 'subcards' do
220
+ def create_subcards
221
+ Card.create! name: '', subcards: {
222
+ '+sub1' => 'some content',
223
+ '+sub2' => { '+sub3' => 'content' }
224
+ }
225
+ end
226
+
227
+ it "has correct name if supercard's name get changed" do
228
+ Card::Auth.as_bot do
229
+ changed = false
230
+ in_stage :prepare_to_validate,
231
+ on: :create,
232
+ trigger: :create_subcards do
233
+ self.name = 'main' if name.empty? && !changed
234
+ end
235
+ expect(Card['main+sub1'].class).to eq(Card)
236
+ expect(Card['main+sub2+sub3'].class).to eq(Card)
237
+ end
238
+ end
239
+ it "has correct name if supercard's name get changed to a junction card" do
240
+ Card::Auth.as_bot do
241
+ changed = false
242
+ in_stage :prepare_to_validate,
243
+ on: :create,
244
+ trigger: :create_subcards do
245
+ if name.empty? && !changed
246
+ self.name = 'main1+main2'
247
+ expect(subfield('sub1')).to be
248
+ expect(subfield('sub1').content).to eq('some content')
249
+ end
250
+ end
251
+ expect(Card['main1+main2+sub1'].class).to eq(Card)
252
+ expect(Card['main1+main2+sub1'].content).to eq('some content')
253
+ expect(Card['main1+main2+sub2+sub3'].class).to eq(Card)
254
+ expect(Card['main1+main2+sub2+sub3'].content).to eq('content')
255
+ end
256
+ end
257
+ end
258
+
259
+ describe 'creating and updating cards in stages' do
260
+ it 'update_attributes works integrate stage' do
261
+ act_cnt = Card['A'].acts.size
262
+ in_stage :integrate,
263
+ on: :create,
264
+ trigger: -> { Card.create! name: 'act card' } do
265
+ Card['A'].update_attributes content: 'changed content'
266
+ end
267
+ expect(Card['A'].content).to eq 'changed content'
268
+ # no act added to A
269
+ expect(Card['A'].acts.size).to eq act_cnt
270
+ # new act for 'act card'
271
+ expect(Card['act card'].acts.size).to eq 1
272
+ end
273
+ end
218
274
  end
@@ -69,7 +69,6 @@ describe Card::Subcards do
69
69
  )
70
70
  expect(card.errors).to be_empty
71
71
  expect(Card["#{card.name}+editable"]).to be_truthy
72
-
73
72
  @card = Card.create!(
74
73
  type: 'Book',
75
74
  subcards: { '+editable' => 'sure' }
@@ -99,43 +99,11 @@ describe Card, 'type transition approve create' do
99
99
  end
100
100
  end
101
101
 
102
- # describe Card, "type transition validate_delete" do
103
- # before do @c = change_card_to_type("type-c-card", :basic) end
104
- #
105
- # it "should have errors" do
106
- # @c.errors[:delete_error].first.should == "card c is indestructible"
107
- # end
108
- #
109
- # it "should retain original type" do
110
- # Card["type_c_card"].type_code.should == :cardtype_c
111
- # end
112
- # end
113
-
114
- describe Card, 'type transition validate_create' do
115
- before { @c = change_card_to_type 'basicname', 'cardtype_d' }
116
-
117
- it 'should have errors' do
118
- pending 'CardtypeD does not have a codename, so this is an invalid test'
119
- msg = /card d always has errors/
120
- expect(@c.errors[:type].first.match msg).to be_truthy
121
- end
122
-
123
- it 'should retain original type' do
124
- pending 'CardtypeD does not have a codename, so this is an invalid test'
125
- expect(Card['basicname'].type_code).to eq(:basic)
126
- end
127
- end
128
-
129
102
  describe Card, 'type transition delete callback' do
130
103
  before do
131
104
  @c = change_card_to_type('type-e-card', :basic)
132
105
  end
133
106
 
134
- it 'should decrement counter in before delete' do
135
- pending 'no trigger for this test anymore'
136
- expect(Card.count).to eq(1)
137
- end
138
-
139
107
  it 'should change type of the card' do
140
108
  expect(Card['type-e-card'].type_code).to eq(:basic)
141
109
  end
@@ -144,16 +112,12 @@ end
144
112
  describe Card, 'type transition create callback' do
145
113
  before do
146
114
  Card::Auth.as_bot do
147
- Card.create(name: 'Basic+*type+*delete', type: 'Pointer', content: '[[Anyone Signed in]]')
115
+ Card.create name: 'Basic+*type+*delete', type: 'Pointer',
116
+ content: '[[Anyone Signed in]]'
148
117
  end
149
118
  @c = change_card_to_type('basicname', :cardtype_f)
150
119
  end
151
120
 
152
- it 'should increment counter' do
153
- pending 'No extensions, so no hooks for this now'
154
- expect(Card.count).to eq(3)
155
- end
156
-
157
121
  it 'should change type of card' do
158
122
  expect(Card['basicname'].type_code).to eq(:cardtype_f)
159
123
  end
@@ -161,9 +125,8 @@ end
161
125
 
162
126
  def change_card_to_type name, type
163
127
  card = Card.fetch(name)
164
- tid = card.type_id = Symbol === type ? Card::Codename[type] : Card.fetch_id(type)
165
- # warn "card[#{name.inspect}, T:#{type.inspect}] is #{card.inspect}, TID:#{tid}"
166
- r = card.save
167
- # warn "saved #{card.inspect} R#{r}"
128
+ card.type_id =
129
+ type.is_a?(Symbol) ? Card::Codename[type] : Card.fetch_id(type)
130
+ card.save
168
131
  card
169
132
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: card
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.0
4
+ version: 1.18.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan McCutchen
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2016-02-18 00:00:00.000000000 Z
14
+ date: 2016-02-26 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: smartname
@@ -27,20 +27,6 @@ dependencies:
27
27
  - - '='
28
28
  - !ruby/object:Gem::Version
29
29
  version: 0.2.3
30
- - !ruby/object:Gem::Dependency
31
- name: activerecord-session_store
32
- requirement: !ruby/object:Gem::Requirement
33
- requirements:
34
- - - "~>"
35
- - !ruby/object:Gem::Version
36
- version: '0.1'
37
- type: :runtime
38
- prerelease: false
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - "~>"
42
- - !ruby/object:Gem::Version
43
- version: '0.1'
44
30
  - !ruby/object:Gem::Dependency
45
31
  name: uuid
46
32
  requirement: !ruby/object:Gem::Requirement
@@ -89,14 +75,14 @@ dependencies:
89
75
  requirements:
90
76
  - - "~>"
91
77
  - !ruby/object:Gem::Version
92
- version: 4.2.10
78
+ version: '4.2'
93
79
  type: :runtime
94
80
  prerelease: false
95
81
  version_requirements: !ruby/object:Gem::Requirement
96
82
  requirements:
97
83
  - - "~>"
98
84
  - !ruby/object:Gem::Version
99
- version: 4.2.10
85
+ version: '4.2'
100
86
  - !ruby/object:Gem::Dependency
101
87
  name: recaptcha
102
88
  requirement: !ruby/object:Gem::Requirement
@@ -201,14 +187,14 @@ dependencies:
201
187
  requirements:
202
188
  - - "~>"
203
189
  - !ruby/object:Gem::Version
204
- version: 0.0.5
190
+ version: '0'
205
191
  type: :runtime
206
192
  prerelease: false
207
193
  version_requirements: !ruby/object:Gem::Requirement
208
194
  requirements:
209
195
  - - "~>"
210
196
  - !ruby/object:Gem::Version
211
- version: 0.0.5
197
+ version: '0'
212
198
  - !ruby/object:Gem::Dependency
213
199
  name: diff-lcs
214
200
  requirement: !ruby/object:Gem::Requirement
@@ -223,8 +209,8 @@ dependencies:
223
209
  - - "~>"
224
210
  - !ruby/object:Gem::Version
225
211
  version: '1.2'
226
- description: Cards are data atoms that are grouped into Sets to which Rules can apply.
227
- Cards can formatted with Views and transformed with Events.
212
+ description: Cards are data atoms grouped into Sets to which Rules can apply. Cards
213
+ can formatted with Views and transformed with Events.
228
214
  email:
229
215
  - info@wagn.org
230
216
  executables: []
@@ -391,12 +377,15 @@ files:
391
377
  - lib/card/cache.rb
392
378
  - lib/card/cache/persistent.rb
393
379
  - lib/card/cache/temporary.rb
394
- - lib/card/chunk.rb
395
380
  - lib/card/codename.rb
396
381
  - lib/card/content.rb
382
+ - lib/card/content/chunk.rb
383
+ - lib/card/content/parser.rb
397
384
  - lib/card/core_ext.rb
398
385
  - lib/card/core_migration.rb
399
386
  - lib/card/diff.rb
387
+ - lib/card/diff/lcs.rb
388
+ - lib/card/diff/result.rb
400
389
  - lib/card/director_register.rb
401
390
  - lib/card/env.rb
402
391
  - lib/card/exceptions.rb
data/lib/card/chunk.rb DELETED
@@ -1,122 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
-
3
- require 'uri/common'
4
-
5
- # A chunk is a pattern of text that can be protected
6
- # and interrogated by a format. Each Chunk class has a
7
- # +pattern+ that states what sort of text it matches.
8
- # Chunks are initalized by passing in the result of a
9
-
10
- class Card
11
- # A chunk is a pattern of text that can be protected
12
- # and interrogated by a format. Each Chunk class has a
13
- # +pattern+ that states what sort of text it matches.
14
- # Chunks are initalized by passing in the result of a
15
- # match by its pattern.
16
- module Chunk
17
- mattr_accessor :raw_list, :prefix_regexp_by_list, :prefix_map
18
- @@raw_list = {}
19
- @@prefix_regexp_by_list = {}
20
- @@prefix_map = {}
21
-
22
- class << self
23
- def register_class klass, hash
24
- klass.config = hash.merge class: klass
25
- prefix_index = hash[:idx_char] || :default
26
- # ^ this is gross and needs to be moved out.
27
- prefix_map[prefix_index] = klass.config
28
- end
29
-
30
- def register_list key, list
31
- raw_list[key] = list
32
- end
33
-
34
- def find_class_by_prefix prefix
35
- config = prefix_map[prefix[0, 1]] ||
36
- prefix_map[prefix[-1, 1]] ||
37
- prefix_map[:default]
38
- # prefix identified by first character, last character, or default.
39
- # a little ugly...
40
- config[:class]
41
- end
42
-
43
- def get_prefix_regexp chunk_list_key
44
- prefix_regexp_by_list[chunk_list_key] ||= begin
45
- prefix_res = raw_list[chunk_list_key].map do |chunkname|
46
- chunk_class = const_get chunkname
47
- chunk_class.config[:prefix_re]
48
- end
49
- /(?:#{ prefix_res * '|' })/m
50
- end
51
- end
52
- end
53
-
54
- # not sure whether this is best place. Could really happen almost anywhere
55
- # (even before chunk classes are loaded).
56
- register_list :default, [
57
- :URI, :HostURI, :EmailURI, :EscapedLiteral, :Include, :Link
58
- ]
59
- register_list :references, [:EscapedLiteral, :Include, :Link]
60
- register_list :nest_only, [:Include]
61
- register_list :query, [:QueryReference]
62
-
63
- class Abstract
64
- class_attribute :config
65
- attr_reader :text, :process_chunk
66
-
67
- class << self
68
- # if the prefix regex matched check that chunk against the full regex
69
- def full_match content, prefix=nil
70
- content.match full_re(prefix)
71
- end
72
-
73
- def full_re _prefix
74
- config[:full_re]
75
- end
76
-
77
- def context_ok? _content, _chunk_start
78
- true
79
- end
80
- end
81
-
82
- def reference_code
83
- 'I'
84
- end
85
-
86
- def initialize match, content
87
- @text = match[0]
88
- @processed = nil
89
- @content = content
90
- interpret match, content
91
- self
92
- end
93
-
94
- def interpret _match_string, _content, _params
95
- Rails.logger.info 'no #interpret method found for chunk class: ' \
96
- "#{self.class}"
97
- end
98
-
99
- def format
100
- @content.format
101
- end
102
-
103
- def card
104
- @content.card
105
- end
106
-
107
- def to_s
108
- @process_chunk || @processed || @text
109
- end
110
-
111
- def inspect
112
- "<##{self.class}##{self}>"
113
- end
114
-
115
- def as_json _options={}
116
- @process_chunk || @processed ||
117
- "not rendered #{self.class}, #{card && card.name}"
118
- end
119
- end
120
- end
121
- Loader.load_chunks
122
- end