typed_dag 2.0.1 → 2.0.2

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/typed_dag/version.rb +1 -1
  4. metadata +3 -141
  5. data/spec/spec_helper.rb +0 -89
  6. data/spec/support/helpers.rb +0 -47
  7. data/spec/test_app/Rakefile +0 -6
  8. data/spec/test_app/app/assets/config/manifest.js +0 -4
  9. data/spec/test_app/app/assets/javascripts/application.js +0 -13
  10. data/spec/test_app/app/assets/javascripts/cable.js +0 -13
  11. data/spec/test_app/app/assets/stylesheets/application.css +0 -15
  12. data/spec/test_app/app/channels/application_cable/channel.rb +0 -4
  13. data/spec/test_app/app/channels/application_cable/connection.rb +0 -4
  14. data/spec/test_app/app/controllers/application_controller.rb +0 -3
  15. data/spec/test_app/app/helpers/application_helper.rb +0 -2
  16. data/spec/test_app/app/jobs/application_job.rb +0 -2
  17. data/spec/test_app/app/mailers/application_mailer.rb +0 -4
  18. data/spec/test_app/app/models/application_record.rb +0 -3
  19. data/spec/test_app/app/models/message.rb +0 -2
  20. data/spec/test_app/app/models/relation.rb +0 -2
  21. data/spec/test_app/app/views/layouts/application.html.erb +0 -14
  22. data/spec/test_app/app/views/layouts/mailer.html.erb +0 -13
  23. data/spec/test_app/app/views/layouts/mailer.text.erb +0 -1
  24. data/spec/test_app/bin/bundle +0 -3
  25. data/spec/test_app/bin/rails +0 -4
  26. data/spec/test_app/bin/rake +0 -4
  27. data/spec/test_app/bin/setup +0 -38
  28. data/spec/test_app/bin/update +0 -29
  29. data/spec/test_app/bin/yarn +0 -11
  30. data/spec/test_app/config.ru +0 -5
  31. data/spec/test_app/config/application.rb +0 -26
  32. data/spec/test_app/config/boot.rb +0 -5
  33. data/spec/test_app/config/cable.yml +0 -10
  34. data/spec/test_app/config/database.mysql.yml.travis +0 -9
  35. data/spec/test_app/config/database.postgresql.yml.travis +0 -9
  36. data/spec/test_app/config/database.yml +0 -23
  37. data/spec/test_app/config/environment.rb +0 -5
  38. data/spec/test_app/config/environments/development.rb +0 -54
  39. data/spec/test_app/config/environments/production.rb +0 -91
  40. data/spec/test_app/config/environments/test.rb +0 -42
  41. data/spec/test_app/config/initializers/application_controller_renderer.rb +0 -6
  42. data/spec/test_app/config/initializers/assets.rb +0 -14
  43. data/spec/test_app/config/initializers/backtrace_silencers.rb +0 -7
  44. data/spec/test_app/config/initializers/cookies_serializer.rb +0 -5
  45. data/spec/test_app/config/initializers/filter_parameter_logging.rb +0 -4
  46. data/spec/test_app/config/initializers/inflections.rb +0 -16
  47. data/spec/test_app/config/initializers/mime_types.rb +0 -4
  48. data/spec/test_app/config/initializers/typed_dag.rb +0 -12
  49. data/spec/test_app/config/initializers/wrap_parameters.rb +0 -14
  50. data/spec/test_app/config/locales/en.yml +0 -33
  51. data/spec/test_app/config/puma.rb +0 -56
  52. data/spec/test_app/config/routes.rb +0 -3
  53. data/spec/test_app/config/secrets.yml +0 -32
  54. data/spec/test_app/config/spring.rb +0 -6
  55. data/spec/test_app/db/development.sqlite3 +0 -0
  56. data/spec/test_app/db/migrate/20170831093433_create_nodes_and_endges.rb +0 -22
  57. data/spec/test_app/db/schema.rb +0 -35
  58. data/spec/test_app/db/test.sqlite3 +0 -0
  59. data/spec/test_app/log/development.log +0 -101
  60. data/spec/test_app/log/test.log +0 -0
  61. data/spec/test_app/package.json +0 -5
  62. data/spec/test_app/public/404.html +0 -67
  63. data/spec/test_app/public/422.html +0 -67
  64. data/spec/test_app/public/500.html +0 -66
  65. data/spec/test_app/public/apple-touch-icon-precomposed.png +0 -0
  66. data/spec/test_app/public/apple-touch-icon.png +0 -0
  67. data/spec/test_app/public/favicon.ico +0 -0
  68. data/spec/typed_dag/configuration.rb +0 -92
  69. data/spec/typed_dag/edge_spec.rb +0 -578
  70. data/spec/typed_dag/node_spec.rb +0 -2178
  71. data/spec/typed_dag/sql/add_closure_spec.rb +0 -116
  72. data/spec/typed_dag/sql/truncate_closure_spec.rb +0 -112
  73. data/spec/typed_dag_spec.rb +0 -7
@@ -1,67 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>The change you wanted was rejected (422)</title>
5
- <meta name="viewport" content="width=device-width,initial-scale=1">
6
- <style>
7
- .rails-default-error-page {
8
- background-color: #EFEFEF;
9
- color: #2E2F30;
10
- text-align: center;
11
- font-family: arial, sans-serif;
12
- margin: 0;
13
- }
14
-
15
- .rails-default-error-page div.dialog {
16
- width: 95%;
17
- max-width: 33em;
18
- margin: 4em auto 0;
19
- }
20
-
21
- .rails-default-error-page div.dialog > div {
22
- border: 1px solid #CCC;
23
- border-right-color: #999;
24
- border-left-color: #999;
25
- border-bottom-color: #BBB;
26
- border-top: #B00100 solid 4px;
27
- border-top-left-radius: 9px;
28
- border-top-right-radius: 9px;
29
- background-color: white;
30
- padding: 7px 12% 0;
31
- box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
- }
33
-
34
- .rails-default-error-page h1 {
35
- font-size: 100%;
36
- color: #730E15;
37
- line-height: 1.5em;
38
- }
39
-
40
- .rails-default-error-page div.dialog > p {
41
- margin: 0 0 1em;
42
- padding: 1em;
43
- background-color: #F7F7F7;
44
- border: 1px solid #CCC;
45
- border-right-color: #999;
46
- border-left-color: #999;
47
- border-bottom-color: #999;
48
- border-bottom-left-radius: 4px;
49
- border-bottom-right-radius: 4px;
50
- border-top-color: #DADADA;
51
- color: #666;
52
- box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
- }
54
- </style>
55
- </head>
56
-
57
- <body class="rails-default-error-page">
58
- <!-- This file lives in public/422.html -->
59
- <div class="dialog">
60
- <div>
61
- <h1>The change you wanted was rejected.</h1>
62
- <p>Maybe you tried to change something you didn't have access to.</p>
63
- </div>
64
- <p>If you are the application owner check the logs for more information.</p>
65
- </div>
66
- </body>
67
- </html>
@@ -1,66 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>We're sorry, but something went wrong (500)</title>
5
- <meta name="viewport" content="width=device-width,initial-scale=1">
6
- <style>
7
- .rails-default-error-page {
8
- background-color: #EFEFEF;
9
- color: #2E2F30;
10
- text-align: center;
11
- font-family: arial, sans-serif;
12
- margin: 0;
13
- }
14
-
15
- .rails-default-error-page div.dialog {
16
- width: 95%;
17
- max-width: 33em;
18
- margin: 4em auto 0;
19
- }
20
-
21
- .rails-default-error-page div.dialog > div {
22
- border: 1px solid #CCC;
23
- border-right-color: #999;
24
- border-left-color: #999;
25
- border-bottom-color: #BBB;
26
- border-top: #B00100 solid 4px;
27
- border-top-left-radius: 9px;
28
- border-top-right-radius: 9px;
29
- background-color: white;
30
- padding: 7px 12% 0;
31
- box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
- }
33
-
34
- .rails-default-error-page h1 {
35
- font-size: 100%;
36
- color: #730E15;
37
- line-height: 1.5em;
38
- }
39
-
40
- .rails-default-error-page div.dialog > p {
41
- margin: 0 0 1em;
42
- padding: 1em;
43
- background-color: #F7F7F7;
44
- border: 1px solid #CCC;
45
- border-right-color: #999;
46
- border-left-color: #999;
47
- border-bottom-color: #999;
48
- border-bottom-left-radius: 4px;
49
- border-bottom-right-radius: 4px;
50
- border-top-color: #DADADA;
51
- color: #666;
52
- box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
- }
54
- </style>
55
- </head>
56
-
57
- <body class="rails-default-error-page">
58
- <!-- This file lives in public/500.html -->
59
- <div class="dialog">
60
- <div>
61
- <h1>We're sorry, but something went wrong.</h1>
62
- </div>
63
- <p>If you are the application owner check the logs for more information.</p>
64
- </div>
65
- </body>
66
- </html>
File without changes
File without changes
@@ -1,92 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe TypedDag::Configuration do
4
- describe 'defining/accessing' do
5
- context 'for a single confg' do
6
- before do
7
- described_class.set edge_class_name: 'Relation',
8
- node_class_name: 'Message',
9
- types: { hierarchy: { up: { name: :parent, limit: 1 },
10
- down: :children,
11
- all_up: :ancestors,
12
- all_down: :descendants },
13
- invalidate: { up: :invalidated_by,
14
- down: :invalidates,
15
- all_up: :all_invalidated_by,
16
- all_down: :all_invalidates } }
17
- end
18
-
19
- it 'accesses the correct config for the edge name' do
20
- expect(described_class['Relation'].node_class_name)
21
- .to eql 'Message'
22
- end
23
-
24
- it 'accesses the correct config for the node name' do
25
- expect(described_class['Message'].edge_class_name)
26
- .to eql 'Relation'
27
- end
28
-
29
- it 'accesses the correct config for the edge class' do
30
- expect(described_class[Relation].node_class_name)
31
- .to eql 'Message'
32
- end
33
-
34
- it 'accesses the correct config for the node class' do
35
- expect(described_class[Message].edge_class_name)
36
- .to eql 'Relation'
37
- end
38
- end
39
-
40
- context 'for a multiple confgs' do
41
- before do
42
- described_class.set [
43
- {
44
- edge_class_name: 'Relation',
45
- node_class_name: 'Message',
46
- types: { hierarchy: { up: { name: :parent, limit: 1 },
47
- down: :children,
48
- all_up: :ancestors,
49
- all_down: :descendants },
50
- invalidate: { up: :invalidated_by,
51
- down: :invalidates,
52
- all_up: :all_invalidated_by,
53
- all_down: :all_invalidates } }
54
- },
55
- {
56
- edge_class_name: 'Relation2',
57
- node_class_name: 'Message2',
58
- types: { hierarchy: { up: { name: :parent, limit: 1 },
59
- down: :children,
60
- all_up: :ancestors,
61
- all_down: :descendants },
62
- invalidate: { up: :invalidated_by,
63
- down: :invalidates,
64
- all_up: :all_invalidated_by,
65
- all_down: :all_invalidates } }
66
-
67
- }
68
- ]
69
- end
70
-
71
- it 'accesses the correct config for the first edge name' do
72
- expect(described_class['Relation'].node_class_name)
73
- .to eql 'Message'
74
- end
75
-
76
- it 'accesses the correct config for the first node name' do
77
- expect(described_class['Message'].edge_class_name)
78
- .to eql 'Relation'
79
- end
80
-
81
- it 'accesses the correct config for the second edge name' do
82
- expect(described_class['Relation2'].node_class_name)
83
- .to eql 'Message2'
84
- end
85
-
86
- it 'accesses the correct config for the second node name' do
87
- expect(described_class['Message2'].edge_class_name)
88
- .to eql 'Relation2'
89
- end
90
- end
91
- end
92
- end
@@ -1,578 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/helpers'
3
-
4
- RSpec.describe 'Edge' do
5
- include TypedDag::Specs::Helpers
6
- # using Relation, Message as the concrete classes
7
-
8
- let(:from) { Message.new text: 'from' }
9
- let(:to) { Message.new text: 'to' }
10
- let(:relation) do
11
- Relation.new from: from,
12
- to: to,
13
- hierarchy: 1
14
- end
15
-
16
- describe 'validations' do
17
- it 'is valid' do
18
- expect(relation)
19
- .to be_valid
20
- end
21
-
22
- context 'without a from' do
23
- let(:from) { nil }
24
-
25
- it 'is invalid' do
26
- expect(relation)
27
- .to be_invalid
28
- end
29
-
30
- it 'states the error' do
31
- relation.valid?
32
-
33
- expect(relation.errors.details[:from])
34
- .to match_array([error: :blank])
35
- end
36
- end
37
-
38
- context 'without a to' do
39
- let(:to) { nil }
40
-
41
- it 'is invalid' do
42
- expect(relation)
43
- .to be_invalid
44
- end
45
-
46
- it 'states the error' do
47
- relation.valid?
48
-
49
- expect(relation.errors.details[:to])
50
- .to match_array([error: :blank])
51
- end
52
- end
53
-
54
- context 'with a relation already in place between the two nodes' do
55
- let!(:same_relation) do
56
- Relation.create from: from,
57
- to: to
58
- end
59
-
60
- it 'is invalid' do
61
- expect(relation)
62
- .to be_invalid
63
- end
64
-
65
- it 'notes the uniqueness constraint' do
66
- relation.valid?
67
-
68
- expect(relation.errors.details[:from].first[:error])
69
- .to eql :taken
70
- end
71
- end
72
-
73
- context 'with a relation already in place between the two nodes having a different type' do
74
- let!(:same_relation) do
75
- Relation.create from: from,
76
- to: to,
77
- invalidate: 1
78
- end
79
-
80
- it 'is invalid' do
81
- expect(relation)
82
- .to be_invalid
83
- end
84
-
85
- it 'notes the uniqueness constraint' do
86
- relation.valid?
87
-
88
- expect(relation.errors.details[:from].first[:error])
89
- .to eql :taken
90
- end
91
- end
92
-
93
- context 'with a closure relation already in place between the two nodes (same type)' do
94
- let!(:closure_relation) do
95
- Relation.create from: from,
96
- to: to,
97
- invalidate: 2
98
- end
99
-
100
- it 'is valid' do
101
- expect(relation)
102
- .to be_valid
103
- end
104
- end
105
-
106
- context 'with a closure relation already in place between the two nodes (mixed type)' do
107
- let!(:closure_relation) do
108
- Relation.create from: from,
109
- to: to,
110
- invalidate: 1,
111
- hierarchy: 1
112
- end
113
-
114
- it 'is valid' do
115
- expect(relation)
116
- .to be_valid
117
- end
118
- end
119
-
120
- context 'with a relation in place but in the other direction' do
121
- let(:inverse_relation) do
122
- Relation.create to: from,
123
- from: to,
124
- hierarchy: 1
125
- end
126
-
127
- before do
128
- inverse_relation
129
- end
130
-
131
- it 'is invalid' do
132
- expect(relation)
133
- .to be_invalid
134
- end
135
- end
136
-
137
- context 'with the relation switching directions' do
138
- before do
139
- relation.save
140
- relation.from = to
141
- relation.to = from
142
- end
143
-
144
- it 'is valid' do
145
- expect(relation)
146
- .to be_valid
147
- end
148
- end
149
-
150
- context 'with A - B - C and trying to connect C and A' do
151
- let(:a) { Message.create text: 'A' }
152
- let(:b) { Message.create text: 'B' }
153
- let(:c) { Message.create text: 'C' }
154
- let!(:relationAB) do
155
- Relation.create from: a,
156
- to: b,
157
- hierarchy: 1
158
- end
159
- let!(:relationBC) do
160
- Relation.create from: b,
161
- to: c,
162
- hierarchy: 1
163
- end
164
- let(:from) { c }
165
- let(:to) { b }
166
-
167
- it 'is invalid' do
168
- expect(relation)
169
- .to be_invalid
170
- end
171
- end
172
-
173
- context 'with A - B - C (different type) already related and trying to connect C and A' do
174
- let(:a) { Message.create text: 'A' }
175
- let(:b) { Message.create text: 'B' }
176
- let(:c) { Message.create text: 'C' }
177
- let!(:relationAB) do
178
- Relation.create from: a,
179
- to: b,
180
- invalidate: 1
181
- end
182
- let!(:relationBC) do
183
- Relation.create from: b,
184
- to: c,
185
- hierarchy: 1
186
- end
187
- let(:from) { c }
188
- let(:to) { b }
189
-
190
- it 'is invalid' do
191
- expect(relation)
192
- .to be_invalid
193
- end
194
- end
195
- end
196
-
197
- describe '.direct' do
198
- description = <<-'WITH'
199
-
200
- DAG:
201
- ------- A -------
202
- / \
203
- invalidate hierarchy
204
- / \
205
- B C
206
- | |
207
- hierarchy hierarchy
208
- | |
209
- D E
210
-
211
- WITH
212
- context description do
213
- let!(:a) { Message.create text: 'A' }
214
- let!(:b) { create_message_with_invalidated_by('B', a) }
215
- let!(:c) { Message.create text: 'C', parent: a }
216
- let!(:d) { Message.create text: 'D', parent: b }
217
- let!(:e) { Message.create text: 'E', parent: c }
218
-
219
- it 'returns only the relations that have no hops' do
220
- expect(Relation.direct.map { |r| [r.from.text, r.to.text] })
221
- .to match_array [['A', 'B'], ['B', 'D'], ['A', 'C'], ['C', 'E']]
222
- end
223
- end
224
- end
225
-
226
- describe '#direct?' do
227
- context 'for a relation having invalidate = 1' do
228
- let(:relation) { Relation.new invalidate: 1 }
229
-
230
- it 'is true' do
231
- expect(relation)
232
- .to be_direct
233
- end
234
- end
235
-
236
- context 'for a relation having invalidate = 2' do
237
- let(:relation) { Relation.new invalidate: 2 }
238
-
239
- it 'is true' do
240
- expect(relation)
241
- .not_to be_direct
242
- end
243
- end
244
-
245
- context 'for a relation having invalidate = 1 and hierarchy = 1' do
246
- let(:relation) { Relation.new invalidate: 1, hierarchy: 1 }
247
-
248
- it 'is true' do
249
- expect(relation)
250
- .not_to be_direct
251
- end
252
- end
253
- end
254
-
255
- describe 'type selection scopes' do
256
- description = <<-'WITH'
257
-
258
- DAG:
259
- ------- A -------
260
- / \
261
- invalidate hierarchy
262
- / \
263
- B C
264
- / \ |
265
- hierarchy invalidate hierarchy
266
- / \ |
267
- D E F
268
-
269
- WITH
270
- context description do
271
- let!(:a) { Message.create text: 'A' }
272
- let!(:b) { create_message_with_invalidated_by('B', a) }
273
- let!(:c) { Message.create text: 'C', parent: a }
274
- let!(:d) { Message.create text: 'D', parent: b }
275
- let!(:e) { create_message_with_invalidated_by('E', b) }
276
- let!(:f) { Message.create text: 'F', parent: c }
277
-
278
- it 'returns all hierarchy relations (including transtitive) for #hierarchy' do
279
- expect(Relation.non_reflexive.hierarchy.map { |r| [r.from.text, r.to.text, r.hierarchy, r.invalidate ] })
280
- .to match_array [['B', 'D', 1, 0],
281
- ['A', 'C', 1, 0],
282
- ['C', 'F', 1, 0],
283
- ['A', 'F', 2, 0]]
284
- end
285
-
286
- it 'returns all invalidate relations (including transtitive) for #invalidate' do
287
- expect(Relation.non_reflexive.invalidate.map { |r| [r.from.text, r.to.text, r.hierarchy, r.invalidate ] })
288
- .to match_array [['A', 'B', 0, 1],
289
- ['B', 'E', 0, 1],
290
- ['A', 'E', 0, 2]]
291
- end
292
-
293
- it 'returns all non hierarchy relations (including transtitive) for #non_hierarchy' do
294
- expect(Relation.non_reflexive.non_hierarchy.map { |r| [r.from.text, r.to.text, r.hierarchy, r.invalidate ] })
295
- .to match_array [['A', 'B', 0, 1],
296
- ['B', 'E', 0, 1],
297
- ['A', 'E', 0, 2]]
298
- end
299
-
300
- it 'returns all non invalidate relations (including transtitive) for #non_invalidate' do
301
- expect(Relation.non_reflexive.non_invalidate.map { |r| [r.from.text, r.to.text, r.hierarchy, r.invalidate ] })
302
- .to match_array [['B', 'D', 1, 0],
303
- ['A', 'C', 1, 0],
304
- ['C', 'F', 1, 0],
305
- ['A', 'F', 2, 0]]
306
- end
307
- end
308
-
309
- describe 'altering type (column)' do
310
- description = <<-'WITH'
311
-
312
- DAG before:
313
- A
314
- |
315
- invalidate
316
- +
317
- B
318
- |
319
- invalidate
320
- +
321
- C
322
- / \
323
- invalidate hierarchy
324
- + +
325
- D E
326
- WITH
327
- context description do
328
- let!(:a) { Message.create text: 'A' }
329
- let!(:b) { create_message_with_invalidated_by('B', a) }
330
- let!(:c) { create_message_with_invalidated_by('C', b) }
331
- let!(:d) { create_message_with_invalidated_by('D', c) }
332
- let!(:e) { Message.create text: 'E', parent: c }
333
-
334
- description = <<-'WITH'
335
-
336
- DAG after (altering relation between B and C):
337
- A
338
- |
339
- invalidate
340
- +
341
- B
342
- |
343
- hierarchy
344
- +
345
- C
346
- / \
347
- invalidate hierarchy
348
- + +
349
- D E
350
- WITH
351
-
352
- context description do
353
- before do
354
- r = Relation.where(from: b, to: c).first
355
- r.hierarchy = 1
356
- r.invalidate = 0
357
- r.save!
358
- end
359
-
360
- it 'expects the transitive relations to be updated' do
361
- attribute_array = to_attribute_array Relation.non_reflexive
362
- expect(attribute_array)
363
- .to match_array([['A', 'B', 0, 1, 1],
364
- ['A', 'C', 1, 1, 1],
365
- ['A', 'D', 1, 2, 1],
366
- ['A', 'E', 2, 1, 1],
367
- ['B', 'C', 1, 0, 1],
368
- ['B', 'D', 1, 1, 1],
369
- ['B', 'E', 2, 0, 1],
370
- ['C', 'D', 0, 1, 1],
371
- ['C', 'E', 1, 0, 1]])
372
- end
373
- end
374
- end
375
- end
376
-
377
- describe 'altering ancestor' do
378
- description = <<-'WITH'
379
-
380
- DAG before:
381
- A F
382
- |
383
- invalidate
384
- +
385
- B
386
- |
387
- invalidate
388
- +
389
- C
390
- / \
391
- invalidate hierarchy
392
- + +
393
- D E
394
- WITH
395
- context description do
396
- let!(:a) { Message.create text: 'A' }
397
- let!(:b) { create_message_with_invalidated_by('B', a) }
398
- let!(:c) { create_message_with_invalidated_by('C', b) }
399
- let!(:d) { create_message_with_invalidated_by('D', c) }
400
- let!(:e) { Message.create text: 'E', parent: c }
401
- let!(:f) { Message.create text: 'F' }
402
-
403
- description = <<-'WITH'
404
-
405
- DAG after (changing B's invalidate from A to F):
406
- A F
407
- |
408
- invalidate
409
- +
410
- B
411
- |
412
- invalidate
413
- +
414
- C
415
- / \
416
- invalidate hierarchy
417
- + +
418
- D E
419
- WITH
420
-
421
- context description do
422
- before do
423
- r = Relation.where(from: a, to: b).first
424
- r.from = f
425
- r.save!
426
- end
427
-
428
- it 'expects the transitive relations to be updated' do
429
- attribute_array = to_attribute_array Relation.non_reflexive
430
- expect(attribute_array)
431
- .to match_array([['F', 'B', 0, 1, 1],
432
- ['F', 'C', 0, 2, 1],
433
- ['F', 'D', 0, 3, 1],
434
- ['F', 'E', 1, 2, 1],
435
- ['B', 'C', 0, 1, 1],
436
- ['B', 'D', 0, 2, 1],
437
- ['B', 'E', 1, 1, 1],
438
- ['C', 'D', 0, 1, 1],
439
- ['C', 'E', 1, 0, 1]])
440
- end
441
- end
442
- end
443
- end
444
-
445
- describe 'altering descendant' do
446
- description = <<-'WITH'
447
-
448
- DAG before:
449
- A F
450
- |
451
- invalidate
452
- +
453
- B
454
- |
455
- invalidate
456
- +
457
- C
458
- / \
459
- invalidate hierarchy
460
- + +
461
- D E
462
- WITH
463
- context description do
464
- let!(:a) { Message.create text: 'A' }
465
- let!(:b) { create_message_with_invalidated_by('B', a) }
466
- let!(:c) { create_message_with_invalidated_by('C', b) }
467
- let!(:d) { create_message_with_invalidated_by('D', c) }
468
- let!(:e) { Message.create text: 'E', parent: c }
469
- let!(:f) { Message.create text: 'F' }
470
-
471
- description = <<-'WITH'
472
-
473
- DAG after (changing B's invalidate from A to F):
474
- A
475
- |
476
- invalidate
477
- +
478
- B
479
- |
480
- invalidate
481
- +
482
- C
483
- / \
484
- invalidate hierarchy
485
- + +
486
- D F E
487
- WITH
488
-
489
- context description do
490
- before do
491
- r = Relation.where(from: c, to: d).first
492
- r.to = f
493
- r.save!
494
- end
495
-
496
- it 'expects the transitive relations to be updated' do
497
- attribute_array = to_attribute_array Relation.non_reflexive
498
- expect(attribute_array)
499
- .to match_array([['A', 'B', 0, 1, 1],
500
- ['A', 'C', 0, 2, 1],
501
- ['A', 'F', 0, 3, 1],
502
- ['A', 'E', 1, 2, 1],
503
- ['B', 'C', 0, 1, 1],
504
- ['B', 'F', 0, 2, 1],
505
- ['B', 'E', 1, 1, 1],
506
- ['C', 'F', 0, 1, 1],
507
- ['C', 'E', 1, 0, 1]])
508
- end
509
- end
510
- end
511
- end
512
-
513
- describe 'altering ancestor' do
514
- description = <<-'WITH'
515
-
516
- DAG before:
517
- A F
518
- |
519
- invalidate
520
- +
521
- B
522
- |
523
- invalidate
524
- +
525
- C
526
- / \
527
- invalidate hierarchy
528
- + +
529
- D E
530
- WITH
531
- context description do
532
- let!(:a) { Message.create text: 'A' }
533
- let!(:b) { create_message_with_invalidated_by('B', a) }
534
- let!(:c) { create_message_with_invalidated_by('C', b) }
535
- let!(:d) { create_message_with_invalidated_by('D', c) }
536
- let!(:e) { Message.create text: 'E', parent: c }
537
- let!(:f) { Message.create text: 'F' }
538
-
539
- description = <<-'WITH'
540
-
541
- DAG after (changing B's invalidate from A to F):
542
-
543
- A
544
- | F
545
- invalidate |
546
- + invalidate
547
- B +
548
- C
549
- / \
550
- invalidate hierarchy
551
- + +
552
- D E
553
-
554
-
555
- WITH
556
-
557
- context description do
558
- before do
559
- r = Relation.where(from: b, to: c).first
560
- r.from = f
561
- r.save!
562
- end
563
-
564
- it 'expects the transitive relations to be updated' do
565
- attribute_array = to_attribute_array Relation.non_reflexive
566
- expect(attribute_array)
567
- .to match_array([['A', 'B', 0, 1, 1],
568
- ['F', 'C', 0, 1, 1],
569
- ['C', 'D', 0, 1, 1],
570
- ['C', 'E', 1, 0, 1],
571
- ['F', 'D', 0, 2, 1],
572
- ['F', 'E', 1, 1, 1]])
573
- end
574
- end
575
- end
576
- end
577
- end
578
- end