ru.Bee 1.10.1 → 1.11.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e34bf9669d522ca579263e0ea388b8157f443f362991a36b7e76b73b69d49467
4
- data.tar.gz: a58a62af03a502867bbd61316b4983a2114dc2d5a64e5744941c3bcb03776c70
3
+ metadata.gz: b6c1764a41eaa86619270fbaf3077cb5fc55b8d9c6b4f4edac37c2ac7f584fb7
4
+ data.tar.gz: e298000985901fea481a623fd1a08759b6be441251dba2efd78d0120f1ee16f1
5
5
  SHA512:
6
- metadata.gz: a0e8688ef9c4c8ae50552e5db73964ae477b036383eb10cf7194df7edf31b58f7e9fb143689e61f6445750933d9dec9815ffd7e67d0cd0cf684df96b90fd9df3
7
- data.tar.gz: ea6871cf13344b5d235eff69b7fc6df7cd98e9061aeaa593b682b9a35071f73a7dad8a5012778bf55a64b8f1ef49ffdc4ad49cc6bf702cbacfa39410a1f2368c
6
+ metadata.gz: d11f20305783059eef64fa35530e2c6861ff708db527e6ff628b8d735b833d3ec565ce7bbeb4faa9ac0fb98d7868007c8c8728804ecd07adf37a49fc7f665c20
7
+ data.tar.gz: 91b9a63e9bc18c4be04d6e11b097607c01733921b6ba9e33134ea0ee07780fbdf4352083e76f901f741856048732f2a55b8998451a735260aa61da05df80644c
@@ -7,16 +7,6 @@ module Rubee
7
7
 
8
8
  module ClassMethods
9
9
  def before(*methods, handler, **options)
10
- if options[:class_methods]
11
- methods.each do |method|
12
- define_method(method) do |*args, &block|
13
- self.class.send(method, *args, &block)
14
- end
15
-
16
- private(method)
17
- end
18
- end
19
-
20
10
  methods.each do |method|
21
11
  hook = Module.new do
22
12
  define_method(method) do |*args, &block|
@@ -28,21 +18,11 @@ module Rubee
28
18
  end
29
19
  end
30
20
 
31
- prepend(hook)
21
+ options[:class_methods] ? singleton_class.prepend(hook) : prepend(hook)
32
22
  end
33
23
  end
34
24
 
35
25
  def after(*methods, handler, **options)
36
- if options[:class_methods]
37
- methods.each do |method|
38
- define_method(method) do |*args, &block|
39
- self.class.send(method, *args, &block)
40
- end
41
-
42
- private(method)
43
- end
44
- end
45
-
46
26
  methods.each do |method|
47
27
  hook = Module.new do
48
28
  define_method(method) do |*args, &block|
@@ -56,21 +36,11 @@ module Rubee
56
36
  end
57
37
  end
58
38
 
59
- prepend(hook)
39
+ options[:class_methods] ? singleton_class.prepend(hook) : prepend(hook)
60
40
  end
61
41
  end
62
42
 
63
43
  def around(*methods, handler, **options)
64
- if options[:class_methods]
65
- methods.each do |method|
66
- define_method(method) do |*args, &block|
67
- self.class.send(method, *args, &block)
68
- end
69
-
70
- private(method)
71
- end
72
- end
73
-
74
44
  methods.each do |method|
75
45
  hook = Module.new do
76
46
  define_method(method) do |*args, &block|
@@ -93,17 +63,9 @@ module Rubee
93
63
  end
94
64
  end
95
65
 
96
- prepend(hook)
66
+ options[:class_methods] ? singleton_class.prepend(hook) : prepend(hook)
97
67
  end
98
68
  end
99
- end
100
-
101
- module InstanceMethods
102
- private
103
-
104
- def handle_class_method
105
- self.class.send(name, *args, &block)
106
- end
107
69
 
108
70
  def conditions_met?(if_condition = nil, unless_condition = nil)
109
71
  return true if if_condition.nil? && unless_condition.nil?
@@ -128,5 +90,11 @@ module Rubee
128
90
  if_condition_result && !unless_condition_result
129
91
  end
130
92
  end
93
+
94
+ module InstanceMethods
95
+ def conditions_met?(if_condition = nil, unless_condition = nil)
96
+ self.class.conditions_met?(if_condition, unless_condition)
97
+ end
98
+ end
131
99
  end
132
100
  end
@@ -4,7 +4,7 @@ module Rubee
4
4
  using ChargedString
5
5
  using ChargedHash
6
6
 
7
- before :save, :update, :set_timestamps
7
+ before :update, :save, :set_timestamps
8
8
 
9
9
  def destroy(cascade: false, **_options)
10
10
  if cascade
@@ -43,13 +43,15 @@ module Rubee
43
43
  true
44
44
  end
45
45
 
46
- def assign_attributes(args={})
47
- self.class.dataset.columns do |attr|
48
- send("#{attr}=", args[attr.to_sym]) if args[attr.to_sym]
46
+ def assign_attributes(args = {})
47
+ self.class.dataset.columns.each do |attr|
48
+ if args[attr.to_sym]
49
+ send("#{attr}=", args[attr.to_sym])
50
+ end
49
51
  end
50
52
  end
51
53
 
52
- def update(args={})
54
+ def update(args = {})
53
55
  assign_attributes(args)
54
56
  args.merge!(updated:)
55
57
  found_hash = self.class.dataset.where(id:)
data/lib/rubee.rb CHANGED
@@ -16,7 +16,7 @@ module Rubee
16
16
  JS_DIR = File.join(APP_ROOT, LIB, 'js') unless defined?(JS_DIR)
17
17
  CSS_DIR = File.join(APP_ROOT, LIB, 'css') unless defined?(CSS_DIR)
18
18
  ROOT_PATH = File.expand_path(File.join(__dir__, '..')) unless defined?(ROOT_PATH)
19
- VERSION = '1.10.1'
19
+ VERSION = '1.11.1'
20
20
 
21
21
  require_relative 'rubee/router'
22
22
  require_relative 'rubee/logger'
@@ -54,6 +54,11 @@ class TestHookable
54
54
  before :prep_unless_condition, :set_value
55
55
  after :set_unless_condition, :set_glue, unless: :value_red
56
56
 
57
+ # Check class methods
58
+ before :before_print_hello, :print_world, class_methods: true
59
+ after :after_print_hello, :print_world, class_methods: true
60
+ around :around_print_hello, :around_print_world, class_methods: true
61
+
57
62
  def after_around_before; end
58
63
 
59
64
  def before_around_after; end
@@ -82,6 +87,31 @@ class TestHookable
82
87
  value == 'red'
83
88
  end
84
89
 
90
+ class << self
91
+ def before_print_hello
92
+ puts 'hello'
93
+ end
94
+
95
+ def after_print_hello
96
+ puts 'hello'
97
+ end
98
+
99
+ def around_print_hello
100
+ puts 'hello'
101
+ end
102
+
103
+ def print_world
104
+ puts 'world'
105
+ end
106
+
107
+ def around_print_world
108
+ puts 'world1'
109
+ res = yield
110
+ puts 'world2'
111
+ res
112
+ end
113
+ end
114
+
85
115
  private
86
116
 
87
117
  def set_value
@@ -217,4 +247,30 @@ describe 'Hookable Controller' do
217
247
  _(hookable.glue).must_be_nil
218
248
  end
219
249
  end
250
+
251
+ describe 'class methods' do
252
+ it 'calls before print hello hook' do
253
+ output = capture_io do
254
+ TestHookable.before_print_hello
255
+ end.first # capture_io returns [stdout, stderr]
256
+
257
+ _(output).must_equal("world\nhello\n")
258
+ end
259
+
260
+ it 'calls after print hello hook' do
261
+ output = capture_io do
262
+ TestHookable.after_print_hello
263
+ end.first # capture_io returns [stdout, stderr]
264
+
265
+ _(output).must_equal("hello\nworld\n")
266
+ end
267
+
268
+ it 'calls around print hello hook' do
269
+ output = capture_io do
270
+ TestHookable.around_print_hello
271
+ end.first # capture_io returns [stdout, stderr]
272
+
273
+ _(output).must_equal("world1\nhello\nworld2\n")
274
+ end
275
+ end
220
276
  end
@@ -19,14 +19,12 @@ end
19
19
  describe 'Rubee::Logger' do
20
20
  describe 'logger' do
21
21
  it 'exists' do
22
- puts "logger exists"
23
22
  _(Rubee::Logger).wont_be_nil
24
23
  end
25
24
  end
26
25
 
27
26
  describe '.warn' do
28
27
  it 'output message' do
29
- puts "warn output message"
30
28
  output = capture_stdout { Rubee::Logger.warn(message: 'test') }
31
29
 
32
30
  assert_includes(output, "WARN test")
@@ -35,7 +33,6 @@ describe 'Rubee::Logger' do
35
33
 
36
34
  describe '.info' do
37
35
  it 'output message' do
38
- puts "info output message"
39
36
  output = capture_stdout { Rubee::Logger.info(message: 'test') }
40
37
 
41
38
  assert_includes(output, "INFO test")
@@ -52,7 +49,6 @@ describe 'Rubee::Logger' do
52
49
 
53
50
  describe '.critical' do
54
51
  it 'output message' do
55
- puts "critical output message"
56
52
  output = capture_stdout { Rubee::Logger.critical(message: 'test') }
57
53
 
58
54
  assert_includes(output, "CRITICAL test")
@@ -61,7 +57,6 @@ describe 'Rubee::Logger' do
61
57
 
62
58
  describe '.debug' do
63
59
  it 'output message' do
64
- puts "debug output message"
65
60
  output = capture_stdout { Rubee::Logger.debug(object: User.new(email: 'ok@ok.com', password: 123)) }
66
61
 
67
62
  assert_includes(output, "DEBUG #<User:")
@@ -70,7 +65,6 @@ describe 'Rubee::Logger' do
70
65
 
71
66
  describe 'when custom logger defined in the configuration' do
72
67
  it 'uses custom logger' do
73
- puts "CUSTOM INFO test"
74
68
  Rubee::Configuration.setup(env = :test) { _1.logger = { logger: CustomLogger, env: } }
75
69
 
76
70
  output = capture_stdout { Rubee::Logger.info(message: 'test') }
@@ -140,14 +140,14 @@ describe 'User model' do
140
140
  end
141
141
  end
142
142
 
143
- describe 'when udpate existing user with no argumants' do
143
+ describe 'when udpate existing user with no arguments' do
144
144
  it 'update updated field' do
145
145
  user = User.new(email: 'ok-test@test.com', password: '123')
146
146
  user.save
147
147
  updated_field_before_update = user.updated
148
148
 
149
149
  user.update
150
- _(user.updated > updated_field_before_update).must_equal(true)
150
+ _(user.reload.updated > updated_field_before_update).must_equal(true)
151
151
  end
152
152
  end
153
153
  end
data/lib/tests/test.db CHANGED
Binary file
data/readme.md CHANGED
@@ -8,7 +8,8 @@
8
8
 
9
9
  # <img src="lib/images/rubee.svg" alt="RUBEE" height="40"> ... RUBEE
10
10
 
11
- Rubee is a Ruby-based framework designed to streamline the development of modular monolith applications. \
11
+ Rubee is a Ruby-based web framework designed to streamline the development of modular monolith web applications. \
12
+ Under the hood, it leverages the power of Ruby and Rack backed by Puma, offering a clean, efficient, and flexible architecture. \
12
13
  It offers a structured approach to building scalable, maintainable, and React-ready projects, \
13
14
  making it an ideal choice for developers seeking a balance between monolithic simplicity and modular flexibility.
14
15
 
@@ -24,8 +25,8 @@ Want to explore how it built? https://github.com/nucleom42/rubee-site
24
25
  ## Stress tested
25
26
 
26
27
  ```bash
27
- wrk -t4 -c100 -d30s https://rubee.duckdns.org/docs
28
- Running 30s test @ https://rubee.duckdns.org/docs
28
+ wrk -t4 -c100 -d30s https://rubee.dedyn.io/docs
29
+ Running 30s test @ https://rubee.dedyn.io/docs
29
30
  4 threads and 100 connections
30
31
  Thread Stats Avg Stdev Max +/- Stdev
31
32
  Latency 304.95ms 33.22ms 551.86ms 90.38%
@@ -44,6 +45,24 @@ Transfer/sec: 140.07KB
44
45
 
45
46
  This demonstrates RUBEE’s efficient architecture and suitability for lightweight deployments — even on low-power hardware.
46
47
 
48
+ ## Comparison
49
+ Here below is a **short web frameworks comparison** built with Ruby, so you can evaluate your choice with RUBEE.
50
+
51
+ **Disclaimer:**
52
+ The comparison is based on a very generic and subjective information open in the Internet and is not a real benchmark. The comparison is aimed to give you a general idea of the differences between the frameworks and Rubee and not to compare the frameworks directly.
53
+
54
+ | Feature / Framework | **Rubee** | Rails | Sinatra | Hanami | Padrino | Grape |
55
+ |---------------------|-----------|-------|---------|--------|---------|-------|
56
+ | **React readiness** | Built-in React integration (route generator can scaffold React components that fetch data via controllers) | React via webpacker/importmap, but indirect | No direct React support | Can integrate React | Can integrate via JS pipelines | API-focused, no React support |
57
+ | **Routing style** | Explicit, file-based routes with clear JSON/HTML handling | DSL, routes often implicit inside controllers | Explicit DSL, inline in code | Declarative DSL | Rails-like DSL | API-oriented DSL |
58
+ | **Modularity** | Lightweight core, pluggable projects | One project by default, but can be extended with repsecrive gem | Very modular (small DSL) | Designed for modularity | Semi-modular, still Rails-like | Modular (mount APIs) |
59
+ | **Startup / Load speed** | Very fast (minimal boot time, designed for modern Ruby) | Not very fast, especially on large apps | Very fast | Medium (slower than Sinatra, faster than Rails) | Similar to Rails (heavier) | Fast |
60
+ | **Ecosystem** | 🌱 Early-stage, focused on modern simplicity, but easily expandable over bundler | Huge ecosystem, gems, community | Large ecosystem, many gems work | Small, growing | Small, less active | Small, niche |
61
+ | **Learning curve** | Simple, explicit, minimal DSL | Steep (lots of conventions & magic) | Very low (DSL fits in one file) | Medium, more concepts (repositories, entities) | Similar to Rails, easier in parts | Low (API-only) |
62
+ | **Customizability** | High (explicit over implicit, hooks & generators) | Limited without monkey-patching | Very high (you control flow) | High, modular architecture | Medium | High (designed for APIs) |
63
+ | **Target use case** | Modern full-stack apps with React frontends or APIs, may be well suite if you prefer modular monolith over microservices | Large, full-stack, mature apps | Small apps, microservices | Modular apps, DDD | Rails-like but modular | APIs & microservices |
64
+ | **Early adopters support** | Personal early adopters support via fast extending and fixing | Not available | Not known | Not known | Not known | Not known |
65
+
47
66
  ## Content
48
67
 
49
68
  - [Installation](#installation)
@@ -64,16 +83,16 @@ This demonstrates RUBEE’s efficient architecture and suitability for lightweig
64
83
  - [Modular](#modualar-application)
65
84
  - [Logger](#logger)
66
85
 
67
- You can read it on the demo [site](https://rubee.dedyn.io/)
86
+ You can read it on the demo: [site](https://rubee.dedyn.io/)
68
87
 
69
- 🚧 The doc site is on uodate mode now. We are working on it.
70
- Please refer to downbelow documentation.
88
+ 🚧 The doc site is on update mode now. We are working on it.
89
+ Please refer to the documentation shown below.
71
90
 
72
91
  ## Features
73
92
 
74
93
  Lightweight – A minimal footprint focused on serving Ruby applications efficiently.
75
94
  <br>
76
- Modular – A modular approach to application development. Build modular monoliths with ease by attaching \
95
+ Modular – A modular approach to application development. Build modular monolith app with ease by attaching
77
96
  as many subprojects as you need.
78
97
  <br>
79
98
  Contract-driven – Define your API contracts in a simple, declarative way, then generate all the boilerplate you need.
@@ -148,6 +167,8 @@ rubee start_dev --jit=yjit
148
167
  rubee test
149
168
  # or you can specify specific test file
150
169
  rubee test models/user_model_test.rb
170
+ # you can run specicfc line in the test file
171
+ rubee test models/user_model_test.rb --line=12
151
172
  ```
152
173
  [Back to content](#content)
153
174
 
@@ -812,6 +833,29 @@ after log around
812
833
  127.0.0.1 - - [17/Feb/2025:11:42:14 -0500] "GET /apples HTTP/1.1" 401 - 0.0359
813
834
  ```
814
835
 
836
+ Starting from ver 1.11 hooks are able to be pinned to class methods.
837
+
838
+ ```ruby
839
+ class AnyClass
840
+ include Rubee::Hookable
841
+ before :print_world, :print_hello, class_methods: true # you can use class method as a handler
842
+
843
+ class << self
844
+ def print_world
845
+ puts "world!"
846
+ end
847
+
848
+ def print_hello
849
+ puts "hello!"
850
+ end
851
+ end
852
+ end
853
+ ```
854
+ ```bash
855
+ hello!
856
+ world!
857
+ ```
858
+
815
859
  [Back to content](#content)
816
860
 
817
861
  ## JWT based authentification
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.10.1
4
+ version: 1.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleg Saltykov