blest 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +60 -99
  3. data/lib/blest.rb +811 -143
  4. data/spec/blest_spec.rb +220 -0
  5. metadata +10 -9
@@ -0,0 +1,220 @@
1
+ require 'rspec'
2
+ require 'securerandom'
3
+ require_relative '../lib/blest'
4
+
5
+ RSpec.describe Router do
6
+
7
+ benchmarks = []
8
+
9
+ router = Router.new(timeout: 1000)
10
+ router2 = Router.new(timeout: 10)
11
+ router3 = Router.new
12
+
13
+ testId1 = nil
14
+ testValue1 = nil
15
+ result1 = nil
16
+ error1 = nil
17
+ testId2 = nil
18
+ testValue2 = nil
19
+ result2 = nil
20
+ error2 = nil
21
+ testId3 = nil
22
+ testValue3 = nil
23
+ result3 = nil
24
+ error3 = nil
25
+ testId4 = nil
26
+ testValue4 = nil
27
+ result4 = nil
28
+ error4 = nil
29
+ testId5 = nil
30
+ testValue5 = nil
31
+ result5 = nil
32
+ error5 = nil
33
+ testId6 = nil
34
+ testValue6 = nil
35
+ result6 = nil
36
+ error6 = nil
37
+
38
+ before(:all) do
39
+ router.route('basicRoute') do |body, context|
40
+ { 'route'=> 'basicRoute', 'body' => body, 'context' => context }
41
+ end
42
+
43
+ router.before do |body, context|
44
+ context['test'] = { 'value' => body['testValue'] }
45
+ context['requestTime'] = Time.now
46
+ nil
47
+ end
48
+
49
+ router.after do |_, context|
50
+ complete_time = Time.now
51
+ difference = (complete_time - context['requestTime'])
52
+ benchmarks.push(difference)
53
+ nil
54
+ end
55
+
56
+ router2.route('mergedRoute') do |body, context|
57
+ { 'route' => 'mergedRoute', 'body' => body, 'context' => context }
58
+ end
59
+
60
+ router2.route('timeoutRoute') do |body|
61
+ sleep(0.2)
62
+ { 'testValue' => body['testValue'] }
63
+ end
64
+
65
+ router.merge(router2)
66
+
67
+ router3.route('errorRoute') do |body|
68
+ error = BlestError.new(body['testValue'])
69
+ error.code = "ERROR_#{(body['testValue'].to_f * 10).round}"
70
+ raise error
71
+ end
72
+
73
+ router.namespace('subRoutes', router3)
74
+
75
+ # puts router.routes
76
+
77
+ # Basic route
78
+ testId1 = SecureRandom.uuid
79
+ testValue1 = rand
80
+ result1, error1 = router.handle([[testId1, 'basicRoute', { 'testValue' => testValue1 }]], { 'testValue' => testValue1 })
81
+
82
+ # Merged route
83
+ testId2 = SecureRandom.uuid
84
+ testValue2 = rand
85
+ result2, error2 = router.handle([[testId2, 'mergedRoute', { 'testValue' => testValue2 }]], { 'testValue' => testValue2 })
86
+
87
+ # Error route
88
+ testId3 = SecureRandom.uuid
89
+ testValue3 = rand
90
+ result3, error3 = router.handle([[testId3, 'subRoutes/errorRoute', { 'testValue' => testValue3 }]], { 'testValue' => testValue3 })
91
+
92
+ # Missing route
93
+ testId4 = SecureRandom.uuid
94
+ testValue4 = rand
95
+ result4, error4 = router.handle([[testId4, 'missingRoute', { 'testValue' => testValue4 }]], { 'testValue' => testValue4 })
96
+
97
+ # Timeout route
98
+ testId5 = SecureRandom.uuid
99
+ testValue5 = rand
100
+ result5, error5 = router.handle([[testId5, 'timeoutRoute', { 'testValue' => testValue5 }]], { 'testValue' => testValue5 })
101
+
102
+ # Malformed request
103
+ testId6 = SecureRandom.uuid
104
+ result6, error6 = router.handle([[testId6], {}, [true, 1.25]])
105
+
106
+ end
107
+
108
+ it 'should have class properties' do
109
+ expect(router.is_a?(Router)).to be_truthy
110
+ expect(router.routes.keys.length).to eq(4)
111
+ expect(router).to respond_to(:handle)
112
+ end
113
+
114
+ it 'should have class properties' do
115
+ expect(router).to be_a(Router)
116
+ expect(router.routes.keys.length).to eq(4)
117
+ expect(router).to respond_to(:handle)
118
+ end
119
+
120
+ it 'should process all valid requests' do
121
+ expect(error1).to be_nil
122
+ expect(error2).to be_nil
123
+ expect(error3).to be_nil
124
+ expect(error4).to be_nil
125
+ expect(error5).to be_nil
126
+ end
127
+
128
+ it 'should return matching IDs' do
129
+ expect(result1[0][0]).to eq(testId1)
130
+ expect(result2[0][0]).to eq(testId2)
131
+ expect(result3[0][0]).to eq(testId3)
132
+ expect(result4[0][0]).to eq(testId4)
133
+ expect(result5[0][0]).to eq(testId5)
134
+ end
135
+
136
+ it 'should return matching routes' do
137
+ expect(result1[0][1]).to eq('basicRoute')
138
+ expect(result2[0][1]).to eq('mergedRoute')
139
+ expect(result3[0][1]).to eq('subRoutes/errorRoute')
140
+ expect(result4[0][1]).to eq('missingRoute')
141
+ expect(result5[0][1]).to eq('timeoutRoute')
142
+ end
143
+
144
+ it 'should accept body' do
145
+ expect(result1[0][2]['body']['testValue']).to eq(testValue1)
146
+ expect(result2[0][2]['body']['testValue']).to eq(testValue2)
147
+ end
148
+
149
+ it 'should respect context' do
150
+ expect(result1[0][2]['context']['testValue']).to eq(testValue1)
151
+ expect(result2[0][2]['context']['testValue']).to eq(testValue2)
152
+ end
153
+
154
+ it 'should support middleware' do
155
+ expect(result1[0][2]['context']['test']).to be_nil
156
+ expect(result2[0][2]['context']['test']['value']).to eq(testValue2)
157
+ end
158
+
159
+ it 'should handle errors correctly' do
160
+ expect(result1[0][3]).to be_nil
161
+ expect(result2[0][3]).to be_nil
162
+ expect(result3[0][3]['message']).to eq(testValue3.to_s)
163
+ expect(result3[0][3]['status']).to eq(500)
164
+ expect(result3[0][3]['code']).to eq("ERROR_#{(testValue3 * 10).round}")
165
+ expect(result4[0][3]['message']).to eq('Not Found')
166
+ expect(result4[0][3]['status']).to eq(404)
167
+ end
168
+
169
+ it 'should support timeout setting' do
170
+ expect(result5[0][2]).to be_nil
171
+ expect(result5[0][3]['message']).to eq('Internal Server Error')
172
+ expect(result5[0][3]['status']).to eq(500)
173
+ end
174
+
175
+ it 'should reject malformed requests' do
176
+ expect(error6['message']).not_to be_nil
177
+ end
178
+
179
+ it 'should allow trailing middleware' do
180
+ expect(benchmarks.length).to eq(1)
181
+ end
182
+
183
+ it 'should throw an error for invalid routes' do
184
+ handler = proc {}
185
+ expect { router.route('a', &handler) }.to raise_error(ArgumentError)
186
+ expect { router.route('0abc', &handler) }.to raise_error(ArgumentError)
187
+ expect { router.route('_abc', &handler) }.to raise_error(ArgumentError)
188
+ expect { router.route('-abc', &handler) }.to raise_error(ArgumentError)
189
+ expect { router.route('abc_', &handler) }.to raise_error(ArgumentError)
190
+ expect { router.route('abc-', &handler) }.to raise_error(ArgumentError)
191
+ expect { router.route('abc/0abc', &handler) }.to raise_error(ArgumentError)
192
+ expect { router.route('abc/_abc', &handler) }.to raise_error(ArgumentError)
193
+ expect { router.route('abc/-abc', &handler) }.to raise_error(ArgumentError)
194
+ expect { router.route('abc/', &handler) }.to raise_error(ArgumentError)
195
+ expect { router.route('/abc', &handler) }.to raise_error(ArgumentError)
196
+ expect { router.route('abc//abc', &handler) }.to raise_error(ArgumentError)
197
+ expect { router.route('abc/a/abc', &handler) }.to raise_error(ArgumentError)
198
+ expect { router.route('abc/0abc/abc', &handler) }.to raise_error(ArgumentError)
199
+ expect { router.route('abc/_abc/abc', &handler) }.to raise_error(ArgumentError)
200
+ expect { router.route('abc/-abc/abc', &handler) }.to raise_error(ArgumentError)
201
+ expect { router.route('abc/abc_/abc', &handler) }.to raise_error(ArgumentError)
202
+ expect { router.route('abc/abc-/abc', &handler) }.to raise_error(ArgumentError)
203
+ end
204
+
205
+ end
206
+
207
+
208
+
209
+ RSpec.describe HttpClient do
210
+ client = HttpClient.new('http://localhost:8080', max_batch_size = 25, buffer_delay = 10)
211
+
212
+ it 'should have class properties' do
213
+ expect(client.is_a?(HttpClient)).to be_truthy
214
+ expect(client.url).to eq('http://localhost:8080')
215
+ expect(client.max_batch_size).to eq(25)
216
+ expect(client.buffer_delay).to eq(10)
217
+ expect(client).to respond_to(:request)
218
+ end
219
+
220
+ end
metadata CHANGED
@@ -1,21 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - JHunt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-10 00:00:00.000000000 Z
11
+ date: 2024-10-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The Ruby reference implementation of BLEST (Batch-able, Lightweight,
14
14
  Encrypted State Transfer), an improved communication protocol for web APIs which
15
- leverages JSON, supports request batching and selective returns, and provides a
16
- modern alternative to REST.
15
+ leverages JSON, supports request batching by default, and provides a modern alternative
16
+ to REST.
17
17
  email:
18
- - blest@jhunt.dev
18
+ - hello@jhunt.dev
19
19
  executables: []
20
20
  extensions: []
21
21
  extra_rdoc_files: []
@@ -23,11 +23,12 @@ files:
23
23
  - LICENSE
24
24
  - README.md
25
25
  - lib/blest.rb
26
+ - spec/blest_spec.rb
26
27
  homepage: https://blest.jhunt.dev
27
28
  licenses:
28
29
  - MIT
29
30
  metadata: {}
30
- post_install_message:
31
+ post_install_message:
31
32
  rdoc_options: []
32
33
  require_paths:
33
34
  - lib
@@ -42,8 +43,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
42
43
  - !ruby/object:Gem::Version
43
44
  version: '0'
44
45
  requirements: []
45
- rubygems_version: 3.0.3
46
- signing_key:
46
+ rubygems_version: 3.5.16
47
+ signing_key:
47
48
  specification_version: 4
48
49
  summary: The Ruby reference implementation of BLEST
49
50
  test_files: []