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.
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