itsi 0.2.15 → 0.2.17

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 (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Cargo.lock +76 -74
  4. data/crates/itsi_acme/Cargo.toml +1 -1
  5. data/crates/itsi_scheduler/Cargo.toml +1 -1
  6. data/crates/itsi_scheduler/extconf.rb +3 -1
  7. data/crates/itsi_server/Cargo.lock +1 -1
  8. data/crates/itsi_server/Cargo.toml +3 -1
  9. data/crates/itsi_server/extconf.rb +3 -1
  10. data/crates/itsi_server/src/lib.rs +7 -1
  11. data/crates/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +2 -0
  12. data/crates/itsi_server/src/ruby_types/itsi_grpc_call.rs +6 -6
  13. data/crates/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +14 -13
  14. data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +71 -42
  15. data/crates/itsi_server/src/ruby_types/itsi_http_response.rs +151 -152
  16. data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +6 -15
  17. data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +32 -6
  18. data/crates/itsi_server/src/ruby_types/itsi_server.rs +1 -1
  19. data/crates/itsi_server/src/server/binds/listener.rs +49 -8
  20. data/crates/itsi_server/src/server/frame_stream.rs +142 -0
  21. data/crates/itsi_server/src/server/http_message_types.rs +143 -10
  22. data/crates/itsi_server/src/server/io_stream.rs +28 -5
  23. data/crates/itsi_server/src/server/lifecycle_event.rs +1 -1
  24. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +2 -3
  25. data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +8 -10
  26. data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +2 -3
  27. data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +3 -3
  28. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +54 -58
  29. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +6 -9
  30. data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +27 -42
  31. data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +65 -14
  32. data/crates/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +1 -1
  33. data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +8 -11
  34. data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +21 -8
  35. data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +2 -3
  36. data/crates/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +1 -5
  37. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +1 -2
  38. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +13 -6
  39. data/crates/itsi_server/src/server/mod.rs +1 -0
  40. data/crates/itsi_server/src/server/process_worker.rs +5 -5
  41. data/crates/itsi_server/src/server/serve_strategy/acceptor.rs +100 -0
  42. data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +87 -31
  43. data/crates/itsi_server/src/server/serve_strategy/mod.rs +1 -0
  44. data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +166 -206
  45. data/crates/itsi_server/src/server/signal.rs +37 -9
  46. data/crates/itsi_server/src/server/thread_worker.rs +92 -70
  47. data/crates/itsi_server/src/services/itsi_http_service.rs +67 -62
  48. data/crates/itsi_server/src/services/mime_types.rs +185 -183
  49. data/crates/itsi_server/src/services/rate_limiter.rs +16 -34
  50. data/crates/itsi_server/src/services/static_file_server.rs +35 -60
  51. data/docs/benchmark-dashboard/.gitignore +27 -0
  52. data/docs/benchmark-dashboard/app/api/benchmarks/route.ts +22 -0
  53. data/docs/benchmark-dashboard/app/globals.css +94 -0
  54. data/docs/benchmark-dashboard/app/layout.tsx +20 -0
  55. data/docs/benchmark-dashboard/app/page.tsx +252 -0
  56. data/docs/benchmark-dashboard/components/benchmark-dashboard.tsx +1663 -0
  57. data/docs/benchmark-dashboard/components/theme-provider.tsx +11 -0
  58. data/docs/benchmark-dashboard/components/ui/accordion.tsx +58 -0
  59. data/docs/benchmark-dashboard/components/ui/alert-dialog.tsx +141 -0
  60. data/docs/benchmark-dashboard/components/ui/alert.tsx +59 -0
  61. data/docs/benchmark-dashboard/components/ui/aspect-ratio.tsx +7 -0
  62. data/docs/benchmark-dashboard/components/ui/avatar.tsx +50 -0
  63. data/docs/benchmark-dashboard/components/ui/badge.tsx +36 -0
  64. data/docs/benchmark-dashboard/components/ui/breadcrumb.tsx +115 -0
  65. data/docs/benchmark-dashboard/components/ui/button.tsx +56 -0
  66. data/docs/benchmark-dashboard/components/ui/calendar.tsx +66 -0
  67. data/docs/benchmark-dashboard/components/ui/card.tsx +79 -0
  68. data/docs/benchmark-dashboard/components/ui/carousel.tsx +262 -0
  69. data/docs/benchmark-dashboard/components/ui/chart.tsx +365 -0
  70. data/docs/benchmark-dashboard/components/ui/checkbox.tsx +30 -0
  71. data/docs/benchmark-dashboard/components/ui/collapsible.tsx +11 -0
  72. data/docs/benchmark-dashboard/components/ui/command.tsx +153 -0
  73. data/docs/benchmark-dashboard/components/ui/context-menu.tsx +200 -0
  74. data/docs/benchmark-dashboard/components/ui/dialog.tsx +122 -0
  75. data/docs/benchmark-dashboard/components/ui/drawer.tsx +118 -0
  76. data/docs/benchmark-dashboard/components/ui/dropdown-menu.tsx +200 -0
  77. data/docs/benchmark-dashboard/components/ui/form.tsx +178 -0
  78. data/docs/benchmark-dashboard/components/ui/hover-card.tsx +29 -0
  79. data/docs/benchmark-dashboard/components/ui/input-otp.tsx +71 -0
  80. data/docs/benchmark-dashboard/components/ui/input.tsx +22 -0
  81. data/docs/benchmark-dashboard/components/ui/label.tsx +26 -0
  82. data/docs/benchmark-dashboard/components/ui/loading-spinner.tsx +12 -0
  83. data/docs/benchmark-dashboard/components/ui/menubar.tsx +236 -0
  84. data/docs/benchmark-dashboard/components/ui/navigation-menu.tsx +128 -0
  85. data/docs/benchmark-dashboard/components/ui/pagination.tsx +117 -0
  86. data/docs/benchmark-dashboard/components/ui/popover.tsx +31 -0
  87. data/docs/benchmark-dashboard/components/ui/progress.tsx +28 -0
  88. data/docs/benchmark-dashboard/components/ui/radio-group.tsx +44 -0
  89. data/docs/benchmark-dashboard/components/ui/resizable.tsx +45 -0
  90. data/docs/benchmark-dashboard/components/ui/scroll-area.tsx +48 -0
  91. data/docs/benchmark-dashboard/components/ui/select.tsx +160 -0
  92. data/docs/benchmark-dashboard/components/ui/separator.tsx +31 -0
  93. data/docs/benchmark-dashboard/components/ui/sheet.tsx +140 -0
  94. data/docs/benchmark-dashboard/components/ui/sidebar.tsx +763 -0
  95. data/docs/benchmark-dashboard/components/ui/skeleton.tsx +15 -0
  96. data/docs/benchmark-dashboard/components/ui/slider.tsx +28 -0
  97. data/docs/benchmark-dashboard/components/ui/sonner.tsx +31 -0
  98. data/docs/benchmark-dashboard/components/ui/switch.tsx +29 -0
  99. data/docs/benchmark-dashboard/components/ui/table.tsx +117 -0
  100. data/docs/benchmark-dashboard/components/ui/tabs.tsx +55 -0
  101. data/docs/benchmark-dashboard/components/ui/textarea.tsx +22 -0
  102. data/docs/benchmark-dashboard/components/ui/toast.tsx +129 -0
  103. data/docs/benchmark-dashboard/components/ui/toaster.tsx +35 -0
  104. data/docs/benchmark-dashboard/components/ui/toggle-group.tsx +61 -0
  105. data/docs/benchmark-dashboard/components/ui/toggle.tsx +45 -0
  106. data/docs/benchmark-dashboard/components/ui/tooltip.tsx +30 -0
  107. data/docs/benchmark-dashboard/components/ui/use-mobile.tsx +19 -0
  108. data/docs/benchmark-dashboard/components/ui/use-toast.ts +194 -0
  109. data/docs/benchmark-dashboard/components.json +21 -0
  110. data/docs/benchmark-dashboard/dist/benchmark-dashboard.css +1 -0
  111. data/docs/benchmark-dashboard/dist/benchmark-dashboard.iife.js +211 -0
  112. data/docs/benchmark-dashboard/dist/placeholder-logo.png +0 -0
  113. data/docs/benchmark-dashboard/dist/placeholder-logo.svg +1 -0
  114. data/docs/benchmark-dashboard/dist/placeholder-user.jpg +0 -0
  115. data/docs/benchmark-dashboard/dist/placeholder.jpg +0 -0
  116. data/docs/benchmark-dashboard/dist/placeholder.svg +1 -0
  117. data/docs/benchmark-dashboard/embed.tsx +13 -0
  118. data/docs/benchmark-dashboard/hooks/use-mobile.tsx +19 -0
  119. data/docs/benchmark-dashboard/hooks/use-toast.ts +194 -0
  120. data/docs/benchmark-dashboard/lib/benchmark-utils.ts +54 -0
  121. data/docs/benchmark-dashboard/lib/utils.ts +6 -0
  122. data/docs/benchmark-dashboard/next.config.mjs +14 -0
  123. data/docs/benchmark-dashboard/package-lock.json +5859 -0
  124. data/docs/benchmark-dashboard/package.json +72 -0
  125. data/docs/benchmark-dashboard/pnpm-lock.yaml +5 -0
  126. data/docs/benchmark-dashboard/postcss.config.mjs +8 -0
  127. data/docs/benchmark-dashboard/styles/globals.css +94 -0
  128. data/docs/benchmark-dashboard/tailwind.config.ts +96 -0
  129. data/docs/benchmark-dashboard/tsconfig.json +27 -0
  130. data/docs/benchmark-dashboard/vite.config.ts +24 -0
  131. data/docs/build.rb +52 -0
  132. data/docs/content/benchmarks/index.md +96 -0
  133. data/docs/content/features/_index.md +1 -1
  134. data/docs/content/getting_started/_index.md +76 -46
  135. data/docs/hugo.yaml +3 -0
  136. data/docs/static/results.json +1 -0
  137. data/docs/static/scripts/benchmark-dashboard.iife.js +211 -0
  138. data/docs/static/styles/benchmark-dashboard.css +1 -0
  139. data/examples/rails_with_static_assets/Gemfile.lock +1 -1
  140. data/examples/rails_with_static_assets/Itsi.rb +4 -1
  141. data/gems/scheduler/Cargo.lock +15 -15
  142. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  143. data/gems/server/Cargo.lock +75 -73
  144. data/gems/server/exe/itsi +6 -1
  145. data/gems/server/lib/itsi/http_request.rb +31 -39
  146. data/gems/server/lib/itsi/http_response.rb +5 -0
  147. data/gems/server/lib/itsi/rack_env_pool.rb +59 -0
  148. data/gems/server/lib/itsi/server/config/config_helpers.rb +1 -2
  149. data/gems/server/lib/itsi/server/config/dsl.rb +5 -4
  150. data/gems/server/lib/itsi/server/config/middleware/etag.md +3 -7
  151. data/gems/server/lib/itsi/server/config/middleware/etag.rb +2 -4
  152. data/gems/server/lib/itsi/server/config/middleware/proxy.rb +1 -1
  153. data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +2 -2
  154. data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +6 -2
  155. data/gems/server/lib/itsi/server/config/options/include.rb +5 -2
  156. data/gems/server/lib/itsi/server/config/options/listen_backlog.rb +1 -1
  157. data/gems/server/lib/itsi/server/config/options/pipeline_flush.md +16 -0
  158. data/gems/server/lib/itsi/server/config/options/pipeline_flush.rb +19 -0
  159. data/gems/server/lib/itsi/server/config/options/send_buffer_size.md +15 -0
  160. data/gems/server/lib/itsi/server/config/options/send_buffer_size.rb +19 -0
  161. data/gems/server/lib/itsi/server/config/options/writev.md +25 -0
  162. data/gems/server/lib/itsi/server/config/options/writev.rb +19 -0
  163. data/gems/server/lib/itsi/server/config.rb +43 -31
  164. data/gems/server/lib/itsi/server/default_config/Itsi.rb +1 -4
  165. data/gems/server/lib/itsi/server/grpc/grpc_call.rb +2 -0
  166. data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +2 -2
  167. data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -1
  168. data/gems/server/lib/itsi/server/rack_interface.rb +17 -12
  169. data/gems/server/lib/itsi/server/route_tester.rb +1 -1
  170. data/gems/server/lib/itsi/server/scheduler_interface.rb +2 -0
  171. data/gems/server/lib/itsi/server/version.rb +1 -1
  172. data/gems/server/lib/itsi/server.rb +1 -0
  173. data/gems/server/lib/ruby_lsp/itsi/addon.rb +12 -13
  174. data/gems/server/test/helpers/test_helper.rb +12 -13
  175. data/gems/server/test/middleware/etag.rb +3 -3
  176. data/gems/server/test/middleware/grpc/grpc.rb +13 -14
  177. data/gems/server/test/middleware/grpc/test_service_impl.rb +3 -3
  178. data/gems/server/test/middleware/proxy.rb +262 -268
  179. data/gems/server/test/options/ruby_thread_request_backlog_size.rb +2 -3
  180. data/lib/itsi/version.rb +1 -1
  181. metadata +99 -6
  182. data/tasks.txt +0 -27
@@ -5,8 +5,8 @@ require "itsi/server"
5
5
 
6
6
  module RubyLsp
7
7
  module Itsi
8
- class Addon < ::RubyLsp::Addon
9
- def activate(global_state, message_queue)
8
+ class Addon < ::RubyLsp::Addon # rubocop:disable Style/Documentation
9
+ def activate(_global_state, message_queue)
10
10
  @message_queue = message_queue
11
11
  end
12
12
 
@@ -20,33 +20,34 @@ module RubyLsp
20
20
  "0.1.0"
21
21
  end
22
22
 
23
-
24
23
  def create_completion_listener(response_builder, node_context, dispatcher, uri)
25
- return unless uri.to_s.end_with?("Itsi.rb")
24
+ return unless uri.to_s =~ /itsi.rb$/i
25
+
26
26
  @in_itsi_file = true
27
27
  CompletionListener.new(response_builder, node_context, dispatcher, uri)
28
28
  end
29
29
 
30
30
  def create_hover_listener(response_builder, node_context, dispatcher)
31
31
  hl = dispatcher.listeners[:on_call_node_enter].find { |c| c.is_a?(RubyLsp::Listeners::Hover) }
32
- return unless hl.instance_variable_get("@path").to_s.end_with?("Itsi.rb")
32
+ return unless hl.instance_variable_get("@path").to_s =~ /itsi.rb$/i
33
+
33
34
  HoverListener.new(response_builder, node_context, dispatcher)
34
35
  end
35
36
  end
36
37
 
37
- class HoverListener
38
+ class HoverListener # rubocop:disable Style/Documentation
38
39
  def initialize(response_builder, node_context, dispatcher)
39
40
  @response_builder = response_builder
40
41
  @node_context = node_context
41
42
  @dispatcher = dispatcher
42
43
 
43
- @options_by_name = ::Itsi::Server::Config::Option.subclasses.group_by(&:option_name).map{|k,v| [k,v.first]}.to_h
44
- @middlewares_by_name = ::Itsi::Server::Config::Middleware.subclasses.group_by(&:middleware_name).map{|k,v| [k,v.first]}.to_h
44
+ @options_by_name = ::Itsi::Server::Config::Option.subclasses.group_by(&:option_name).transform_values(&:first)
45
+ @middlewares_by_name = ::Itsi::Server::Config::Middleware.subclasses.group_by(&:middleware_name).transform_values(&:first)
45
46
  # Register for call nodes for hover events
46
47
  dispatcher.register(self, :on_call_node_enter)
47
48
  end
48
49
 
49
- def on_call_node_enter(node)
50
+ def on_call_node_enter(node) # rubocop:disable Metrics/MethodLength
50
51
  if (matched_class = @options_by_name[node.message.to_sym])
51
52
  @response_builder.push(
52
53
  matched_class.documentation,
@@ -61,7 +62,7 @@ module RubyLsp
61
62
  end
62
63
  end
63
64
 
64
- class CompletionListener
65
+ class CompletionListener # rubocop:disable Style/Documentation
65
66
  def initialize(response_builder, node_context, dispatcher, uri)
66
67
  @response_builder = response_builder
67
68
  @node_context = node_context
@@ -74,7 +75,7 @@ module RubyLsp
74
75
  dispatcher.register(self, :completion_item_resolve)
75
76
  end
76
77
 
77
- def on_call_node_enter(node)
78
+ def on_call_node_enter(node) # rubocop:disable Metrics/AbcSize
78
79
  # Only handle method calls that are being typed (i.e. no arguments yet)
79
80
  return unless node.arguments.nil?
80
81
 
@@ -122,8 +123,6 @@ module RubyLsp
122
123
  end
123
124
  end
124
125
  end
125
-
126
-
127
126
  end
128
127
  end
129
128
  end
@@ -25,17 +25,10 @@ def free_bind(protocol = "http", unix_socket: false)
25
25
  end
26
26
  end
27
27
 
28
- def server(app: nil, app_with_lint: nil, protocol: "http", bind: free_bind(protocol), itsi_rb: nil, cleanup: true,
29
- timeout: 5, &blk)
28
+ def server(
29
+ app: nil, app_with_lint: nil, protocol: "http", bind: free_bind(protocol), itsi_rb: nil, cleanup: true,
30
+ &blk)
30
31
  app ||= Rack::Lint.new(app_with_lint) if app_with_lint
31
- itsi_rb ||= lambda do
32
- # Inline Itsi.rb
33
- bind bind
34
- workers 1
35
- threads 1
36
- log_level :warn
37
- run app if app
38
- end
39
32
 
40
33
  cli_params = {}
41
34
  cli_params[:binds] = [bind] if bind
@@ -46,13 +39,18 @@ def server(app: nil, app_with_lint: nil, protocol: "http", bind: free_bind(proto
46
39
  sync.push(true)
47
40
  end
48
41
 
49
- Itsi::Server.start_in_background_thread(cli_params, &itsi_rb)
42
+ Itsi::Server.start_in_background_thread(cli_params) do
43
+ bind bind
44
+ workers 1
45
+ threads 1
46
+ log_level :warn
47
+ run app if app
48
+ instance_exec(&itsi_rb) if itsi_rb
49
+ end
50
50
 
51
51
  sync.pop
52
52
  uri = URI(bind)
53
- # Timeout.timeout(timeout) do
54
53
  RequestContext.new(uri, self).instance_exec(uri, &blk)
55
- # end
56
54
  rescue StandardError => e
57
55
  puts e
58
56
  # puts e.message
@@ -119,6 +117,7 @@ class RequestContext
119
117
  def patch(path, data = "", headers = {})
120
118
  request = Net::HTTP::Patch.new(uri_for(path))
121
119
  request.body = data
120
+ headers.each { |k, v| request[k] = v }
122
121
  client.request(request)
123
122
  end
124
123
 
@@ -4,7 +4,7 @@ class TestETag < Minitest::Test
4
4
  def test_strong_etag_added
5
5
  server(
6
6
  itsi_rb: lambda do
7
- etag type: "strong", algorithm: "sha256", min_body_size: 0, handle_if_none_match: false
7
+ etag type: "strong", algorithm: "sha256", min_body_size: 0
8
8
  get("/foo") { |r| r.ok "etag-body" }
9
9
  end
10
10
  ) do
@@ -17,7 +17,7 @@ class TestETag < Minitest::Test
17
17
  def test_weak_etag_added_with_md5
18
18
  server(
19
19
  itsi_rb: lambda do
20
- etag type: "weak", algorithm: "md5", min_body_size: 0, handle_if_none_match: false
20
+ etag type: "weak", algorithm: "md5", min_body_size: 0
21
21
  get("/foo") { |r| r.ok "etag-weak-md5" }
22
22
  end
23
23
  ) do
@@ -42,7 +42,7 @@ class TestETag < Minitest::Test
42
42
  body = "etag-content"
43
43
  server(
44
44
  itsi_rb: lambda do
45
- etag type: "strong", min_body_size: 0, handle_if_none_match: true
45
+ etag type: "strong", min_body_size: 0
46
46
  get("/foo") { |r| r.ok body }
47
47
  end
48
48
  ) do
@@ -5,14 +5,13 @@ class TestGrpc < Minitest::Test
5
5
  Stub = Test::TestService::Stub
6
6
 
7
7
  def new_stub(uri)
8
- address = uri.to_s[/\/\/(.*)/,1] # e.g. "127.0.0.1:12345"
8
+ address = uri.to_s[%r{//(.*)}, 1] # e.g. "127.0.0.1:12345"
9
9
  channel = GRPC::Core::Channel.new(address,
10
- {}, # channel_args hash
11
- :this_channel_is_insecure,
12
- )
10
+ {}, # channel_args hash
11
+ :this_channel_is_insecure)
13
12
  stub = Stub.new(nil,
14
- nil,
15
- channel_override: channel)
13
+ nil,
14
+ channel_override: channel)
16
15
  end
17
16
 
18
17
  def test_unary_echo
@@ -46,7 +45,7 @@ class TestGrpc < Minitest::Test
46
45
  req = Test::EchoRequest.new(message: "xy")
47
46
  # expect two StreamResponse frames, one per character
48
47
  chars = stub.server_stream(req).map(&:messages).flatten
49
- assert_equal ["x", "y"], chars
48
+ assert_equal %w[x y], chars
50
49
  end
51
50
  end
52
51
 
@@ -58,7 +57,7 @@ class TestGrpc < Minitest::Test
58
57
  inputs = %w[test1 test2].map { |m| Test::EchoRequest.new(message: m) }
59
58
  # each response uppercases its incoming message
60
59
  results = stub.bidi_stream(inputs.each).map(&:message)
61
- assert_equal ["TEST1", "TEST2"], results
60
+ assert_equal %w[TEST1 TEST2], results
62
61
  end
63
62
  end
64
63
 
@@ -82,7 +81,6 @@ class TestGrpc < Minitest::Test
82
81
  end
83
82
  end
84
83
 
85
-
86
84
  def test_unary_echo_json
87
85
  server(itsi_rb: lambda do
88
86
  grpc TestServiceImpl.new
@@ -99,7 +97,7 @@ class TestGrpc < Minitest::Test
99
97
  server(itsi_rb: lambda do
100
98
  grpc TestServiceImpl.new
101
99
  end) do
102
- input = [{"message" => "a"}, {"message" => "b"}, {"message" => "c"}]
100
+ input = [{ "message" => "a" }, { "message" => "b" }, { "message" => "c" }]
103
101
  res = post("test.TestService/ClientStream", input.to_json, { "Content-Type" => "application/json" })
104
102
  json = JSON.parse(res.body)
105
103
  assert_equal 200, res.code.to_i
@@ -117,7 +115,7 @@ class TestGrpc < Minitest::Test
117
115
  # service streams back one JSON object per character
118
116
  messages = arr.flat_map { |frame| frame["messages"] }
119
117
  assert_equal 200, res.code.to_i
120
- assert_equal ["x","y"], messages
118
+ assert_equal %w[x y], messages
121
119
  end
122
120
  end
123
121
 
@@ -125,13 +123,13 @@ class TestGrpc < Minitest::Test
125
123
  server(itsi_rb: lambda do
126
124
  grpc TestServiceImpl.new
127
125
  end) do
128
- inputs = [{"message":"foo"}, {"message":"Bar"}]
126
+ inputs = [{ "message": "foo" }, { "message": "Bar" }]
129
127
  res = post("test.TestService/BidiStream", inputs.to_json, { "Content-Type" => "application/json" })
130
128
  arr = JSON.parse(res.body)
131
129
  # bidi uppercases each incoming message
132
130
  results = arr.map { |frame| frame["message"] }
133
131
  assert_equal 200, res.code.to_i
134
- assert_equal ["FOO","BAR"], results
132
+ assert_equal %w[FOO BAR], results
135
133
  end
136
134
  end
137
135
 
@@ -145,7 +143,8 @@ class TestGrpc < Minitest::Test
145
143
  assert_nil json1["messages"]
146
144
 
147
145
  # empty server-stream
148
- res2 = post("test.TestService/ServerStream", { "message" => "" }.to_json, { "Content-Type" => "application/json" })
146
+ res2 = post("test.TestService/ServerStream", { "message" => "" }.to_json,
147
+ { "Content-Type" => "application/json" })
149
148
  arr2 = JSON.parse(res2.body)
150
149
  assert arr2.empty?
151
150
 
@@ -1,12 +1,12 @@
1
- require_relative 'test_service_services_pb' # generated by grpc_tools_ruby_protoc
1
+ require_relative "test_service_services_pb" # generated by grpc_tools_ruby_protoc
2
2
 
3
3
  class TestServiceImpl < Test::TestService::Service
4
4
  def unary_echo(req, _unused_call)
5
5
  Test::EchoResponse.new(message: req.message)
6
6
  end
7
7
 
8
- def client_stream(stream, _call)
9
- msgs = stream.map(&:message)
8
+ def client_stream(call)
9
+ msgs = call.each_remote_read.map(&:message)
10
10
  Test::StreamResponse.new(messages: msgs)
11
11
  end
12
12