From 01b035b66adf53448ea8f07153ffdf2a9b0d330e Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Thu, 21 Feb 2019 13:04:34 -0600 Subject: [PATCH] [UNSTABLE] Corpus-level `value` types work. NEXT: Get `enum` and friends working --- app/lib/celery_script/checker.rb | 41 +++++++++++++++------------ app/lib/celery_script/corpus.rb | 35 +++++++++++++++++++---- spec/lib/celery_script/corpus_spec.rb | 4 +-- 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/app/lib/celery_script/checker.rb b/app/lib/celery_script/checker.rb index 6b4a2ad65..033b61aeb 100644 --- a/app/lib/celery_script/checker.rb +++ b/app/lib/celery_script/checker.rb @@ -54,10 +54,7 @@ module CeleryScript end def check_leaf(node) - allowed = corpus.values(node) - actual = node.value.class - - maybe_bad_leaf(node.kind, node.parent.kind, allowed, actual) + needs_new_name(node) end private @@ -89,7 +86,7 @@ module CeleryScript unless has_key msgs = node.args.keys.join(", ") msgs = "nothing" if msgs.length < 1 - msg = MISSING_ARG % [node.kind, arg, msgs] + msg = MISSING_ARG % [node.kind, arg, msgs] raise TypeCheckError, msg end end @@ -129,28 +126,36 @@ module CeleryScript end end - maybe_bad_leaf(value.kind, value.parent.kind, allowed, actual) + needs_new_name(value, key) end # This is where leaves get invalidated. # IDEA: Add a refinement to string class to allow it to quack like other # special classes. - def maybe_bad_leaf(kind, parent_kind, allowed, actual) - unless allowed.include?(actual) - message = (FRIENDLY_ERRORS.dig(kind, parent_kind) || BAD_LEAF) % { - kind: kind, - parent_kind: parent_kind, - allowed: allowed, - actual: actual - } - raise TypeCheckError, message + def needs_new_name(node, arg_key = nil) + case node + when CeleryScript::AstNode + print "🔥" + when CeleryScript::AstLeaf + allowed = corpus.fetchArg(node.kind).allowed_values + unless allowed.any? { |spec| spec.valid?(node, corpus) } + actual = node.value.class + kind = node.kind + parent_kind = node.parent.kind + + message = (FRIENDLY_ERRORS.dig(kind, parent_kind) || BAD_LEAF) % { + kind: kind, + parent_kind: parent_kind, + allowed: "[#{allowed.map(&:name).join(", ")}]", + actual: actual + } + raise TypeCheckError, message + end end end def validate_leaf_pairing(key, value) - actual = value.value.class - allowed = corpus.fetchArg(key).allowed_values - maybe_bad_leaf(value.kind, value.parent.kind, allowed, actual) + needs_new_name(value, key) end def bad_body_kind(prnt, child, i, ok) diff --git a/app/lib/celery_script/corpus.rb b/app/lib/celery_script/corpus.rb index 45ef5774e..5823e6f9e 100644 --- a/app/lib/celery_script/corpus.rb +++ b/app/lib/celery_script/corpus.rb @@ -4,16 +4,41 @@ module CeleryScript class Corpus class ArgAtom - attr_reader :value + attr_reader :value, :name def initialize(value) - raise "USE SYMBOLS!" unless value.is_a?(Symbol) @value = value + @name = value.to_s + end + end + + class Enum < ArgAtom + def valid?(node, corpus) + binding.pry + return false + end + end + + class Value < ArgAtom + def initialize(value) + super(value) + @name = @name.capitalize + end + + def valid?(node, corpus) + return corpus + .instance_variable_get(:@value_def_list) + .fetch(value) + .values + .include?(node.value.class) + end + end + + class Node < ArgAtom + def valid?(node, corpus) + return true end end - class Enum < ArgAtom; end - class Value < ArgAtom; end - class Node < ArgAtom; end ATOMS = [Enum, Value, Node] BAD_NODE_NAME = "Can't find validation rules for node " diff --git a/spec/lib/celery_script/corpus_spec.rb b/spec/lib/celery_script/corpus_spec.rb index 7cb86cd33..17573fc87 100644 --- a/spec/lib/celery_script/corpus_spec.rb +++ b/spec/lib/celery_script/corpus_spec.rb @@ -154,9 +154,7 @@ describe CeleryScript::Corpus do expect(checker.error.message).to include("not a valid message_type") end - it "Handles channel_name validations for version 1" do - # This test is __ONLY__ relevant for version 1. - # Change / delete / update as needed. + it "Handles channel_name validations" do tree = CeleryScript::AstNode.new({ "kind": "send_message", "args": {