interfacets 0.9.9 → 0.9.99
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/.tmp +5 -0
- data/Rakefile +4 -0
- data/lib/interfacets/client/assets.rb +1 -0
- data/lib/interfacets/client/bus.rb +5 -1
- data/lib/interfacets/client/channels/api.rb +10 -3
- data/lib/interfacets/client/registry.rb +9 -70
- data/lib/interfacets/client/utils/mruby_patches.rb +1 -1
- data/lib/interfacets/client/utils/open_struct.rb +90 -77
- data/lib/interfacets/component_registry.rb +115 -0
- data/lib/interfacets/component_schema_parser.rb +84 -0
- data/lib/interfacets/server/api.rb +5 -25
- data/lib/interfacets/server/assets/facet.rb +5 -3
- data/lib/interfacets/server/assets.rb +13 -7
- data/lib/interfacets/server/basic_router.rb +15 -10
- data/lib/interfacets/server/bus.rb +4 -9
- data/lib/interfacets/server/config.rb +1 -1
- data/lib/interfacets/server/registry.rb +23 -184
- data/lib/interfacets/shared/basic_routable.rb +45 -0
- data/lib/interfacets/shared/entities/bus.rb +41 -29
- data/lib/interfacets/shared/entities/specs/handlers.rb +16 -0
- data/lib/interfacets/shared/entities/specs.rb +46 -9
- data/lib/interfacets/shared/entity.rb +23 -99
- data/lib/interfacets/shared/entity_dsl.rb +154 -0
- data/lib/interfacets/shared/facet.rb +200 -0
- data/lib/interfacets/shared/generated_store.rb +6 -2
- data/lib/interfacets/shared/utils.rb +1 -1
- data/lib/interfacets/shared/validations.rb +5 -1
- data/lib/interfacets/{client → shared}/view.rb +33 -6
- data/lib/interfacets/test/component_registry.rb +63 -0
- data/lib/interfacets/test/js/inline_bus.rb +21 -12
- data/lib/interfacets/test/js/nodo_bus.rb +18 -1
- data/lib/interfacets/test/js/receivers/api.rb +14 -3
- data/lib/interfacets/test/js/receivers/react/node/xml_parser.rb +75 -0
- data/lib/interfacets/test/js/receivers/react/node.rb +29 -63
- data/lib/interfacets/test/js/receivers/react.rb +4 -3
- data/lib/interfacets/test/js/receivers/timer.rb +77 -0
- data/lib/interfacets/test/js/receivers/url.rb +5 -0
- data/lib/interfacets/test/standard_elements.yml +173 -0
- data/lib/interfacets/test/{browser.rb → ui_simulator.rb} +18 -6
- data/lib/interfacets/test/validation_engine.rb +151 -0
- data/lib/interfacets/test.rb +0 -4
- data/lib/interfacets/version.rb +1 -1
- data/lib/interfacets.rb +3 -0
- metadata +29 -18
- data/lib/interfacets/client/facet.rb +0 -26
- data/lib/interfacets/client/facet2.rb +0 -15
- data/lib/interfacets/client/facets/attributes/accessor.rb +0 -28
- data/lib/interfacets/client/facets/attributes/association.rb +0 -50
- data/lib/interfacets/client/facets/attributes/bind.rb +0 -25
- data/lib/interfacets/client/facets/attributes/collection.rb +0 -47
- data/lib/interfacets/client/facets/attributes/readonly.rb +0 -19
- data/lib/interfacets/client/facets/deserializer.rb +0 -30
- data/lib/interfacets/client/facets/schema/deserializer.rb +0 -63
- data/lib/interfacets/client/facets/schema.rb +0 -63
- data/lib/interfacets/client/facets/serializer.rb +0 -18
- data/lib/interfacets/server/basic_routable.rb +0 -40
- data/lib/interfacets/server/facet.rb +0 -51
- data/lib/interfacets/shared/entity_collection.rb +0 -88
|
@@ -19,7 +19,7 @@ module Interfacets
|
|
|
19
19
|
type: "interfacets:system:create_bus",
|
|
20
20
|
payload: {
|
|
21
21
|
id: "default",
|
|
22
|
-
channel_ids: ["interfacets:api", "dom", "url"],
|
|
22
|
+
channel_ids: ["interfacets:api", "dom", "url", "timer"],
|
|
23
23
|
hydration: {
|
|
24
24
|
destination: { bus: "default", channel: "interfacets:api" },
|
|
25
25
|
type: "interfacets:api:hydrate",
|
|
@@ -30,6 +30,10 @@ module Interfacets
|
|
|
30
30
|
}))
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
def dispatch(channel_id, event)
|
|
34
|
+
dispatch_to_bus(bus_id: "default", channel_id: channel_id, event: event)
|
|
35
|
+
end
|
|
36
|
+
|
|
33
37
|
private
|
|
34
38
|
|
|
35
39
|
def handle(event)
|
|
@@ -40,21 +44,33 @@ module Interfacets
|
|
|
40
44
|
|
|
41
45
|
bus_event.fetch("payload").each do |channel_event|
|
|
42
46
|
channel_id = channel_event.fetch("id")
|
|
43
|
-
receiver_index
|
|
44
|
-
|
|
47
|
+
receiver = receiver_index.fetch(channel_id)
|
|
48
|
+
|
|
49
|
+
receiver
|
|
45
50
|
.receive(
|
|
46
51
|
payload: channel_event.fetch("payload"),
|
|
47
52
|
dispatch: ->(ev) {
|
|
48
|
-
|
|
53
|
+
dispatch_to_bus(bus_id:, channel_id:, event: ev)
|
|
49
54
|
},
|
|
50
55
|
)
|
|
51
56
|
end
|
|
52
57
|
else
|
|
53
58
|
raise("unhandled event type: #{event}")
|
|
54
59
|
end
|
|
60
|
+
|
|
61
|
+
# Flush any responses that may have come from the server
|
|
62
|
+
# should separate this out so that auto-flush or manual-flush
|
|
63
|
+
# is possible to simulate ordering events as needed.
|
|
64
|
+
receiver_index.each do |channel_id, receiver|
|
|
65
|
+
if receiver.respond_to?(:response_queue)
|
|
66
|
+
receiver.flush_responses.each do |response|
|
|
67
|
+
dispatch_to_bus(bus_id:, channel_id:, event: response)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
55
71
|
end
|
|
56
72
|
|
|
57
|
-
def
|
|
73
|
+
def dispatch_to_bus(bus_id:, channel_id:, event:)
|
|
58
74
|
client.handle(
|
|
59
75
|
H.j(
|
|
60
76
|
{
|
|
@@ -69,13 +85,6 @@ module Interfacets
|
|
|
69
85
|
def client
|
|
70
86
|
@client ||= (
|
|
71
87
|
$asset_logger = Logger.new("/dev/null")
|
|
72
|
-
original_verbose = $VERBOSE
|
|
73
|
-
$VERBOSE = nil
|
|
74
|
-
begin
|
|
75
|
-
Client::Assets.bootstrap(client_system_json.fetch("assets"))
|
|
76
|
-
ensure
|
|
77
|
-
$VERBOSE = original_verbose
|
|
78
|
-
end
|
|
79
88
|
Client::System.logger = $asset_logger
|
|
80
89
|
|
|
81
90
|
Client.start(
|
|
@@ -30,10 +30,27 @@ module Interfacets
|
|
|
30
30
|
|
|
31
31
|
def render
|
|
32
32
|
receiver_index.each do |id, ch|
|
|
33
|
+
state = js_get_state(id)
|
|
34
|
+
next if state.nil?
|
|
35
|
+
|
|
33
36
|
ch.receive(
|
|
34
|
-
payload:
|
|
37
|
+
payload: state.fetch("data"),
|
|
35
38
|
dispatch: ->(e) { dispatch(id, e) }
|
|
36
39
|
)
|
|
40
|
+
|
|
41
|
+
receiver_index.each do |id, ch|
|
|
42
|
+
if ch.respond_to?(:response_queue)
|
|
43
|
+
ch.flush_responses.each do |response|
|
|
44
|
+
dispatch(id, response)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if js_get_logs.any? { _1.fetch("type") == "error" }
|
|
51
|
+
js_get_logs
|
|
52
|
+
.map { _1.fetch("value") }
|
|
53
|
+
.then { raise(_1.join("\n")) }
|
|
37
54
|
end
|
|
38
55
|
end
|
|
39
56
|
|
|
@@ -25,10 +25,21 @@ module Interfacets
|
|
|
25
25
|
return if payload.dig("streams", "default").nil?
|
|
26
26
|
return if payload.dig("streams", "default").empty?
|
|
27
27
|
|
|
28
|
+
method = payload.dig("streams", "default", "method")
|
|
28
29
|
url = payload.dig("streams", "default", "url")
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if method == "get"
|
|
33
|
+
response_queue << router.call(url).render
|
|
34
|
+
else
|
|
35
|
+
payload
|
|
36
|
+
.dig("streams", "default", "body", "event", "payload")
|
|
37
|
+
.then { response_queue << router.call(url).handle(_1) }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def flush_responses
|
|
42
|
+
response_queue.tap { @response_queue = [] }
|
|
32
43
|
end
|
|
33
44
|
end
|
|
34
45
|
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "nokogiri"
|
|
4
|
+
|
|
5
|
+
module Interfacets
|
|
6
|
+
module Test
|
|
7
|
+
module Js
|
|
8
|
+
module Receivers
|
|
9
|
+
class React
|
|
10
|
+
class Node
|
|
11
|
+
class XmlParser
|
|
12
|
+
attr_reader :json, :validation_engine
|
|
13
|
+
def initialize(json, validation_engine:)
|
|
14
|
+
@json = json
|
|
15
|
+
@validation_engine = validation_engine
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def call
|
|
19
|
+
xml = Nokogiri::XML.fragment("<Facet/>")
|
|
20
|
+
json
|
|
21
|
+
.dig("streams", "default", "dom")
|
|
22
|
+
.map { parse_element(_1) }
|
|
23
|
+
.each { xml.add_child(_1) }
|
|
24
|
+
xml
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def parse_attribute(value, top: true)
|
|
30
|
+
case value
|
|
31
|
+
when Array
|
|
32
|
+
when Hash
|
|
33
|
+
value
|
|
34
|
+
.transform_values { parse_attribute(_1, top: false) }
|
|
35
|
+
# we don't want to call to_json on nested hashes
|
|
36
|
+
.then { top ? _1.to_json : _1 }
|
|
37
|
+
when Numeric, String, TrueClass, FalseClass, NilClass
|
|
38
|
+
value
|
|
39
|
+
else
|
|
40
|
+
raise "unknown attribute type: #{value}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def parse_element(el)
|
|
45
|
+
case el.fetch("type")
|
|
46
|
+
when "interfacets:string-node"
|
|
47
|
+
el.dig("attributes", "value").to_s
|
|
48
|
+
when "interfacets:react-dom:element"
|
|
49
|
+
xml = (
|
|
50
|
+
el
|
|
51
|
+
.fetch("element")
|
|
52
|
+
.tap { validation_engine&.validate_props(_1, el.fetch("attributes")) }
|
|
53
|
+
.then { Nokogiri::XML.fragment("<#{_1} />").children.first }
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
el.fetch("children").each do |child|
|
|
57
|
+
xml.add_child(parse_element(child)) if child
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
el.fetch("attributes").each do |name, value|
|
|
61
|
+
xml.set_attribute(name, parse_attribute(value))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
xml
|
|
65
|
+
else
|
|
66
|
+
raise "unknown type: #{el.fetch("type")}"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -8,71 +8,17 @@ module Interfacets
|
|
|
8
8
|
module Receivers
|
|
9
9
|
class React
|
|
10
10
|
class Node
|
|
11
|
-
|
|
12
|
-
attr_reader :json
|
|
13
|
-
def initialize(json)
|
|
14
|
-
@json = json
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def call
|
|
18
|
-
xml = Nokogiri::XML.fragment("<Facet/>")
|
|
19
|
-
json
|
|
20
|
-
.dig("streams", "default", "dom")
|
|
21
|
-
.map { parse_element(_1) }
|
|
22
|
-
.each { xml.add_child(_1) }
|
|
23
|
-
xml
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def parse_attribute(value)
|
|
29
|
-
case value
|
|
30
|
-
when Array
|
|
31
|
-
when Hash
|
|
32
|
-
value.transform_values { parse_attribute(_1) }
|
|
33
|
-
when Numeric, String, TrueClass, FalseClass, NilClass
|
|
34
|
-
value
|
|
35
|
-
else
|
|
36
|
-
raise "unknown attribute type: #{value}"
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def parse_element(el)
|
|
41
|
-
case el.fetch("type")
|
|
42
|
-
when "interfacets:string-node"
|
|
43
|
-
el.dig("attributes", "value")
|
|
44
|
-
when "interfacets:react-dom:element"
|
|
45
|
-
xml = (
|
|
46
|
-
el
|
|
47
|
-
.fetch("element")
|
|
48
|
-
.then { Nokogiri::XML.fragment("<#{_1} />").children.first }
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
el.fetch("children").each do |child|
|
|
52
|
-
xml.add_child(parse_element(child)) if child
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
el.fetch("attributes").each do |name, value|
|
|
56
|
-
xml.set_attribute(name, parse_attribute(value).to_json)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
xml
|
|
60
|
-
else
|
|
61
|
-
raise "unknown type: #{el.fetch("type")}"
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def self.parse(json:, dispatch:)
|
|
11
|
+
def self.parse(json:, dispatch:, validation_engine:)
|
|
67
12
|
new(
|
|
68
|
-
xml: XmlParser.new(json).call,
|
|
13
|
+
xml: XmlParser.new(json, validation_engine:).call,
|
|
69
14
|
dispatch:,
|
|
15
|
+
validation_engine:,
|
|
70
16
|
parent: nil,
|
|
71
17
|
)
|
|
72
18
|
end
|
|
73
19
|
|
|
74
20
|
Error = Class.new(StandardError)
|
|
75
|
-
|
|
21
|
+
NoMatchesError = Class.new(Error)
|
|
76
22
|
MultipleMatchesError = Class.new(Error)
|
|
77
23
|
StaleNodeError = Class.new(Error) do
|
|
78
24
|
def initialize
|
|
@@ -87,11 +33,12 @@ module Interfacets
|
|
|
87
33
|
end
|
|
88
34
|
end
|
|
89
35
|
|
|
90
|
-
attr_reader :xml, :dispatch, :parent
|
|
91
|
-
def initialize(xml:, dispatch:, parent:)
|
|
36
|
+
attr_reader :xml, :dispatch, :parent, :validation_engine
|
|
37
|
+
def initialize(xml:, dispatch:, parent:, validation_engine:)
|
|
92
38
|
@xml = xml
|
|
93
39
|
@dispatch = dispatch
|
|
94
40
|
@parent = parent
|
|
41
|
+
@validation_engine = validation_engine
|
|
95
42
|
end
|
|
96
43
|
|
|
97
44
|
def stale!
|
|
@@ -102,6 +49,20 @@ module Interfacets
|
|
|
102
49
|
@stale || parent&.stale?
|
|
103
50
|
end
|
|
104
51
|
|
|
52
|
+
def component_name
|
|
53
|
+
raise StaleNodeError if stale?
|
|
54
|
+
|
|
55
|
+
xml.name
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def props
|
|
59
|
+
raise StaleNodeError if stale?
|
|
60
|
+
|
|
61
|
+
xml.attributes.transform_values do |attr|
|
|
62
|
+
attr.value.then { JSON.parse(_1) rescue _1 }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
105
66
|
def content
|
|
106
67
|
raise StaleNodeError if stale?
|
|
107
68
|
|
|
@@ -129,12 +90,12 @@ module Interfacets
|
|
|
129
90
|
|
|
130
91
|
xml
|
|
131
92
|
.css(*a, **p)
|
|
132
|
-
.map { Node.new(xml: _1, dispatch:, parent: self) }
|
|
93
|
+
.map { Node.new(xml: _1, dispatch:, parent: self, validation_engine:) }
|
|
133
94
|
.select {
|
|
134
95
|
(
|
|
135
96
|
content == EMPTY_ARG || (
|
|
136
97
|
if content.is_a?(Regexp)
|
|
137
|
-
_1.content.match(content)
|
|
98
|
+
_1.content.match?(content)
|
|
138
99
|
else
|
|
139
100
|
_1.content == content
|
|
140
101
|
end
|
|
@@ -149,13 +110,18 @@ module Interfacets
|
|
|
149
110
|
|
|
150
111
|
xml
|
|
151
112
|
.attribute(name)
|
|
152
|
-
|
|
113
|
+
&.value
|
|
114
|
+
&.then { JSON.parse(_1) rescue _1 }
|
|
153
115
|
end
|
|
154
116
|
|
|
155
117
|
def trigger(name, data = {})
|
|
156
118
|
raise StaleNodeError if stale?
|
|
157
119
|
|
|
120
|
+
validation_engine&.validate_event(xml.name, name, data)
|
|
121
|
+
|
|
158
122
|
value = attribute(name.to_s)
|
|
123
|
+
raise "No event handler registered for: #{name}" unless value
|
|
124
|
+
|
|
159
125
|
value["payload"]["event"] = data
|
|
160
126
|
dispatch.(value)
|
|
161
127
|
end
|
|
@@ -8,9 +8,10 @@ module Interfacets
|
|
|
8
8
|
module Js
|
|
9
9
|
module Receivers
|
|
10
10
|
class React
|
|
11
|
-
attr_reader :name, :node
|
|
12
|
-
def initialize(name:)
|
|
11
|
+
attr_reader :name, :node, :validation_engine
|
|
12
|
+
def initialize(name:, validation_engine: nil)
|
|
13
13
|
@name = name
|
|
14
|
+
@validation_engine = validation_engine
|
|
14
15
|
@actions = {}
|
|
15
16
|
end
|
|
16
17
|
|
|
@@ -18,7 +19,7 @@ module Interfacets
|
|
|
18
19
|
@dispatch = dispatch
|
|
19
20
|
@actions = nil
|
|
20
21
|
@node&.stale!
|
|
21
|
-
@node = Node.parse(json: payload, dispatch:)
|
|
22
|
+
@node = Node.parse(json: payload, dispatch:, validation_engine:)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def handler
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Interfacets
|
|
4
|
+
module Test
|
|
5
|
+
module Js
|
|
6
|
+
module Receivers
|
|
7
|
+
class Timer
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
class Registration
|
|
11
|
+
attr_reader :ms, :response_payload, :dispatch
|
|
12
|
+
|
|
13
|
+
def initialize(ms:, response_payload:, dispatch:)
|
|
14
|
+
@ms = ms
|
|
15
|
+
@response_payload = response_payload
|
|
16
|
+
@dispatch = dispatch
|
|
17
|
+
@notified = false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def notify
|
|
21
|
+
return if @notified
|
|
22
|
+
@dispatch.call({ payload: response_payload })
|
|
23
|
+
@notified = true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attr_reader :name, :registrations
|
|
28
|
+
def initialize(name:)
|
|
29
|
+
@name = name
|
|
30
|
+
@registrations = []
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def receive(payload:, dispatch:)
|
|
34
|
+
@dispatch = dispatch
|
|
35
|
+
|
|
36
|
+
return if payload.nil?
|
|
37
|
+
return if payload.empty?
|
|
38
|
+
return if payload.dig("streams", "default").nil?
|
|
39
|
+
return if payload.dig("streams", "default").empty?
|
|
40
|
+
|
|
41
|
+
event = payload.dig("streams", "default")
|
|
42
|
+
ms = event["ms"]
|
|
43
|
+
response_payload = event["response"]
|
|
44
|
+
|
|
45
|
+
return unless ms && response_payload
|
|
46
|
+
|
|
47
|
+
@registrations << Registration.new(
|
|
48
|
+
ms: ms,
|
|
49
|
+
response_payload: response_payload,
|
|
50
|
+
dispatch: dispatch
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def handler
|
|
55
|
+
self
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def first
|
|
59
|
+
registrations.first
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def last
|
|
63
|
+
registrations.last
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def each(&block)
|
|
67
|
+
registrations.each(&block)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def clear
|
|
71
|
+
@registrations = []
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -32,6 +32,7 @@ module Interfacets
|
|
|
32
32
|
attr_reader :server, :name, :response_queue
|
|
33
33
|
def initialize(name:)
|
|
34
34
|
@name = name
|
|
35
|
+
@response_queue = []
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def receive(payload:, dispatch:)
|
|
@@ -48,6 +49,10 @@ module Interfacets
|
|
|
48
49
|
def handler
|
|
49
50
|
@handler
|
|
50
51
|
end
|
|
52
|
+
|
|
53
|
+
def flush_responses
|
|
54
|
+
response_queue.tap { @response_queue = [] }
|
|
55
|
+
end
|
|
51
56
|
end
|
|
52
57
|
end
|
|
53
58
|
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
- a
|
|
3
|
+
- abbr
|
|
4
|
+
- address
|
|
5
|
+
- area
|
|
6
|
+
- article
|
|
7
|
+
- aside
|
|
8
|
+
- audio
|
|
9
|
+
- b
|
|
10
|
+
- base
|
|
11
|
+
- bdi
|
|
12
|
+
- bdo
|
|
13
|
+
- blockquote
|
|
14
|
+
- body
|
|
15
|
+
- br
|
|
16
|
+
- button
|
|
17
|
+
- canvas
|
|
18
|
+
- caption
|
|
19
|
+
- cite
|
|
20
|
+
- code
|
|
21
|
+
- col
|
|
22
|
+
- colgroup
|
|
23
|
+
- data
|
|
24
|
+
- datalist
|
|
25
|
+
- dd
|
|
26
|
+
- del
|
|
27
|
+
- details
|
|
28
|
+
- dfn
|
|
29
|
+
- dialog
|
|
30
|
+
- div
|
|
31
|
+
- dl
|
|
32
|
+
- dt
|
|
33
|
+
- em
|
|
34
|
+
- embed
|
|
35
|
+
- fieldset
|
|
36
|
+
- figcaption
|
|
37
|
+
- figure
|
|
38
|
+
- footer
|
|
39
|
+
- form
|
|
40
|
+
- h1
|
|
41
|
+
- h2
|
|
42
|
+
- h3
|
|
43
|
+
- h4
|
|
44
|
+
- h5
|
|
45
|
+
- h6
|
|
46
|
+
- head
|
|
47
|
+
- header
|
|
48
|
+
- hgroup
|
|
49
|
+
- hr
|
|
50
|
+
- html
|
|
51
|
+
- i
|
|
52
|
+
- iframe
|
|
53
|
+
- img
|
|
54
|
+
- input
|
|
55
|
+
- ins
|
|
56
|
+
- kbd
|
|
57
|
+
- label
|
|
58
|
+
- legend
|
|
59
|
+
- li
|
|
60
|
+
- link
|
|
61
|
+
- main
|
|
62
|
+
- map
|
|
63
|
+
- mark
|
|
64
|
+
- menu
|
|
65
|
+
- meta
|
|
66
|
+
- meter
|
|
67
|
+
- nav
|
|
68
|
+
- noscript
|
|
69
|
+
- object
|
|
70
|
+
- ol
|
|
71
|
+
- optgroup
|
|
72
|
+
- option
|
|
73
|
+
- output
|
|
74
|
+
- p
|
|
75
|
+
- picture
|
|
76
|
+
- pre
|
|
77
|
+
- progress
|
|
78
|
+
- q
|
|
79
|
+
- rp
|
|
80
|
+
- rt
|
|
81
|
+
- ruby
|
|
82
|
+
- s
|
|
83
|
+
- samp
|
|
84
|
+
- script
|
|
85
|
+
- section
|
|
86
|
+
- select
|
|
87
|
+
- slot
|
|
88
|
+
- small
|
|
89
|
+
- source
|
|
90
|
+
- span
|
|
91
|
+
- strong
|
|
92
|
+
- style
|
|
93
|
+
- sub
|
|
94
|
+
- summary
|
|
95
|
+
- sup
|
|
96
|
+
- table
|
|
97
|
+
- tbody
|
|
98
|
+
- td
|
|
99
|
+
- template
|
|
100
|
+
- textarea
|
|
101
|
+
- tfoot
|
|
102
|
+
- th
|
|
103
|
+
- thead
|
|
104
|
+
- time
|
|
105
|
+
- title
|
|
106
|
+
- tr
|
|
107
|
+
- track
|
|
108
|
+
- u
|
|
109
|
+
- ul
|
|
110
|
+
- var
|
|
111
|
+
- video
|
|
112
|
+
- wbr
|
|
113
|
+
- animate
|
|
114
|
+
- animatemotion
|
|
115
|
+
- animatetransform
|
|
116
|
+
- circle
|
|
117
|
+
- clippath
|
|
118
|
+
- defs
|
|
119
|
+
- desc
|
|
120
|
+
- discard
|
|
121
|
+
- ellipse
|
|
122
|
+
- feblend
|
|
123
|
+
- fecolormatrix
|
|
124
|
+
- fecomponenttransfer
|
|
125
|
+
- fecomposite
|
|
126
|
+
- feconvolvematrix
|
|
127
|
+
- fediffuselighting
|
|
128
|
+
- fedisplacementmap
|
|
129
|
+
- fedistantlight
|
|
130
|
+
- fedropshadow
|
|
131
|
+
- feflood
|
|
132
|
+
- fefunca
|
|
133
|
+
- fefuncb
|
|
134
|
+
- fefuncg
|
|
135
|
+
- fefuncr
|
|
136
|
+
- fegaussianblur
|
|
137
|
+
- feimage
|
|
138
|
+
- femerge
|
|
139
|
+
- femergenode
|
|
140
|
+
- femorphology
|
|
141
|
+
- feoffset
|
|
142
|
+
- fepointlight
|
|
143
|
+
- fespecularlighting
|
|
144
|
+
- fespotlight
|
|
145
|
+
- fetile
|
|
146
|
+
- feturbulence
|
|
147
|
+
- filter
|
|
148
|
+
- foreignobject
|
|
149
|
+
- g
|
|
150
|
+
- image
|
|
151
|
+
- line
|
|
152
|
+
- lineargradient
|
|
153
|
+
- marker
|
|
154
|
+
- mask
|
|
155
|
+
- metadata
|
|
156
|
+
- mpath
|
|
157
|
+
- path
|
|
158
|
+
- pattern
|
|
159
|
+
- polygon
|
|
160
|
+
- polyline
|
|
161
|
+
- radialgradient
|
|
162
|
+
- rect
|
|
163
|
+
- script
|
|
164
|
+
- set
|
|
165
|
+
- stop
|
|
166
|
+
- svg
|
|
167
|
+
- switch
|
|
168
|
+
- symbol
|
|
169
|
+
- text
|
|
170
|
+
- textpath
|
|
171
|
+
- tspan
|
|
172
|
+
- use
|
|
173
|
+
- view
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
|
|
2
2
|
module Interfacets
|
|
3
3
|
module Test
|
|
4
|
-
class
|
|
4
|
+
class UiSimulator
|
|
5
5
|
TYPES = {
|
|
6
6
|
inline: Js::InlineBus,
|
|
7
7
|
nodo: Js::NodoBus,
|
|
8
|
+
mruby_wasm: Js::NodoBus,
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
attr_reader :system_json, :router, :type
|
|
11
|
-
def initialize(
|
|
11
|
+
attr_reader :system_json, :router, :type, :contract_path, :validation
|
|
12
|
+
def initialize(type:, bus:, router:, contract_path: nil, validation: :strict)
|
|
12
13
|
unless TYPES.keys.include?(type)
|
|
13
14
|
raise ArgumentError.new(
|
|
14
15
|
"type: #{type.inspect} not allowed. Must be one of #{TYPES.keys}"
|
|
@@ -17,8 +18,10 @@ module Interfacets
|
|
|
17
18
|
|
|
18
19
|
@type = type
|
|
19
20
|
# Serialize and deserialize to ensure proper data structure for JS
|
|
20
|
-
@system_json = JSON.parse(
|
|
21
|
+
@system_json = JSON.parse(bus.client_system_json(only_facets: type == :inline).to_json)
|
|
21
22
|
@router = router
|
|
23
|
+
@contract_path = contract_path
|
|
24
|
+
@validation = validation
|
|
22
25
|
end
|
|
23
26
|
|
|
24
27
|
def visit(path)
|
|
@@ -43,14 +46,23 @@ module Interfacets
|
|
|
43
46
|
c("dom")
|
|
44
47
|
end
|
|
45
48
|
|
|
49
|
+
def timers
|
|
50
|
+
c("timer")
|
|
51
|
+
end
|
|
52
|
+
|
|
46
53
|
private
|
|
47
54
|
|
|
48
55
|
def js
|
|
49
56
|
@js ||= (
|
|
57
|
+
validation_engine = if contract_path
|
|
58
|
+
ValidationEngine.new(ComponentRegistry.load(contract_path), validation_mode: validation)
|
|
59
|
+
end
|
|
60
|
+
|
|
50
61
|
js_api = Test::Js::Receivers::Api.new(name: "interfacets:api", router:)
|
|
51
|
-
js_react = Test::Js::Receivers::React.new(name: "dom")
|
|
62
|
+
js_react = Test::Js::Receivers::React.new(name: "dom", validation_engine:)
|
|
52
63
|
js_url = Test::Js::Receivers::Url.new(name: "url")
|
|
53
|
-
|
|
64
|
+
js_timer = Test::Js::Receivers::Timer.new(name: "timer")
|
|
65
|
+
receivers = [js_api, js_react, js_url, js_timer]
|
|
54
66
|
|
|
55
67
|
TYPES.fetch(type).new(
|
|
56
68
|
receiver_index: receivers.map { [_1.name, _1] }.to_h,
|