Updates to corpus + generator.
parent
8b79fdd866
commit
9399ad7f27
|
@ -232,7 +232,12 @@ module CeleryScriptSettingsBag
|
|||
end,
|
||||
},
|
||||
package: {
|
||||
defn: [e(:ALLOWED_PACKAGES)],
|
||||
defn: [v(:string)],
|
||||
# `package` has an ambiguous intent depending on who is using the arg
|
||||
# (FBOS vs. API). Corpus-native enums cannot be used for validation
|
||||
# outside of the API. If `package` _was_ declared as a native enum (rather
|
||||
# than a string), it would cause false type errors in FE/FBJS.
|
||||
blk: -> (node) { manual_enum(ALLOWED_PACKAGES, node, BAD_PACKAGE) },
|
||||
},
|
||||
axis: {
|
||||
defn: [e(:ALLOWED_AXIS)],
|
||||
|
@ -281,12 +286,13 @@ module CeleryScriptSettingsBag
|
|||
change_ownership: {
|
||||
body: [:pair],
|
||||
tags: [:function, :network_user, :disk_user, :cuts_power, :api_writer],
|
||||
docs: "Not a commonly used node. May be removed without notice."
|
||||
blk: -> (node) { raise "Never." },
|
||||
docs: "Not a commonly used node. May be removed without notice.",
|
||||
},
|
||||
channel: {
|
||||
args: [:channel_name],
|
||||
tags: [:data],
|
||||
docs: "Specifies a communication path for log messages."
|
||||
docs: "Specifies a communication path for log messages.",
|
||||
},
|
||||
check_updates: {
|
||||
args: [:package],
|
||||
|
@ -294,11 +300,11 @@ module CeleryScriptSettingsBag
|
|||
},
|
||||
coordinate: {
|
||||
args: [:x, :y, :z],
|
||||
tags: [:data, :location_like]
|
||||
tags: [:data, :location_like],
|
||||
},
|
||||
dump_info: {
|
||||
tags: [:function, :network_user, :disk_user, :api_writer],
|
||||
docs: "Sends an info dump to server administrators for troubleshooting."
|
||||
docs: "Sends an info dump to server administrators for troubleshooting.",
|
||||
},
|
||||
emergency_lock: {
|
||||
tags: [:function, :firmware_user, :control_flow],
|
||||
|
@ -309,7 +315,7 @@ module CeleryScriptSettingsBag
|
|||
every_point: {
|
||||
args: [:every_point_type],
|
||||
tags: [:data, :list_like, :control_flow],
|
||||
docs: "Experimental node used for iteration."
|
||||
docs: "Experimental node used for iteration.",
|
||||
},
|
||||
execute_script: {
|
||||
args: [:label],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
WARNING_HEADER = \
|
||||
WARNING_HEADER =
|
||||
"" "
|
||||
// THIS INTERFACE WAS AUTO GENERATED ON #{Date.today}
|
||||
// DO NOT EDIT THIS FILE.
|
||||
|
@ -24,15 +24,15 @@ ARGS = HASH
|
|||
end
|
||||
NODES = HASH.fetch(:nodes)
|
||||
NODE_START = ["export type %{camel_case}BodyItem = %{body_types};",
|
||||
"/** %{docs} %{tag_docs} */",
|
||||
"/** %{snake_case}\n%{docs}\n %{tag_docs} */",
|
||||
"export interface %{camel_case} {",
|
||||
" comment?: string | undefined;",
|
||||
' kind: "%{snake_case}";',
|
||||
" args: {", ].join("\n")
|
||||
" args: {"].join("\n")
|
||||
MIDDLE_CENTER = " %{arg_name}: %{arg_values};"
|
||||
BOTTOM_END = [" }",
|
||||
" body?: %{camel_case}BodyItem[] | undefined;",
|
||||
"}\n", ].join("\n")
|
||||
"}\n"].join("\n")
|
||||
CONSTANT_DECLR_HACK = {
|
||||
LATEST_VERSION: Sequence::LATEST_VERSION,
|
||||
DIGITAL: CeleryScriptSettingsBag::DIGITAL,
|
||||
|
@ -40,6 +40,8 @@ CONSTANT_DECLR_HACK = {
|
|||
}
|
||||
CONSTANT_DECLR_HACK_TPL = "export const %{name} = %{value};\n"
|
||||
PUBLIC_NODES = [] # Filled at runtime
|
||||
PIPE = " |\n"
|
||||
|
||||
def emit_constants()
|
||||
CONSTANT_DECLR_HACK.map do |(name, value)|
|
||||
konst = CONSTANT_DECLR_HACK_TPL % { name: name, value: value }
|
||||
|
@ -77,7 +79,7 @@ end
|
|||
def emit_enums
|
||||
output = ENUMS.map do |enum|
|
||||
name = name_of(enum)
|
||||
type = enum.fetch("allowed_values").sort.map(&:inspect).uniq.join(" | ")
|
||||
type = enum.fetch("allowed_values").sort.map(&:inspect).uniq.join(PIPE)
|
||||
FUNNY_NAMES[name] = name
|
||||
ENUM_TPL % { name: name, type: type }
|
||||
end
|
||||
|
@ -100,14 +102,14 @@ def emit_nodes()
|
|||
.uniq
|
||||
.map(&:to_s)
|
||||
.map(&:camelize)
|
||||
bt = bodies.any? ? "(#{bodies.join(" | ")})" : "never"
|
||||
bt = bodies.any? ? "(#{bodies.join(PIPE)})" : "never"
|
||||
PUBLIC_NODES.push(name.camelize)
|
||||
tpl_binding = {
|
||||
body_types: bt,
|
||||
camel_case: name.camelize,
|
||||
docs: node.fetch("docs"),
|
||||
snake_case: name,
|
||||
tag_docs: "Tag properties: #{tag_list}."
|
||||
tag_docs: "Tag properties: #{tag_list}.",
|
||||
}
|
||||
|
||||
one = NODE_START % tpl_binding
|
||||
|
@ -118,7 +120,7 @@ def emit_nodes()
|
|||
.fetch("allowed_values")
|
||||
.map(&:name)
|
||||
.map { |x| FUNNY_NAMES[x] || x.camelize }
|
||||
.join(" | ")
|
||||
.join(PIPE),
|
||||
}
|
||||
end
|
||||
three = BOTTOM_END % tpl_binding
|
||||
|
@ -131,10 +133,11 @@ def emit_nodes()
|
|||
end
|
||||
|
||||
def emit_misc()
|
||||
types = PUBLIC_NODES.sort.uniq.join(" | ")
|
||||
types = PUBLIC_NODES.sort.uniq.join(PIPE)
|
||||
tpl = "export type CeleryNode = #{types};\n"
|
||||
add_to_output(tpl)
|
||||
end
|
||||
|
||||
emit_constants()
|
||||
emit_values()
|
||||
emit_enums()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require 'spec_helper'
|
||||
require "spec_helper"
|
||||
|
||||
describe CeleryScript::Checker do
|
||||
let(:device) { FactoryBot.create(:device) }
|
||||
|
@ -7,10 +7,10 @@ describe CeleryScript::Checker do
|
|||
kind: "sequence",
|
||||
args: {
|
||||
locals: Sequence::SCOPE_DECLARATION,
|
||||
version: 0
|
||||
version: 0,
|
||||
},
|
||||
comment: "Properly formatted, syntactically valid sequence.",
|
||||
body: sequence_body_for(FakeSequence.create())
|
||||
body: sequence_body_for(FakeSequence.create()),
|
||||
}.deep_symbolize_keys
|
||||
end
|
||||
|
||||
|
@ -57,7 +57,7 @@ describe CeleryScript::Checker do
|
|||
expect(checker.run).to be_kind_of(CeleryScript::TypeCheckError)
|
||||
end
|
||||
|
||||
it 'handles wrong leaf types' do
|
||||
it "handles wrong leaf types" do
|
||||
hash[:body][0][:args][:location][:args][:x] = "supposed to be an Integer"
|
||||
result = checker.run
|
||||
expect(result.message).to eq("Expected leaf 'x' within 'coordinate' to be " \
|
||||
|
@ -76,10 +76,8 @@ describe CeleryScript::Checker do
|
|||
{ kind: "execute", args: { sequence_id: 0 } },
|
||||
]
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
expect(chk.valid?)
|
||||
.to be false
|
||||
expect(chk.error.message)
|
||||
.to eq("missing a sequence selection for `execute` block.")
|
||||
expect(chk.valid?).to be false
|
||||
expect(chk.error.message).to eq("missing a sequence selection for `execute` block.")
|
||||
end
|
||||
|
||||
it "validates peripheral presence" do
|
||||
|
@ -91,13 +89,13 @@ describe CeleryScript::Checker do
|
|||
kind: "named_pin",
|
||||
args: {
|
||||
pin_type: "Peripheral",
|
||||
pin_id: 0
|
||||
}
|
||||
pin_id: 0,
|
||||
},
|
||||
},
|
||||
pin_mode: CeleryScriptSettingsBag::ANALOG,
|
||||
label: "FOO"
|
||||
}
|
||||
}
|
||||
label: "FOO",
|
||||
},
|
||||
},
|
||||
]
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
expect(chk.valid?).to be false
|
||||
|
@ -113,10 +111,10 @@ describe CeleryScript::Checker do
|
|||
label: "pin",
|
||||
pin_number: {
|
||||
kind: "named_pin",
|
||||
args: { pin_type: "Not correct", pin_id: 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
args: { pin_type: "Not correct", pin_id: 1 },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
expect(chk.valid?).to be false
|
||||
|
@ -132,10 +130,10 @@ describe CeleryScript::Checker do
|
|||
label: "pin",
|
||||
pin_number: {
|
||||
kind: "named_pin",
|
||||
args: { pin_type: "Peripheral", pin_id: 900 }
|
||||
}
|
||||
}
|
||||
}
|
||||
args: { pin_type: "Peripheral", pin_id: 900 },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
expect(chk.valid?).to be false
|
||||
|
@ -151,10 +149,10 @@ describe CeleryScript::Checker do
|
|||
pin_mode: 0,
|
||||
pin_number: {
|
||||
kind: "named_pin",
|
||||
args: { pin_type: ["BoxLed3", "BoxLed4"].sample, pin_id: 41 }
|
||||
}
|
||||
}
|
||||
}
|
||||
args: { pin_type: ["BoxLed3", "BoxLed4"].sample, pin_id: 41 },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
expect(chk.valid?).to be true
|
||||
|
@ -169,17 +167,16 @@ describe CeleryScript::Checker do
|
|||
pin_mode: CeleryScriptSettingsBag::ANALOG,
|
||||
pin_number: {
|
||||
kind: "named_pin",
|
||||
args: { pin_type: ["BoxLed3", "BoxLed4"].sample, pin_id: 41 }
|
||||
}
|
||||
}
|
||||
}
|
||||
args: { pin_type: ["BoxLed3", "BoxLed4"].sample, pin_id: 41 },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
expect(chk.valid?).to be false
|
||||
expect(chk.error.message).to include(CeleryScriptSettingsBag::CANT_ANALOG)
|
||||
end
|
||||
|
||||
|
||||
it 'gives human-friendly names to "BoxLed3", "BoxLed4"' do
|
||||
hash[:body] = [
|
||||
{
|
||||
|
@ -189,21 +186,20 @@ describe CeleryScript::Checker do
|
|||
pin_mode: CeleryScriptSettingsBag::DIGITAL,
|
||||
pin_number: {
|
||||
kind: "named_pin",
|
||||
args: { pin_type: ["BoxLed3", "BoxLed4"].sample, pin_id: 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
args: { pin_type: ["BoxLed3", "BoxLed4"].sample, pin_id: 0 },
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
expect(chk.valid?).to be false
|
||||
expected = \
|
||||
expected =
|
||||
CeleryScriptSettingsBag::NO_PIN_ID % CeleryScriptSettingsBag::BoxLed.name
|
||||
expect(chk.error.message).to eq(expected)
|
||||
end
|
||||
|
||||
|
||||
it "catches bad `axis` nodes" do
|
||||
t = \
|
||||
t =
|
||||
CeleryScript::AstNode.new({ kind: "home", args: { speed: 100, axis: "?" } })
|
||||
chk = CeleryScript::Checker.new(t, corpus, device)
|
||||
expect(chk.valid?).to be false
|
||||
|
@ -211,8 +207,7 @@ describe CeleryScript::Checker do
|
|||
end
|
||||
|
||||
it "catches bad `package` nodes" do
|
||||
t = \
|
||||
CeleryScript::AstNode.new({ kind: "factory_reset", args: { package: "?" }})
|
||||
t = CeleryScript::AstNode.new({ kind: "factory_reset", args: { package: "?" } })
|
||||
chk = CeleryScript::Checker.new(t, corpus, device)
|
||||
expect(chk.valid?).to be false
|
||||
expect(chk.error.message).to include("not a valid package")
|
||||
|
@ -233,11 +228,12 @@ describe CeleryScript::Checker do
|
|||
label: "parent",
|
||||
default_value: {
|
||||
kind: "coordinate",
|
||||
args: { x: 0, y: 0, z: 0 } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
args: { x: 0, y: 0, z: 0 },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
body: [
|
||||
{
|
||||
|
@ -245,10 +241,10 @@ describe CeleryScript::Checker do
|
|||
args: {
|
||||
speed: 100,
|
||||
location: { kind: "identifier", args: { label: "parent" } },
|
||||
offset: { kind: "coordinate", args: { x: 0, y: 0, z: 0} }
|
||||
}
|
||||
}
|
||||
]
|
||||
offset: { kind: "coordinate", args: { x: 0, y: 0, z: 0 } },
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
tree = CeleryScript::AstNode.new(ast)
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
|
@ -270,12 +266,12 @@ describe CeleryScript::Checker do
|
|||
label: "parent",
|
||||
default_value: {
|
||||
kind: "nothing",
|
||||
args: { }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
args: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
body: [
|
||||
{
|
||||
|
@ -283,10 +279,10 @@ describe CeleryScript::Checker do
|
|||
args: {
|
||||
speed: 100,
|
||||
location: { kind: "identifier", args: { label: "parent" } },
|
||||
offset: { kind: "coordinate", args: { x: 0, y: 0, z: 0} }
|
||||
}
|
||||
}
|
||||
]
|
||||
offset: { kind: "coordinate", args: { x: 0, y: 0, z: 0 } },
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
tree = CeleryScript::AstNode.new(ast)
|
||||
chk = CeleryScript::Checker.new(tree, corpus, device)
|
||||
|
|
Loading…
Reference in New Issue