ru.Bee 1.5.4 → 1.6.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.
- checksums.yaml +4 -4
- data/bin/rubee +7 -2
- data/lib/config/base_configuration.rb +25 -7
- data/lib/db/create_addresses.rb +17 -0
- data/lib/package.json +1 -1
- data/lib/rubee/async/fiber_queue.rb +27 -0
- data/lib/rubee/async/thread_pool.rb +32 -34
- data/lib/rubee/autoload.rb +73 -0
- data/lib/rubee/configuration.rb +60 -0
- data/lib/rubee/extensions/hookable.rb +9 -2
- data/lib/rubee/generator.rb +152 -0
- data/lib/rubee/logger.rb +83 -0
- data/lib/rubee/models/sequel_object.rb +1 -2
- data/lib/rubee/router.rb +41 -0
- data/lib/rubee.rb +7 -314
- data/lib/tests/async/thread_async_test.rb +9 -5
- data/lib/tests/{auth_tokenable_test.rb → controllers/auth_tokenable_test.rb} +2 -2
- data/lib/tests/controllers/base_controller_test.rb +23 -0
- data/lib/tests/controllers/hookable_test.rb +220 -0
- data/lib/tests/{rubeeapp_test.rb → controllers/rubeeapp_test.rb} +2 -1
- data/lib/tests/example_models/address.rb +5 -0
- data/lib/tests/example_models/user.rb +1 -0
- data/lib/tests/logger_test.rb +76 -0
- data/lib/tests/{account_model_test.rb → models/account_model_test.rb} +1 -1
- data/lib/tests/{comment_model_test.rb → models/comment_model_test.rb} +13 -1
- data/lib/tests/models/db_objectable_test.rb +21 -0
- data/lib/tests/models/seralizable_test.rb +36 -0
- data/lib/tests/{user_model_test.rb → models/user_model_test.rb} +32 -1
- data/lib/tests/test.db +0 -0
- data/lib/tests/test_helper.rb +19 -2
- data/readme.md +77 -11
- metadata +19 -8
- data/lib/app/views/apples_.erb +0 -1
- data/lib/app/views/s_.erb +0 -1
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class CustomLogger
|
4
|
+
class << self
|
5
|
+
def warn(message:, **options, &block); end
|
6
|
+
|
7
|
+
def info(message:, **options, &block)
|
8
|
+
puts "CUSTOM INFO #{message}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def error(message:, **options, &block); end
|
12
|
+
|
13
|
+
def critical(message:, **options, &block); end
|
14
|
+
|
15
|
+
def debug(object:, **options, &block); end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'Rubee::Logger' do
|
20
|
+
describe 'logger' do
|
21
|
+
it 'exists' do
|
22
|
+
_(Rubee::Logger).wont_be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '.warn' do
|
27
|
+
it 'output message' do
|
28
|
+
output = capture_stdout { Rubee::Logger.warn(message: 'test') }
|
29
|
+
|
30
|
+
assert_includes(output, "WARN test")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.info' do
|
35
|
+
it 'output message' do
|
36
|
+
output = capture_stdout { Rubee::Logger.info(message: 'test') }
|
37
|
+
|
38
|
+
assert_includes(output, "INFO test")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '.error' do
|
43
|
+
it 'output message' do
|
44
|
+
output = capture_stdout { Rubee::Logger.error(message: 'test') }
|
45
|
+
|
46
|
+
assert_includes(output, "ERROR test")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.critical' do
|
51
|
+
it 'output message' do
|
52
|
+
output = capture_stdout { Rubee::Logger.critical(message: 'test') }
|
53
|
+
|
54
|
+
assert_includes(output, "CRITICAL test")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '.debug' do
|
59
|
+
it 'output message' do
|
60
|
+
output = capture_stdout { Rubee::Logger.debug(object: User.new(email: 'ok@ok.com', password: 123)) }
|
61
|
+
|
62
|
+
assert_includes(output, "DEBUG #<User:")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'when custom logger defined in the configuration' do
|
67
|
+
it 'uses custom logger' do
|
68
|
+
Rubee::Configuration.setup(env = :test) { _1.logger = { logger: CustomLogger, env: } }
|
69
|
+
|
70
|
+
output = capture_stdout { Rubee::Logger.info(message: 'test') }
|
71
|
+
assert_includes(output, "CUSTOM INFO test")
|
72
|
+
|
73
|
+
Rubee::Configuration.setup(env = :test) { _1.logger = { env: } }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative 'test_helper'
|
1
|
+
require_relative '../test_helper'
|
2
2
|
|
3
3
|
describe 'Comment model' do
|
4
4
|
describe 'owns_many :users, over: :posts' do
|
@@ -32,4 +32,16 @@ describe 'Comment model' do
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
describe 'method' do
|
37
|
+
it 'updates existing model' do
|
38
|
+
comment = Comment.new(text: 'test 1')
|
39
|
+
comment.save
|
40
|
+
|
41
|
+
comment.text = 'test 2'
|
42
|
+
comment.save
|
43
|
+
|
44
|
+
_(Comment.find(comment.id).text).must_equal('test 2')
|
45
|
+
end
|
46
|
+
end
|
35
47
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class MergBerg
|
4
|
+
include Rubee::DatabaseObjectable
|
5
|
+
attr_accessor :id, :foo, :bar
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'Database Objectable' do
|
9
|
+
describe 'class methods' do
|
10
|
+
it 'pluralizes class names' do
|
11
|
+
_(MergBerg.pluralize_class_name).must_equal('mergbergs')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'retrieves accessor names' do
|
15
|
+
accessors = MergBerg.accessor_names
|
16
|
+
_(accessors).must_include(:id)
|
17
|
+
_(accessors).must_include(:foo)
|
18
|
+
_(accessors).must_include(:bar)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestSerialized
|
4
|
+
include Rubee::Serializable
|
5
|
+
|
6
|
+
attr_accessor :id, :towel_color, :name
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'Serializable Model' do
|
10
|
+
describe 'attributes' do
|
11
|
+
it 'exists and settable' do
|
12
|
+
cerealed = TestSerialized.new(id: 10, towel_color: 'blue', name: 'Ford Prefect')
|
13
|
+
|
14
|
+
_(cerealed.id).must_equal(10)
|
15
|
+
_(cerealed.towel_color).must_equal('blue')
|
16
|
+
_(cerealed.name).must_equal('Ford Prefect')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'does not exist not settable' do
|
20
|
+
_ { TestSerialized.new(blue: 'hello') }.must_raise(NoMethodError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'coverts to' do
|
25
|
+
before do
|
26
|
+
@cerealed = TestSerialized.new(id: 10, towel_color: 'blue', name: 'Ford Prefect')
|
27
|
+
end
|
28
|
+
it 'hash' do
|
29
|
+
_(@cerealed.to_h).must_be_instance_of(Hash)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'json' do
|
33
|
+
_(@cerealed.to_json).must_be_instance_of(String)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative 'test_helper'
|
1
|
+
require_relative '../test_helper'
|
2
2
|
|
3
3
|
describe 'User model' do
|
4
4
|
describe '.create' do
|
@@ -248,4 +248,35 @@ describe 'User model' do
|
|
248
248
|
end
|
249
249
|
end
|
250
250
|
end
|
251
|
+
|
252
|
+
describe 'owns_one' do
|
253
|
+
after do
|
254
|
+
User.destroy_all(cascade: true)
|
255
|
+
end
|
256
|
+
describe 'when there is one associated account' do
|
257
|
+
it 'cannot add more than one address' do
|
258
|
+
skip "This is an idea that can be implemented later"
|
259
|
+
user = User.new(email: 'bleh@example.com', password: '123')
|
260
|
+
user.save
|
261
|
+
|
262
|
+
address = Address.new(user_id: user.id, street: '1234 ble ave', apt: '', city: 'NY', state: 'NY', zip: '555555')
|
263
|
+
address.save
|
264
|
+
|
265
|
+
address_two = Address.new(user_id: user.id, street: '1234 ble ave', apt: '', city: 'NY', state: 'NY',
|
266
|
+
zip: '555555')
|
267
|
+
|
268
|
+
_ { address_two.save }.must_raise(Rubee::OwnsOneError)
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'returns the single address' do
|
272
|
+
user = User.new(email: 'bleh@example.com', password: '123')
|
273
|
+
user.save
|
274
|
+
|
275
|
+
address = Address.new(user_id: user.id, street: '1234 ble ave', apt: '', city: 'NY', state: 'NY', zip: '555555')
|
276
|
+
address.save
|
277
|
+
|
278
|
+
_(user.address.id).must_equal(address.id)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
251
282
|
end
|
data/lib/tests/test.db
CHANGED
Binary file
|
data/lib/tests/test_helper.rb
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
Bundler.require(:test)
|
3
3
|
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start do
|
6
|
+
add_filter %r{^/lib/db/}
|
7
|
+
add_filter %r{^/lib/inits/}
|
8
|
+
add_filter %r{^/lib/tests/}
|
9
|
+
end
|
10
|
+
|
4
11
|
require 'minitest/autorun'
|
5
12
|
require 'rack/test'
|
13
|
+
require 'stringio'
|
14
|
+
|
6
15
|
require_relative '../../lib/rubee'
|
7
16
|
|
8
17
|
Rubee::Autoload.call
|
@@ -17,7 +26,15 @@ def assert_difference(expression, difference = 1)
|
|
17
26
|
after = expression.call
|
18
27
|
actual_diff = after - before
|
19
28
|
|
20
|
-
assert_equal
|
21
|
-
"Expected change of #{difference}, but got #{actual_diff}"
|
29
|
+
assert_equal(difference, actual_diff,
|
30
|
+
"Expected change of #{difference}, but got #{actual_diff}")
|
22
31
|
end
|
23
32
|
|
33
|
+
def capture_stdout
|
34
|
+
old_stdout = $stdout
|
35
|
+
$stdout = StringIO.new
|
36
|
+
yield
|
37
|
+
$stdout.string
|
38
|
+
ensure
|
39
|
+
$stdout = old_stdout
|
40
|
+
end
|
data/readme.md
CHANGED
@@ -18,6 +18,25 @@ Want to get a quick API server up and runing? You can do it for real quick!
|
|
18
18
|
|
19
19
|
All greaet features are yet to come!
|
20
20
|
|
21
|
+
## Content:
|
22
|
+
|
23
|
+
- [Installation](#Installation)
|
24
|
+
- [Run tests](#Run tests)
|
25
|
+
- [Draw contract](#Draw contract)
|
26
|
+
- [Model](#Model)
|
27
|
+
- [Routing](#Routing)
|
28
|
+
- [Database](#Database)
|
29
|
+
- [Views](#Views)
|
30
|
+
- [Hooks](#Hooks)
|
31
|
+
- [JWT based authentification](#JWT based authentification)
|
32
|
+
- [Rubee commands](#Rubee commands)
|
33
|
+
- [Generate commands](#Generate commands)
|
34
|
+
- [Migration commands](#Migration commands)
|
35
|
+
- [Rubee console](#Rubee console)
|
36
|
+
- [Testing](#Testing)
|
37
|
+
- [Background jobs](#Background jobs)
|
38
|
+
- [Logger](#Logger)
|
39
|
+
|
21
40
|
## Features
|
22
41
|
|
23
42
|
- **Lightweight**: A minimal footprint that focuses on serving Ruby applications efficiently.
|
@@ -33,6 +52,8 @@ All greaet features are yet to come!
|
|
33
52
|
- **Hooks** Addlogic before, after and around any action.
|
34
53
|
- **Test** Run all or selected tests witin minitest.
|
35
54
|
- **Asyncable** Add async adapter and pick any popular background job queue enginee
|
55
|
+
- **Console** Start the interactive console and reload it on the fly
|
56
|
+
- **Background jobs** Add async adapter and pick any popular background job queue engine
|
36
57
|
|
37
58
|
## Installation
|
38
59
|
|
@@ -65,12 +86,12 @@ rubee start
|
|
65
86
|
|
66
87
|
5. Open your browser and go to http://localhost:7000
|
67
88
|
|
68
|
-
## Run
|
89
|
+
## Run tests
|
69
90
|
```bash
|
70
91
|
rubee test
|
71
92
|
```
|
72
93
|
|
73
|
-
##
|
94
|
+
## Draw contract
|
74
95
|
1. Add the routes to the routes.rb
|
75
96
|
```ruby
|
76
97
|
Rubee::Router.draw do |router|
|
@@ -88,21 +109,21 @@ rubee test
|
|
88
109
|
end
|
89
110
|
```
|
90
111
|
2. generate the files
|
91
|
-
|
112
|
+
```bash
|
92
113
|
rubee generate get /apples
|
93
|
-
|
94
|
-
|
95
|
-
|
114
|
+
```
|
115
|
+
This will generate the following files
|
116
|
+
```bash
|
96
117
|
./app/controllers/apples_controller.rb # Controller with respective action
|
97
118
|
./app/views/apples_index.erb # ERB view that is rendered by the controller right away
|
98
119
|
./app/models/apple.rb # Model that acts as ORM
|
99
120
|
./db/create_apples.rb # Database migration file needed for creating repsective table
|
100
|
-
|
121
|
+
```
|
101
122
|
|
102
123
|
3. Run the initial db migration
|
103
124
|
```bash
|
104
125
|
rubee db run:all
|
105
|
-
```
|
126
|
+
```
|
106
127
|
|
107
128
|
5. Fill the generated files with the logic you need and run the server again!
|
108
129
|
|
@@ -395,9 +416,9 @@ Example 3:
|
|
395
416
|
Rubee::Router.draw do |router|
|
396
417
|
...
|
397
418
|
# draw the contract
|
398
|
-
router.get "/apples", to: "apples#index",
|
399
|
-
model: {
|
400
|
-
name: 'apple',
|
419
|
+
router.get "/apples", to: "apples#index",
|
420
|
+
model: {
|
421
|
+
name: 'apple',
|
401
422
|
attributes: [
|
402
423
|
{ name: 'id', type: :primary },
|
403
424
|
{ name: 'colour', type: :string },
|
@@ -755,6 +776,51 @@ end
|
|
755
776
|
|
756
777
|
TestAsyncRunnner.new.perform_async(options: {"email"=> "new@new.com", "password"=> "123"})
|
757
778
|
```
|
779
|
+
### Logger
|
780
|
+
|
781
|
+
You can use your own logger by setting it in the /config/base_configuration.rb.
|
782
|
+
|
783
|
+
```ruby
|
784
|
+
# config/base_configuration.rb
|
785
|
+
Rubee::Configuration.setup(env=:development) do |config|
|
786
|
+
config.database_url = { url: "sqlite://db/development.db", env: }
|
787
|
+
config.logger = { logger: MyLogger, env: }
|
788
|
+
end
|
789
|
+
```
|
790
|
+
|
791
|
+
Or you can use the default logger.
|
792
|
+
Let's consider example with welcome controller and around hook:
|
793
|
+
```ruby
|
794
|
+
# app/controllers/welcome_controller.rb
|
795
|
+
class WelcomeController < Rubee::BaseController
|
796
|
+
around :show, ->(&target_method) do
|
797
|
+
start = Time.now
|
798
|
+
Rubee::Logger.warn(message: 'This is a warning message', method: :show, class_name: 'WelcomeController')
|
799
|
+
Rubee::Logger.error(message: 'This is a warning message', class_name: 'WelcomeController')
|
800
|
+
Rubee::Logger.critical(message: 'We are on fire!')
|
801
|
+
target_method.call
|
802
|
+
Rubee::Logger.info(
|
803
|
+
message: "Execution Time: #{Time.now - start} seconds",
|
804
|
+
method: :show,
|
805
|
+
class_name: 'WelcomeController'
|
806
|
+
)
|
807
|
+
Rubee::Logger.debug(object: User.last, method: :show, class_name: 'WelcomeController')
|
808
|
+
end
|
809
|
+
|
810
|
+
def show
|
811
|
+
response_with
|
812
|
+
end
|
813
|
+
end
|
814
|
+
```
|
815
|
+
When you trigger the controller action, the logs will look like this:
|
816
|
+
|
817
|
+
```bash
|
818
|
+
[2025-04-26 12:32:33] WARN [method: show][class_name: WelcomeController] This is a warning message
|
819
|
+
[2025-04-26 12:32:33] ERROR [class_name: WelcomeController] This is a warning message
|
820
|
+
[2025-04-26 12:32:33] CRITICAL We are on fire!
|
821
|
+
[2025-04-26 12:32:33] INFO [method: show][class_name: WelcomeController] Execution Time: 0.000655 seconds
|
822
|
+
[2025-04-26 12:32:33] DEBUG [method: show][class_name: WelcomeController] #<User:0x000000012c5c63e0 @id=4545, @email="ok@op.com", @password="123">
|
823
|
+
```
|
758
824
|
|
759
825
|
### Contributing
|
760
826
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ru.Bee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oleg Saltykov
|
@@ -44,10 +44,8 @@ files:
|
|
44
44
|
- lib/app/controllers/welcome_controller.rb
|
45
45
|
- lib/app/models/user.rb
|
46
46
|
- lib/app/views/app.tsx
|
47
|
-
- lib/app/views/apples_.erb
|
48
47
|
- lib/app/views/index.html
|
49
48
|
- lib/app/views/layout.erb
|
50
|
-
- lib/app/views/s_.erb
|
51
49
|
- lib/app/views/utils/redirectToBackend.tsx
|
52
50
|
- lib/app/views/welcome_header.erb
|
53
51
|
- lib/app/views/welcome_show.erb
|
@@ -56,6 +54,7 @@ files:
|
|
56
54
|
- lib/config/routes.rb
|
57
55
|
- lib/css/app.css
|
58
56
|
- lib/db/create_accounts.rb
|
57
|
+
- lib/db/create_addresses.rb
|
59
58
|
- lib/db/create_comments.rb
|
60
59
|
- lib/db/create_posts.rb
|
61
60
|
- lib/db/create_users.rb
|
@@ -229,30 +228,42 @@ files:
|
|
229
228
|
- lib/package.json
|
230
229
|
- lib/rubee.rb
|
231
230
|
- lib/rubee/async/asyncable.rb
|
231
|
+
- lib/rubee/async/fiber_queue.rb
|
232
232
|
- lib/rubee/async/sidekiq_async.rb
|
233
233
|
- lib/rubee/async/thread_async.rb
|
234
234
|
- lib/rubee/async/thread_pool.rb
|
235
|
+
- lib/rubee/autoload.rb
|
236
|
+
- lib/rubee/configuration.rb
|
235
237
|
- lib/rubee/controllers/base_controller.rb
|
236
238
|
- lib/rubee/controllers/extensions/auth_tokenable.rb
|
237
239
|
- lib/rubee/controllers/extensions/middlewarable.rb
|
238
240
|
- lib/rubee/controllers/middlewares/auth_token_middleware.rb
|
239
241
|
- lib/rubee/extensions/hookable.rb
|
240
242
|
- lib/rubee/extensions/serializable.rb
|
243
|
+
- lib/rubee/generator.rb
|
244
|
+
- lib/rubee/logger.rb
|
241
245
|
- lib/rubee/models/database_objectable.rb
|
242
246
|
- lib/rubee/models/sequel_object.rb
|
243
|
-
- lib/
|
247
|
+
- lib/rubee/router.rb
|
244
248
|
- lib/tests/async/thread_async_test.rb
|
245
|
-
- lib/tests/auth_tokenable_test.rb
|
246
|
-
- lib/tests/
|
249
|
+
- lib/tests/controllers/auth_tokenable_test.rb
|
250
|
+
- lib/tests/controllers/base_controller_test.rb
|
251
|
+
- lib/tests/controllers/hookable_test.rb
|
252
|
+
- lib/tests/controllers/rubeeapp_test.rb
|
247
253
|
- lib/tests/example_models/account.rb
|
254
|
+
- lib/tests/example_models/address.rb
|
248
255
|
- lib/tests/example_models/comment.rb
|
249
256
|
- lib/tests/example_models/post.rb
|
250
257
|
- lib/tests/example_models/user.rb
|
258
|
+
- lib/tests/logger_test.rb
|
259
|
+
- lib/tests/models/account_model_test.rb
|
260
|
+
- lib/tests/models/comment_model_test.rb
|
261
|
+
- lib/tests/models/db_objectable_test.rb
|
262
|
+
- lib/tests/models/seralizable_test.rb
|
263
|
+
- lib/tests/models/user_model_test.rb
|
251
264
|
- lib/tests/rubee_generator_test.rb
|
252
|
-
- lib/tests/rubeeapp_test.rb
|
253
265
|
- lib/tests/test.db
|
254
266
|
- lib/tests/test_helper.rb
|
255
|
-
- lib/tests/user_model_test.rb
|
256
267
|
- readme.md
|
257
268
|
homepage: https://github.com/nucleom42/rubee
|
258
269
|
licenses:
|
data/lib/app/views/apples_.erb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
<h1>apples_ View</h1>
|
data/lib/app/views/s_.erb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
<h1>s_ View</h1>
|