ruact 0.0.11 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +110 -48
- data/CONTRIBUTING.md +233 -0
- data/README.md +14 -4
- data/RELEASING.md +125 -139
- data/lib/ruact/packaging.rb +68 -0
- data/lib/ruact/version.rb +1 -1
- data/vendor/javascript/vite-plugin-ruact/flight-client.test.mjs +321 -0
- data/vendor/javascript/vite-plugin-ruact/package-lock.json +11 -0
- data/vendor/javascript/vite-plugin-ruact/package.json +1 -0
- data/vendor/javascript/vite-plugin-ruact/runtime/flight-client.js +14 -3
- metadata +6 -107
- data/.codecov.yml +0 -31
- data/.github/workflows/ci.yml +0 -284
- data/.github/workflows/server-functions-bench.yml +0 -54
- data/.rubocop.yml +0 -107
- data/.rubocop_todo.yml +0 -63
- data/Rakefile +0 -10
- data/bench/server_functions_dispatch_bench.rb +0 -276
- data/bench/server_functions_dispatch_bench.results.md +0 -150
- data/docs/internal/README.md +0 -9
- data/docs/internal/decisions/server-functions-api.md +0 -2236
- data/spec/benchmarks/baseline.json +0 -12
- data/spec/benchmarks/render_pipeline_benchmark_spec.rb +0 -109
- data/spec/fixtures/flight/README.md +0 -136
- data/spec/fixtures/flight/array.txt +0 -1
- data/spec/fixtures/flight/as_json_object.txt +0 -2
- data/spec/fixtures/flight/bigint.txt +0 -1
- data/spec/fixtures/flight/boolean_false.txt +0 -1
- data/spec/fixtures/flight/boolean_true.txt +0 -1
- data/spec/fixtures/flight/client_component_with_props.txt +0 -2
- data/spec/fixtures/flight/client_reference.txt +0 -2
- data/spec/fixtures/flight/hash.txt +0 -1
- data/spec/fixtures/flight/infinity.txt +0 -1
- data/spec/fixtures/flight/nan.txt +0 -1
- data/spec/fixtures/flight/negative_infinity.txt +0 -1
- data/spec/fixtures/flight/nil.txt +0 -1
- data/spec/fixtures/flight/number_float.txt +0 -1
- data/spec/fixtures/flight/number_integer.txt +0 -1
- data/spec/fixtures/flight/react_element_no_props.txt +0 -1
- data/spec/fixtures/flight/redirect_row.txt +0 -1
- data/spec/fixtures/flight/serializable_object.txt +0 -2
- data/spec/fixtures/flight/string_basic.txt +0 -1
- data/spec/fixtures/flight/string_dollar_escape.txt +0 -1
- data/spec/fixtures/flight/undefined.txt +0 -1
- data/spec/fixtures/readme/children-error.html.erb +0 -3
- data/spec/fixtures/readme/children-error.txt +0 -1
- data/spec/fixtures/story_7_9_views/controller_request_spec_support/demo/show.html.erb +0 -3
- data/spec/fixtures/story_7_9_views/controller_request_spec_support/errors_demo/new.html.erb +0 -3
- data/spec/fixtures/story_7_9_views/controller_request_spec_support/exploding_layout_demo/show.html.erb +0 -3
- data/spec/fixtures/story_7_9_views/controller_request_spec_support/ghost_layout_demo/show.html.erb +0 -3
- data/spec/fixtures/story_7_9_views/controller_request_spec_support/layout_demo/show.html.erb +0 -3
- data/spec/fixtures/story_7_9_views/controller_request_spec_support/rootless_layout_demo/show.html.erb +0 -3
- data/spec/fixtures/story_7_9_views/controller_request_spec_support/unwired_layout_demo/show.html.erb +0 -3
- data/spec/fixtures/story_7_9_views/layouts/bare_host.html.erb +0 -16
- data/spec/fixtures/story_7_9_views/layouts/exploding_host.html.erb +0 -24
- data/spec/fixtures/story_7_9_views/layouts/rootless_host.html.erb +0 -15
- data/spec/fixtures/story_7_9_views/layouts/ruact_host.html.erb +0 -17
- data/spec/readme_demo_message_spec.rb +0 -67
- data/spec/readme_spec.rb +0 -282
- data/spec/ruact/client_manifest_spec.rb +0 -270
- data/spec/ruact/component_contract_spec.rb +0 -119
- data/spec/ruact/configuration_spec.rb +0 -518
- data/spec/ruact/controller_request_spec.rb +0 -671
- data/spec/ruact/controller_spec.rb +0 -343
- data/spec/ruact/doctor_spec.rb +0 -769
- data/spec/ruact/erb_preprocessor_hook_spec.rb +0 -55
- data/spec/ruact/erb_preprocessor_spec.rb +0 -361
- data/spec/ruact/errors_spec.rb +0 -93
- data/spec/ruact/flight/renderer_spec.rb +0 -133
- data/spec/ruact/flight/serializer_spec.rb +0 -494
- data/spec/ruact/html_converter_spec.rb +0 -375
- data/spec/ruact/install_generator_spec.rb +0 -1549
- data/spec/ruact/layout_source_spec.rb +0 -108
- data/spec/ruact/manifest_resolver_spec.rb +0 -174
- data/spec/ruact/query_request_spec.rb +0 -706
- data/spec/ruact/query_spec.rb +0 -105
- data/spec/ruact/railtie_spec.rb +0 -155
- data/spec/ruact/render_context_spec.rb +0 -58
- data/spec/ruact/render_pipeline_concurrency_spec.rb +0 -78
- data/spec/ruact/render_pipeline_spec.rb +0 -928
- data/spec/ruact/scaffold_generator_spec.rb +0 -1849
- data/spec/ruact/serializable_spec.rb +0 -179
- data/spec/ruact/server_bucket_request_spec.rb +0 -785
- data/spec/ruact/server_function_name_spec.rb +0 -53
- data/spec/ruact/server_functions/backtrace_cleaner_spec.rb +0 -63
- data/spec/ruact/server_functions/bucket_two_payload_spec.rb +0 -200
- data/spec/ruact/server_functions/codegen_spec.rb +0 -397
- data/spec/ruact/server_functions/error_payload_spec.rb +0 -222
- data/spec/ruact/server_functions/error_suggestion_spec.rb +0 -79
- data/spec/ruact/server_functions/introspection_spec.rb +0 -135
- data/spec/ruact/server_functions/name_bridge_spec.rb +0 -212
- data/spec/ruact/server_functions/query_context_spec.rb +0 -72
- data/spec/ruact/server_functions/query_source_spec.rb +0 -193
- data/spec/ruact/server_functions/railtie_integration_spec.rb +0 -215
- data/spec/ruact/server_functions/rake_spec.rb +0 -86
- data/spec/ruact/server_functions/route_source_spec.rb +0 -202
- data/spec/ruact/server_functions/snapshot_spec.rb +0 -96
- data/spec/ruact/server_functions/snapshot_writer_spec.rb +0 -71
- data/spec/ruact/server_rescue_request_spec.rb +0 -416
- data/spec/ruact/server_spec.rb +0 -179
- data/spec/ruact/server_upload_request_spec.rb +0 -311
- data/spec/ruact/signed_references_spec.rb +0 -164
- data/spec/ruact/string_distance_spec.rb +0 -38
- data/spec/ruact/tasks_json_introspection_spec.rb +0 -141
- data/spec/ruact/testing/have_ruact_component_spec.rb +0 -170
- data/spec/ruact/testing/no_production_load_spec.rb +0 -41
- data/spec/ruact/validation_errors_spec.rb +0 -116
- data/spec/ruact/view_helper_spec.rb +0 -131
- data/spec/spec_helper.rb +0 -77
- data/spec/support/fixtures/pixel.png +0 -0
- data/spec/support/flight_wire_parser.rb +0 -21
- data/spec/support/flight_wire_parser_spec.rb +0 -93
- data/spec/support/matchers/flight_fixture_matcher.rb +0 -130
- data/spec/support/matchers/flight_fixture_matcher_spec.rb +0 -250
- 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
|