ruact 0.0.10 → 0.0.12

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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +123 -48
  3. data/CONTRIBUTING.md +233 -0
  4. data/README.md +16 -6
  5. data/RELEASING.md +125 -139
  6. data/lib/ruact/packaging.rb +68 -0
  7. data/lib/ruact/version.rb +1 -1
  8. data/vendor/javascript/vite-plugin-ruact/flight-client.test.mjs +321 -0
  9. data/vendor/javascript/vite-plugin-ruact/package-lock.json +11 -0
  10. data/vendor/javascript/vite-plugin-ruact/package.json +1 -0
  11. data/vendor/javascript/vite-plugin-ruact/runtime/flight-client.js +14 -3
  12. metadata +6 -107
  13. data/.codecov.yml +0 -31
  14. data/.github/workflows/ci.yml +0 -284
  15. data/.github/workflows/server-functions-bench.yml +0 -54
  16. data/.rubocop.yml +0 -107
  17. data/.rubocop_todo.yml +0 -63
  18. data/Rakefile +0 -10
  19. data/bench/server_functions_dispatch_bench.rb +0 -276
  20. data/bench/server_functions_dispatch_bench.results.md +0 -150
  21. data/docs/internal/README.md +0 -9
  22. data/docs/internal/decisions/server-functions-api.md +0 -2236
  23. data/spec/benchmarks/baseline.json +0 -1
  24. data/spec/benchmarks/render_pipeline_benchmark_spec.rb +0 -92
  25. data/spec/fixtures/flight/README.md +0 -136
  26. data/spec/fixtures/flight/array.txt +0 -1
  27. data/spec/fixtures/flight/as_json_object.txt +0 -2
  28. data/spec/fixtures/flight/bigint.txt +0 -1
  29. data/spec/fixtures/flight/boolean_false.txt +0 -1
  30. data/spec/fixtures/flight/boolean_true.txt +0 -1
  31. data/spec/fixtures/flight/client_component_with_props.txt +0 -2
  32. data/spec/fixtures/flight/client_reference.txt +0 -2
  33. data/spec/fixtures/flight/hash.txt +0 -1
  34. data/spec/fixtures/flight/infinity.txt +0 -1
  35. data/spec/fixtures/flight/nan.txt +0 -1
  36. data/spec/fixtures/flight/negative_infinity.txt +0 -1
  37. data/spec/fixtures/flight/nil.txt +0 -1
  38. data/spec/fixtures/flight/number_float.txt +0 -1
  39. data/spec/fixtures/flight/number_integer.txt +0 -1
  40. data/spec/fixtures/flight/react_element_no_props.txt +0 -1
  41. data/spec/fixtures/flight/redirect_row.txt +0 -1
  42. data/spec/fixtures/flight/serializable_object.txt +0 -2
  43. data/spec/fixtures/flight/string_basic.txt +0 -1
  44. data/spec/fixtures/flight/string_dollar_escape.txt +0 -1
  45. data/spec/fixtures/flight/undefined.txt +0 -1
  46. data/spec/fixtures/readme/children-error.html.erb +0 -3
  47. data/spec/fixtures/readme/children-error.txt +0 -1
  48. data/spec/fixtures/story_7_9_views/controller_request_spec_support/demo/show.html.erb +0 -3
  49. data/spec/fixtures/story_7_9_views/controller_request_spec_support/errors_demo/new.html.erb +0 -3
  50. data/spec/fixtures/story_7_9_views/controller_request_spec_support/exploding_layout_demo/show.html.erb +0 -3
  51. data/spec/fixtures/story_7_9_views/controller_request_spec_support/ghost_layout_demo/show.html.erb +0 -3
  52. data/spec/fixtures/story_7_9_views/controller_request_spec_support/layout_demo/show.html.erb +0 -3
  53. data/spec/fixtures/story_7_9_views/controller_request_spec_support/rootless_layout_demo/show.html.erb +0 -3
  54. data/spec/fixtures/story_7_9_views/controller_request_spec_support/unwired_layout_demo/show.html.erb +0 -3
  55. data/spec/fixtures/story_7_9_views/layouts/bare_host.html.erb +0 -16
  56. data/spec/fixtures/story_7_9_views/layouts/exploding_host.html.erb +0 -24
  57. data/spec/fixtures/story_7_9_views/layouts/rootless_host.html.erb +0 -15
  58. data/spec/fixtures/story_7_9_views/layouts/ruact_host.html.erb +0 -17
  59. data/spec/readme_demo_message_spec.rb +0 -67
  60. data/spec/readme_spec.rb +0 -282
  61. data/spec/ruact/client_manifest_spec.rb +0 -270
  62. data/spec/ruact/component_contract_spec.rb +0 -119
  63. data/spec/ruact/configuration_spec.rb +0 -518
  64. data/spec/ruact/controller_request_spec.rb +0 -671
  65. data/spec/ruact/controller_spec.rb +0 -343
  66. data/spec/ruact/doctor_spec.rb +0 -769
  67. data/spec/ruact/erb_preprocessor_hook_spec.rb +0 -55
  68. data/spec/ruact/erb_preprocessor_spec.rb +0 -361
  69. data/spec/ruact/errors_spec.rb +0 -93
  70. data/spec/ruact/flight/renderer_spec.rb +0 -133
  71. data/spec/ruact/flight/serializer_spec.rb +0 -494
  72. data/spec/ruact/html_converter_spec.rb +0 -375
  73. data/spec/ruact/install_generator_spec.rb +0 -1549
  74. data/spec/ruact/layout_source_spec.rb +0 -108
  75. data/spec/ruact/manifest_resolver_spec.rb +0 -174
  76. data/spec/ruact/query_request_spec.rb +0 -706
  77. data/spec/ruact/query_spec.rb +0 -105
  78. data/spec/ruact/railtie_spec.rb +0 -155
  79. data/spec/ruact/render_context_spec.rb +0 -58
  80. data/spec/ruact/render_pipeline_concurrency_spec.rb +0 -78
  81. data/spec/ruact/render_pipeline_spec.rb +0 -928
  82. data/spec/ruact/scaffold_generator_spec.rb +0 -1849
  83. data/spec/ruact/serializable_spec.rb +0 -179
  84. data/spec/ruact/server_bucket_request_spec.rb +0 -785
  85. data/spec/ruact/server_function_name_spec.rb +0 -53
  86. data/spec/ruact/server_functions/backtrace_cleaner_spec.rb +0 -63
  87. data/spec/ruact/server_functions/bucket_two_payload_spec.rb +0 -200
  88. data/spec/ruact/server_functions/codegen_spec.rb +0 -397
  89. data/spec/ruact/server_functions/error_payload_spec.rb +0 -222
  90. data/spec/ruact/server_functions/error_suggestion_spec.rb +0 -79
  91. data/spec/ruact/server_functions/introspection_spec.rb +0 -135
  92. data/spec/ruact/server_functions/name_bridge_spec.rb +0 -212
  93. data/spec/ruact/server_functions/query_context_spec.rb +0 -72
  94. data/spec/ruact/server_functions/query_source_spec.rb +0 -193
  95. data/spec/ruact/server_functions/railtie_integration_spec.rb +0 -215
  96. data/spec/ruact/server_functions/rake_spec.rb +0 -86
  97. data/spec/ruact/server_functions/route_source_spec.rb +0 -202
  98. data/spec/ruact/server_functions/snapshot_spec.rb +0 -96
  99. data/spec/ruact/server_functions/snapshot_writer_spec.rb +0 -71
  100. data/spec/ruact/server_rescue_request_spec.rb +0 -416
  101. data/spec/ruact/server_spec.rb +0 -179
  102. data/spec/ruact/server_upload_request_spec.rb +0 -311
  103. data/spec/ruact/signed_references_spec.rb +0 -164
  104. data/spec/ruact/string_distance_spec.rb +0 -38
  105. data/spec/ruact/tasks_json_introspection_spec.rb +0 -141
  106. data/spec/ruact/testing/have_ruact_component_spec.rb +0 -170
  107. data/spec/ruact/testing/no_production_load_spec.rb +0 -41
  108. data/spec/ruact/validation_errors_spec.rb +0 -116
  109. data/spec/ruact/view_helper_spec.rb +0 -131
  110. data/spec/spec_helper.rb +0 -77
  111. data/spec/support/fixtures/pixel.png +0 -0
  112. data/spec/support/flight_wire_parser.rb +0 -21
  113. data/spec/support/flight_wire_parser_spec.rb +0 -93
  114. data/spec/support/matchers/flight_fixture_matcher.rb +0 -130
  115. data/spec/support/matchers/flight_fixture_matcher_spec.rb +0 -250
  116. data/spec/support/rails_stub.rb +0 -115
@@ -1,179 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- module Ruact
6
- RSpec.describe Serializable do
7
- let(:serializable_class) do
8
- Class.new do
9
- include Ruact::Serializable
10
-
11
- attr_reader :id, :title, :secret
12
-
13
- def initialize
14
- @id = 1
15
- @title = "Hello"
16
- @secret = "top-secret"
17
- end
18
-
19
- ruact_props :id, :title
20
- end
21
- end
22
-
23
- describe "ruact_props (AC#2)" do
24
- it "raises ArgumentError for undefined method at class load time" do
25
- expect do
26
- Class.new do
27
- include Ruact::Serializable
28
-
29
- ruact_props :nonexistent
30
- end
31
- end.to raise_error(ArgumentError, /nonexistent/)
32
- end
33
- end
34
-
35
- # Story 13.7 — `ruact_props` on ActiveRecord models.
36
- #
37
- # ActiveRecord defines its attribute reader methods LAZILY (on first
38
- # instance access), so at the moment the `ruact_props :title` macro runs,
39
- # `method_defined?(:title)` is `false` even for a real column. The eager
40
- # boot check used to raise there, so an AR model that included
41
- # `Ruact::Serializable` crashed at class-load. Story 13.7 makes the check
42
- # HYBRID: POROs are still checked eagerly at class-load (byte-identical, see
43
- # the block above), while for a lazy-attribute (AR) class the loud check is
44
- # DEFERRED to the first `ruact_serialize` — where the DB is up and the reader
45
- # exists. Loudness is preserved: a bogus prop still raises a clean
46
- # `ArgumentError`, just at first render of that model instead of at boot.
47
- #
48
- # Zero suite-boot DB footprint: the connection + table are built INSIDE the
49
- # example (direct connection DDL, NOT `Schema.define`, so we touch nothing
50
- # global — no `schema_migrations` / `ar_internal_metadata`), and only a
51
- # connection we ourselves opened is torn down.
52
- describe "ActiveRecord models (Story 13.7)", :story_13_7 do
53
- before do
54
- require "active_record"
55
- @already_connected =
56
- ActiveRecord::Base.respond_to?(:connected?) && ActiveRecord::Base.connected?
57
- ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") unless @already_connected
58
- ActiveRecord::Base.connection.create_table(:ruact_props_probe_posts, force: true) do |t|
59
- t.string :title
60
- t.string :secret
61
- end
62
- end
63
-
64
- after do
65
- if defined?(ActiveRecord::Base) && ActiveRecord::Base.connected?
66
- ActiveRecord::Base.connection.drop_table(:ruact_props_probe_posts, if_exists: true)
67
- end
68
- ActiveRecord::Base.remove_connection unless @already_connected
69
- end
70
-
71
- let(:ar_model) do
72
- Class.new(ActiveRecord::Base) do
73
- self.table_name = "ruact_props_probe_posts"
74
- include Ruact::Serializable
75
-
76
- ruact_props :id, :title
77
- end
78
- end
79
-
80
- it "loads without raising even though readers are lazy at class-load (AC#1)" do
81
- expect { ar_model }.not_to raise_error
82
- end
83
-
84
- it "ruact_serialize returns only the declared allowlist (AC#1)" do
85
- row = ar_model.create!(title: "Hello", secret: "top-secret")
86
-
87
- expect(row.ruact_serialize).to eq({ "id" => row.id, "title" => "Hello" })
88
- expect(row.ruact_serialize.keys).not_to include("secret")
89
- end
90
-
91
- it "defers the loud check to first serialize for a bogus prop (AC#2)" do
92
- model = nil
93
-
94
- # Declaring a bogus prop on an AR model does NOT raise at class-load —
95
- # the reader might still be defined lazily, so the check is deferred.
96
- expect do
97
- model = Class.new(ActiveRecord::Base) do
98
- self.table_name = "ruact_props_probe_posts"
99
- include Ruact::Serializable
100
-
101
- ruact_props :ttile # typo — neither a column nor a method
102
- end
103
- end.not_to raise_error
104
-
105
- # …but it fails LOUDLY (same clean ArgumentError) on first serialize.
106
- expect { model.new.ruact_serialize }
107
- .to raise_error(ArgumentError, /ttile.*not defined/)
108
- end
109
-
110
- it "re-validates loudly when props are re-declared after a first serialize (AC#2)" do
111
- model = Class.new(ActiveRecord::Base) do
112
- self.table_name = "ruact_props_probe_posts"
113
- include Ruact::Serializable
114
-
115
- ruact_props :id, :title
116
- end
117
-
118
- # First serialize succeeds and memoizes "validated"…
119
- model.create!(title: "Hello").ruact_serialize
120
-
121
- # …a re-declaration with a bogus prop must NOT be masked by the stale
122
- # memo: the next serialize still raises the clean ArgumentError.
123
- model.ruact_props :id, :ttile
124
- expect { model.new.ruact_serialize }
125
- .to raise_error(ArgumentError, /ttile.*not defined/)
126
- end
127
-
128
- it "re-validates an inherited declaration re-declared on the parent after a subclass serialize (AC#2)" do
129
- parent = Class.new(ActiveRecord::Base) do
130
- self.table_name = "ruact_props_probe_posts"
131
- include Ruact::Serializable
132
-
133
- ruact_props :id, :title
134
- end
135
- child = Class.new(parent)
136
-
137
- # The subclass serializes first, memoizing the inherited (valid) list…
138
- parent.create!(title: "Hello")
139
- child.first.ruact_serialize
140
-
141
- # …then the PARENT re-declares with a bogus prop. The subclass must not
142
- # keep serving its stale memo: its next serialize re-validates loudly.
143
- parent.ruact_props :id, :ttile
144
- expect { child.first.ruact_serialize }
145
- .to raise_error(ArgumentError, /ttile.*not defined/)
146
- end
147
-
148
- it "dispatches through serialize_serializable under strict true AND false (AC#4)" do
149
- row = ar_model.create!(title: "Hello", secret: "top-secret")
150
-
151
- [true, false].each do |strict|
152
- output = Ruact::Flight::Renderer.render(
153
- row, Ruact::ClientManifest.from_hash({}), strict_serialization: strict
154
- )
155
- expect(output).to include("Hello")
156
- expect(output).not_to include("top-secret")
157
- end
158
- end
159
- end
160
-
161
- describe "ruact_serialize (AC#1)" do
162
- it "returns only declared props" do
163
- obj = serializable_class.new
164
- expect(obj.ruact_serialize).to eq({ "id" => 1, "title" => "Hello" })
165
- end
166
-
167
- it "excludes undeclared attributes" do
168
- obj = serializable_class.new
169
- expect(obj.ruact_serialize.keys).not_to include("secret")
170
- end
171
- end
172
-
173
- describe "ruact_props_list" do
174
- it "returns the declared prop names as symbols" do
175
- expect(serializable_class.ruact_props_list).to eq(%i[id title])
176
- end
177
- end
178
- end
179
- end