lex-cognitive-synthesis 0.1.0

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.
@@ -0,0 +1,233 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::CognitiveSynthesis::Helpers::SynthesisEngine do
4
+ subject(:engine) { described_class.new }
5
+
6
+ def add_stream(type: :emotional, content: { value: 1 }, weight: 0.7, confidence: 0.8)
7
+ engine.add_stream(stream_type: type, content: content, weight: weight, confidence: confidence)
8
+ end
9
+
10
+ describe '#add_stream' do
11
+ it 'returns success with stream_id' do
12
+ result = add_stream
13
+ expect(result[:success]).to be true
14
+ expect(result[:stream_id]).to match(/\A[0-9a-f-]{36}\z/)
15
+ end
16
+
17
+ it 'stores stream in @streams' do
18
+ add_stream
19
+ expect(engine.streams.size).to eq(1)
20
+ end
21
+
22
+ it 'rejects invalid stream_type' do
23
+ result = engine.add_stream(stream_type: :invalid, content: {})
24
+ expect(result[:success]).to be false
25
+ expect(result[:error]).to eq(:invalid_stream_type)
26
+ end
27
+
28
+ it 'accepts all valid stream types' do
29
+ %i[emotional perceptual memorial predictive reasoning social identity motor].each do |type|
30
+ result = engine.add_stream(stream_type: type, content: {})
31
+ expect(result[:success]).to be true
32
+ end
33
+ end
34
+
35
+ it 'prunes when exceeding MAX_STREAMS' do
36
+ 51.times { add_stream }
37
+ expect(engine.streams.size).to eq(50)
38
+ end
39
+ end
40
+
41
+ describe '#remove_stream' do
42
+ it 'removes an existing stream' do
43
+ result = add_stream
44
+ remove = engine.remove_stream(stream_id: result[:stream_id])
45
+ expect(remove[:success]).to be true
46
+ expect(engine.streams).to be_empty
47
+ end
48
+
49
+ it 'returns not_found for missing stream' do
50
+ result = engine.remove_stream(stream_id: 'nonexistent')
51
+ expect(result[:success]).to be false
52
+ expect(result[:error]).to eq(:not_found)
53
+ end
54
+ end
55
+
56
+ describe '#synthesize!' do
57
+ it 'fails with fewer than MIN_STREAMS_FOR_SYNTHESIS active streams' do
58
+ add_stream
59
+ result = engine.synthesize!
60
+ expect(result[:success]).to be false
61
+ expect(result[:error]).to eq(:insufficient_streams)
62
+ end
63
+
64
+ it 'succeeds with enough streams' do
65
+ 2.times { add_stream }
66
+ result = engine.synthesize!
67
+ expect(result[:success]).to be true
68
+ expect(result[:synthesis]).to have_key(:id)
69
+ end
70
+
71
+ it 'stores synthesis in history' do
72
+ 2.times { add_stream }
73
+ engine.synthesize!
74
+ expect(engine.syntheses.size).to eq(1)
75
+ end
76
+
77
+ it 'includes coherence in result' do
78
+ 2.times { add_stream }
79
+ result = engine.synthesize!
80
+ expect(result[:synthesis][:coherence]).to be_between(0.0, 1.0)
81
+ end
82
+
83
+ it 'includes novelty in result' do
84
+ 2.times { add_stream }
85
+ result = engine.synthesize!
86
+ expect(result[:synthesis][:novelty]).to be_between(0.0, 1.0)
87
+ end
88
+
89
+ it 'includes confidence in result' do
90
+ 2.times { add_stream }
91
+ result = engine.synthesize!
92
+ expect(result[:synthesis][:confidence]).to be_between(0.0, 1.0)
93
+ end
94
+
95
+ it 'marks first synthesis as maximally novel (no prior)' do
96
+ 2.times { add_stream }
97
+ result = engine.synthesize!
98
+ expect(result[:synthesis][:novelty]).to eq(1.0)
99
+ end
100
+
101
+ it 'caps syntheses at MAX_SYNTHESES' do
102
+ 2.times { add_stream }
103
+ 201.times { engine.synthesize! }
104
+ expect(engine.syntheses.size).to eq(200)
105
+ end
106
+
107
+ it 'returns content with dominant_type' do
108
+ 2.times { add_stream }
109
+ result = engine.synthesize!
110
+ expect(result[:synthesis][:content]).to have_key(:dominant_type)
111
+ end
112
+ end
113
+
114
+ describe '#decay_all!' do
115
+ it 'returns success' do
116
+ result = engine.decay_all!
117
+ expect(result[:success]).to be true
118
+ end
119
+
120
+ it 'reduces freshness on all streams' do
121
+ add_stream
122
+ stream = engine.streams.values.first
123
+ before = stream.freshness
124
+ engine.decay_all!
125
+ expect(stream.freshness).to be < before
126
+ end
127
+
128
+ it 'removes stale streams' do
129
+ add_stream
130
+ stream = engine.streams.values.first
131
+ 46.times { stream.decay_freshness! }
132
+ engine.decay_all!
133
+ expect(engine.streams).to be_empty
134
+ end
135
+
136
+ it 'reports removed and remaining counts' do
137
+ 2.times { add_stream }
138
+ result = engine.decay_all!
139
+ expect(result).to have_key(:streams_removed)
140
+ expect(result).to have_key(:streams_remaining)
141
+ end
142
+ end
143
+
144
+ describe '#stream_conflict?' do
145
+ let(:id_a) { add_stream(weight: 0.9, content: { signal: :danger })[:stream_id] }
146
+ let(:id_b) { add_stream(weight: 0.1, content: { signal: :safe })[:stream_id] }
147
+
148
+ it 'detects weight opposition' do
149
+ result = engine.stream_conflict?(stream_id_a: id_a, stream_id_b: id_b)
150
+ expect(result[:success]).to be true
151
+ expect(result[:weight_opposition]).to be true
152
+ end
153
+
154
+ it 'detects content conflict on shared keys' do
155
+ result = engine.stream_conflict?(stream_id_a: id_a, stream_id_b: id_b)
156
+ expect(result[:content_conflict]).to be true
157
+ end
158
+
159
+ it 'reports no conflict for compatible streams' do
160
+ a = add_stream(weight: 0.6, content: { value: 1 })[:stream_id]
161
+ b = add_stream(weight: 0.7, content: { value: 1 })[:stream_id]
162
+ result = engine.stream_conflict?(stream_id_a: a, stream_id_b: b)
163
+ expect(result[:conflict]).to be false
164
+ end
165
+
166
+ it 'returns not_found for missing stream' do
167
+ result = engine.stream_conflict?(stream_id_a: 'x', stream_id_b: 'y')
168
+ expect(result[:success]).to be false
169
+ expect(result[:error]).to eq(:stream_not_found)
170
+ end
171
+ end
172
+
173
+ describe '#dominant_stream' do
174
+ it 'returns no_streams error when empty' do
175
+ result = engine.dominant_stream
176
+ expect(result[:success]).to be false
177
+ expect(result[:error]).to eq(:no_streams)
178
+ end
179
+
180
+ it 'returns the stream with highest effective_weight' do
181
+ add_stream(weight: 0.3, confidence: 0.3)
182
+ id = add_stream(weight: 0.9, confidence: 0.95)[:stream_id]
183
+ result = engine.dominant_stream
184
+ expect(result[:success]).to be true
185
+ expect(result[:stream][:id]).to eq(id)
186
+ end
187
+ end
188
+
189
+ describe '#synthesis_history' do
190
+ it 'returns empty list when no syntheses' do
191
+ result = engine.synthesis_history
192
+ expect(result[:syntheses]).to be_empty
193
+ expect(result[:count]).to eq(0)
194
+ end
195
+
196
+ it 'returns last N syntheses' do
197
+ 2.times { add_stream }
198
+ 5.times { engine.synthesize! }
199
+ result = engine.synthesis_history(limit: 3)
200
+ expect(result[:count]).to eq(3)
201
+ end
202
+ end
203
+
204
+ describe '#average_coherence' do
205
+ it 'returns 0.0 when no syntheses' do
206
+ result = engine.average_coherence
207
+ expect(result[:average_coherence]).to eq(0.0)
208
+ expect(result[:sample_size]).to eq(0)
209
+ end
210
+
211
+ it 'computes average coherence over recent syntheses' do
212
+ 2.times { add_stream }
213
+ 3.times { engine.synthesize! }
214
+ result = engine.average_coherence
215
+ expect(result[:average_coherence]).to be_between(0.0, 1.0)
216
+ expect(result[:sample_size]).to eq(3)
217
+ end
218
+ end
219
+
220
+ describe '#to_h' do
221
+ it 'returns summary stats hash' do
222
+ add_stream(type: :emotional)
223
+ result = engine.to_h
224
+ expect(result).to include(:stream_count, :synthesis_count, :active_streams,
225
+ :stale_streams, :average_coherence)
226
+ end
227
+
228
+ it 'reflects current stream count' do
229
+ 3.times { add_stream }
230
+ expect(engine.to_h[:stream_count]).to eq(3)
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::CognitiveSynthesis::Helpers::Synthesis do
4
+ subject(:synthesis) do
5
+ described_class.new(
6
+ streams: %w[abc def],
7
+ coherence: 0.75,
8
+ novelty: 0.8,
9
+ confidence: 0.7,
10
+ content: { dominant_type: :emotional, stream_count: 2 }
11
+ )
12
+ end
13
+
14
+ describe '#initialize' do
15
+ it 'assigns a UUID id' do
16
+ expect(synthesis.id).to match(/\A[0-9a-f-]{36}\z/)
17
+ end
18
+
19
+ it 'stores stream ids' do
20
+ expect(synthesis.streams).to eq(%w[abc def])
21
+ end
22
+
23
+ it 'clamps coherence to 0-1' do
24
+ s = described_class.new(streams: [], coherence: 1.5, novelty: 0.5, confidence: 0.5, content: {})
25
+ expect(s.coherence).to eq(1.0)
26
+ end
27
+
28
+ it 'clamps novelty to 0-1' do
29
+ s = described_class.new(streams: [], coherence: 0.5, novelty: -0.5, confidence: 0.5, content: {})
30
+ expect(s.novelty).to eq(0.0)
31
+ end
32
+
33
+ it 'clamps confidence to 0-1' do
34
+ s = described_class.new(streams: [], coherence: 0.5, novelty: 0.5, confidence: 2.0, content: {})
35
+ expect(s.confidence).to eq(1.0)
36
+ end
37
+
38
+ it 'sets created_at as UTC time' do
39
+ expect(synthesis.created_at).to be_a(Time)
40
+ end
41
+ end
42
+
43
+ describe '#fragmented?' do
44
+ it 'returns false when coherence >= COHERENCE_THRESHOLD' do
45
+ expect(synthesis.fragmented?).to be false
46
+ end
47
+
48
+ it 'returns true when coherence < COHERENCE_THRESHOLD' do
49
+ s = described_class.new(streams: [], coherence: 0.4, novelty: 0.5, confidence: 0.5, content: {})
50
+ expect(s.fragmented?).to be true
51
+ end
52
+ end
53
+
54
+ describe '#novel?' do
55
+ it 'returns true when novelty > NOVELTY_THRESHOLD' do
56
+ expect(synthesis.novel?).to be true
57
+ end
58
+
59
+ it 'returns false when novelty <= NOVELTY_THRESHOLD' do
60
+ s = described_class.new(streams: [], coherence: 0.5, novelty: 0.5, confidence: 0.5, content: {})
61
+ expect(s.novel?).to be false
62
+ end
63
+ end
64
+
65
+ describe '#coherence_label' do
66
+ it 'returns :coherent for coherence 0.75' do
67
+ expect(synthesis.coherence_label).to eq(:coherent)
68
+ end
69
+
70
+ it 'returns :unified for coherence 0.9' do
71
+ s = described_class.new(streams: [], coherence: 0.9, novelty: 0.5, confidence: 0.5, content: {})
72
+ expect(s.coherence_label).to eq(:unified)
73
+ end
74
+ end
75
+
76
+ describe '#confidence_label' do
77
+ it 'returns :confident for confidence 0.7' do
78
+ expect(synthesis.confidence_label).to eq(:confident)
79
+ end
80
+ end
81
+
82
+ describe '#to_h' do
83
+ let(:hash) { synthesis.to_h }
84
+
85
+ it 'includes all expected keys' do
86
+ %i[id streams coherence novelty confidence content fragmented novel
87
+ coherence_label confidence_label created_at].each do |key|
88
+ expect(hash).to have_key(key)
89
+ end
90
+ end
91
+
92
+ it 'reflects fragmented state' do
93
+ s = described_class.new(streams: [], coherence: 0.3, novelty: 0.5, confidence: 0.5, content: {})
94
+ expect(s.to_h[:fragmented]).to be true
95
+ end
96
+
97
+ it 'reflects novel state' do
98
+ expect(hash[:novel]).to be true
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::CognitiveSynthesis::Helpers::SynthesisStream do
4
+ subject(:stream) do
5
+ described_class.new(stream_type: :emotional, content: { mood: 'alert' }, weight: 0.8, confidence: 0.9)
6
+ end
7
+
8
+ describe '#initialize' do
9
+ it 'assigns a UUID id' do
10
+ expect(stream.id).to match(/\A[0-9a-f-]{36}\z/)
11
+ end
12
+
13
+ it 'sets stream_type' do
14
+ expect(stream.stream_type).to eq(:emotional)
15
+ end
16
+
17
+ it 'sets content' do
18
+ expect(stream.content).to eq({ mood: 'alert' })
19
+ end
20
+
21
+ it 'clamps weight to 0-1' do
22
+ s = described_class.new(stream_type: :perceptual, content: {}, weight: 1.5)
23
+ expect(s.weight).to eq(1.0)
24
+ end
25
+
26
+ it 'clamps confidence to 0-1' do
27
+ s = described_class.new(stream_type: :perceptual, content: {}, confidence: -0.1)
28
+ expect(s.confidence).to eq(0.0)
29
+ end
30
+
31
+ it 'initializes freshness at 1.0' do
32
+ expect(stream.freshness).to eq(1.0)
33
+ end
34
+
35
+ it 'sets created_at as UTC time' do
36
+ expect(stream.created_at).to be_a(Time)
37
+ end
38
+ end
39
+
40
+ describe '#decay_freshness!' do
41
+ it 'reduces freshness by FRESHNESS_DECAY' do
42
+ before = stream.freshness
43
+ stream.decay_freshness!
44
+ expect(stream.freshness).to be_within(0.001).of(before - 0.02)
45
+ end
46
+
47
+ it 'never drops below 0.0' do
48
+ 60.times { stream.decay_freshness! }
49
+ expect(stream.freshness).to eq(0.0)
50
+ end
51
+ end
52
+
53
+ describe '#stale?' do
54
+ it 'returns false when freshness is high' do
55
+ expect(stream.stale?).to be false
56
+ end
57
+
58
+ it 'returns true when freshness drops below 0.1' do
59
+ 46.times { stream.decay_freshness! }
60
+ expect(stream.stale?).to be true
61
+ end
62
+ end
63
+
64
+ describe '#effective_weight' do
65
+ it 'equals weight * freshness * confidence' do
66
+ expected = (0.8 * 1.0 * 0.9).round(10)
67
+ expect(stream.effective_weight).to eq(expected)
68
+ end
69
+
70
+ it 'decreases after decay' do
71
+ before = stream.effective_weight
72
+ stream.decay_freshness!
73
+ expect(stream.effective_weight).to be < before
74
+ end
75
+ end
76
+
77
+ describe '#coherence_label' do
78
+ it 'returns :unified for weight 0.9' do
79
+ s = described_class.new(stream_type: :memorial, content: {}, weight: 0.9)
80
+ expect(s.coherence_label).to eq(:unified)
81
+ end
82
+
83
+ it 'returns :chaotic for weight 0.1' do
84
+ s = described_class.new(stream_type: :memorial, content: {}, weight: 0.1)
85
+ expect(s.coherence_label).to eq(:chaotic)
86
+ end
87
+ end
88
+
89
+ describe '#confidence_label' do
90
+ it 'returns :certain for confidence 0.95' do
91
+ s = described_class.new(stream_type: :memorial, content: {}, confidence: 0.95)
92
+ expect(s.confidence_label).to eq(:certain)
93
+ end
94
+
95
+ it 'returns :guessing for confidence 0.1' do
96
+ s = described_class.new(stream_type: :memorial, content: {}, confidence: 0.1)
97
+ expect(s.confidence_label).to eq(:guessing)
98
+ end
99
+ end
100
+
101
+ describe '#to_h' do
102
+ let(:hash) { stream.to_h }
103
+
104
+ it 'includes all expected keys' do
105
+ %i[id stream_type content weight confidence freshness effective_weight
106
+ stale coherence_label confidence_label created_at].each do |key|
107
+ expect(hash).to have_key(key)
108
+ end
109
+ end
110
+
111
+ it 'reflects current freshness' do
112
+ stream.decay_freshness!
113
+ expect(stream.to_h[:freshness]).to be < 1.0
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_synthesis/client'
4
+
5
+ RSpec.describe Legion::Extensions::CognitiveSynthesis::Runners::CognitiveSynthesis do
6
+ let(:client) { Legion::Extensions::CognitiveSynthesis::Client.new }
7
+
8
+ def add_two_streams
9
+ client.add_stream(stream_type: :emotional, content: { mood: :alert }, weight: 0.8, confidence: 0.9)
10
+ client.add_stream(stream_type: :perceptual, content: { threat: :detected }, weight: 0.6, confidence: 0.7)
11
+ end
12
+
13
+ describe '#add_stream' do
14
+ it 'adds a valid stream and returns success' do
15
+ result = client.add_stream(stream_type: :emotional, content: { mood: :calm })
16
+ expect(result[:success]).to be true
17
+ expect(result[:stream_id]).to match(/\A[0-9a-f-]{36}\z/)
18
+ end
19
+
20
+ it 'rejects an invalid stream type' do
21
+ result = client.add_stream(stream_type: :bogus, content: {})
22
+ expect(result[:success]).to be false
23
+ expect(result[:error]).to eq(:invalid_stream_type)
24
+ end
25
+
26
+ it 'accepts all valid stream types' do
27
+ %i[emotional perceptual memorial predictive reasoning social identity motor].each do |type|
28
+ result = client.add_stream(stream_type: type, content: {})
29
+ expect(result[:success]).to be true
30
+ end
31
+ end
32
+
33
+ it 'accepts injected engine kwarg' do
34
+ engine = Legion::Extensions::CognitiveSynthesis::Helpers::SynthesisEngine.new
35
+ result = client.add_stream(stream_type: :reasoning, content: {}, engine: engine)
36
+ expect(result[:success]).to be true
37
+ expect(engine.streams.size).to eq(1)
38
+ end
39
+ end
40
+
41
+ describe '#remove_stream' do
42
+ it 'removes an existing stream' do
43
+ add_result = client.add_stream(stream_type: :emotional, content: {})
44
+ remove_result = client.remove_stream(stream_id: add_result[:stream_id])
45
+ expect(remove_result[:success]).to be true
46
+ end
47
+
48
+ it 'returns not_found for unknown stream' do
49
+ result = client.remove_stream(stream_id: 'nonexistent-id')
50
+ expect(result[:success]).to be false
51
+ expect(result[:error]).to eq(:not_found)
52
+ end
53
+ end
54
+
55
+ describe '#synthesize' do
56
+ it 'returns insufficient_streams when fewer than 2 active streams' do
57
+ client.add_stream(stream_type: :emotional, content: {})
58
+ result = client.synthesize
59
+ expect(result[:success]).to be false
60
+ expect(result[:error]).to eq(:insufficient_streams)
61
+ end
62
+
63
+ it 'succeeds with 2+ active streams' do
64
+ add_two_streams
65
+ result = client.synthesize
66
+ expect(result[:success]).to be true
67
+ expect(result[:synthesis]).to have_key(:id)
68
+ end
69
+
70
+ it 'returns coherence between 0 and 1' do
71
+ add_two_streams
72
+ result = client.synthesize
73
+ expect(result[:synthesis][:coherence]).to be_between(0.0, 1.0)
74
+ end
75
+
76
+ it 'returns novelty = 1.0 for first synthesis' do
77
+ add_two_streams
78
+ result = client.synthesize
79
+ expect(result[:synthesis][:novelty]).to eq(1.0)
80
+ end
81
+
82
+ it 'uses injected engine when provided' do
83
+ engine = Legion::Extensions::CognitiveSynthesis::Helpers::SynthesisEngine.new
84
+ 2.times { engine.add_stream(stream_type: :emotional, content: {}) }
85
+ result = client.synthesize(engine: engine)
86
+ expect(result[:success]).to be true
87
+ end
88
+ end
89
+
90
+ describe '#decay_streams' do
91
+ it 'returns success' do
92
+ result = client.decay_streams
93
+ expect(result[:success]).to be true
94
+ end
95
+
96
+ it 'reports removed count' do
97
+ result = client.decay_streams
98
+ expect(result).to have_key(:streams_removed)
99
+ end
100
+ end
101
+
102
+ describe '#check_conflict' do
103
+ it 'detects conflict between opposing streams' do
104
+ a = client.add_stream(stream_type: :emotional, content: { signal: :danger }, weight: 0.9)
105
+ b = client.add_stream(stream_type: :perceptual, content: { signal: :safe }, weight: 0.1)
106
+ result = client.check_conflict(stream_id_a: a[:stream_id], stream_id_b: b[:stream_id])
107
+ expect(result[:success]).to be true
108
+ expect(result[:conflict]).to be true
109
+ end
110
+
111
+ it 'reports no conflict for similar streams' do
112
+ a = client.add_stream(stream_type: :emotional, content: { value: 1 }, weight: 0.6)
113
+ b = client.add_stream(stream_type: :perceptual, content: { value: 1 }, weight: 0.65)
114
+ result = client.check_conflict(stream_id_a: a[:stream_id], stream_id_b: b[:stream_id])
115
+ expect(result[:conflict]).to be false
116
+ end
117
+
118
+ it 'returns error for missing stream ids' do
119
+ result = client.check_conflict(stream_id_a: 'x', stream_id_b: 'y')
120
+ expect(result[:success]).to be false
121
+ end
122
+ end
123
+
124
+ describe '#dominant_stream' do
125
+ it 'returns error when no streams present' do
126
+ result = client.dominant_stream
127
+ expect(result[:success]).to be false
128
+ expect(result[:error]).to eq(:no_streams)
129
+ end
130
+
131
+ it 'returns stream with highest effective_weight' do
132
+ client.add_stream(stream_type: :emotional, content: {}, weight: 0.2, confidence: 0.2)
133
+ high = client.add_stream(stream_type: :memorial, content: {}, weight: 0.95, confidence: 0.95)
134
+ result = client.dominant_stream
135
+ expect(result[:stream][:id]).to eq(high[:stream_id])
136
+ end
137
+ end
138
+
139
+ describe '#synthesis_history' do
140
+ it 'returns empty list initially' do
141
+ result = client.synthesis_history
142
+ expect(result[:syntheses]).to be_empty
143
+ end
144
+
145
+ it 'returns syntheses after multiple runs' do
146
+ add_two_streams
147
+ 3.times { client.synthesize }
148
+ result = client.synthesis_history(limit: 2)
149
+ expect(result[:count]).to eq(2)
150
+ end
151
+ end
152
+
153
+ describe '#average_coherence' do
154
+ it 'returns 0.0 when no syntheses' do
155
+ result = client.average_coherence
156
+ expect(result[:average_coherence]).to eq(0.0)
157
+ end
158
+
159
+ it 'returns coherence value after syntheses' do
160
+ add_two_streams
161
+ 3.times { client.synthesize }
162
+ result = client.average_coherence
163
+ expect(result[:average_coherence]).to be_between(0.0, 1.0)
164
+ end
165
+ end
166
+
167
+ describe '#status' do
168
+ it 'returns success with stats' do
169
+ result = client.status
170
+ expect(result[:success]).to be true
171
+ expect(result).to have_key(:stream_count)
172
+ expect(result).to have_key(:synthesis_count)
173
+ end
174
+
175
+ it 'reflects added streams' do
176
+ add_two_streams
177
+ result = client.status
178
+ expect(result[:stream_count]).to eq(2)
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ module Legion
6
+ module Logging
7
+ def self.debug(_msg); end
8
+ def self.info(_msg); end
9
+ def self.warn(_msg); end
10
+ def self.error(_msg); end
11
+ end
12
+ end
13
+
14
+ require 'legion/extensions/cognitive_synthesis'
15
+
16
+ RSpec.configure do |config|
17
+ config.example_status_persistence_file_path = '.rspec_status'
18
+ config.disable_monkey_patching!
19
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
20
+ end