From 5dfc8aeacf15ab4db0181b6a4c0a3802207ad9f0 Mon Sep 17 00:00:00 2001 From: Glenn Sarti Date: Sun, 9 Jun 2019 19:55:13 +0800 Subject: [PATCH] (GH-141) Change Puppet Function information in Sidecar to support V4 API Previously the Puppet Function information retrieved over the Sidecar Protocol only supported the older V3 Function API. This commit updates the Protocol to now be able to transmit V4 function information. V3 information is expected to be adapted into its equivalent in V4. This commit: * Removes the deprecated arity and type methods and adds function_version and signatures. Where signatures are the function method signatures expressed as a PuppetFunctionSignatureList object * Adds a PuppetFunctionSignature and PuppetFunctionSignatureList object which captures all of the properties of Puppet Function V4 API method signature. The PuppetFunctionSignatureList object is a "typed" array of PuppetFunctionSignature objects * Adds a PuppetFunctionSignatureParameter and PuppetFunctionSignatureParameterList object which captures all of the properties of Puppet Function V4 API method signature parameter. The PuppetFunctionSignatureParameterList object is a "typed" array of PuppetFunctionSignatureParameter objects * Updates the spec_helper to be able to create mock objects for functions, function signatures and function signature parameters * Updates the sidecar protocol tests for the modified parameters and newly added classes * Updates the in-memory cache object tests for the modified parameters of a Function. At this point the protocol now only accepts V4 Function API information. Later commits will modify the Sidecar and Language Server to generate and consume the new information respectively. --- lib/puppet-languageserver/sidecar_protocol.rb | 78 ++++++++++-- spec/languageserver/spec_helper.rb | 24 +++- .../puppet_helper/cache_objects_spec.rb | 6 +- .../sidecar_protocol_spec.rb | 111 +++++++++++++++++- 4 files changed, 202 insertions(+), 17 deletions(-) diff --git a/lib/puppet-languageserver/sidecar_protocol.rb b/lib/puppet-languageserver/sidecar_protocol.rb index 86c508bb..dcd0ee58 100644 --- a/lib/puppet-languageserver/sidecar_protocol.rb +++ b/lib/puppet-languageserver/sidecar_protocol.rb @@ -191,17 +191,20 @@ def child_type class PuppetFunction < BasePuppetObject attr_accessor :doc - attr_accessor :arity - attr_accessor :type # The version of this function, typically 3 or 4. attr_accessor :function_version + attr_accessor :signatures + + def initialize + super + self.signatures = PuppetFunctionSignatureList.new + end def to_h super.to_h.merge( 'doc' => doc, - 'arity' => arity, - 'type' => type, - 'function_version' => function_version + 'function_version' => function_version, + 'signatures' => signatures ) end @@ -209,9 +212,8 @@ def from_h!(value) super self.doc = value['doc'] - self.arity = value['arity'] - self.type = value['type'].intern self.function_version = value['function_version'] + value['signatures'].each { |sig| signatures << PuppetFunctionSignature.new.from_h!(sig) } unless value['signatures'].nil? self end end @@ -222,6 +224,68 @@ def child_type end end + class PuppetFunctionSignature < BaseClass + attr_accessor :key + attr_accessor :doc + attr_accessor :return_types + attr_accessor :parameters + + def initialize + super + self.parameters = PuppetFunctionSignatureParameterList.new + end + + def to_h + { + 'key' => key, + 'doc' => doc, + 'return_types' => return_types, + 'parameters' => parameters + } + end + + def from_h!(value) + self.key = value['key'] + self.doc = value['doc'] + self.return_types = value['return_types'] + value['parameters'].each { |param| parameters << PuppetFunctionSignatureParameter.new.from_h!(param) } unless value['parameters'].nil? + self + end + end + + class PuppetFunctionSignatureList < BasePuppetObjectList + def child_type + PuppetFunctionSignature + end + end + + class PuppetFunctionSignatureParameter < BaseClass + attr_accessor :name + attr_accessor :types + attr_accessor :doc + + def to_h + { + 'name' => name, + 'doc' => doc, + 'types' => types + } + end + + def from_h!(value) + self.name = value['name'] + self.doc = value['doc'] + self.types = value['types'] + self + end + end + + class PuppetFunctionSignatureParameterList < BasePuppetObjectList + def child_type + PuppetFunctionSignatureParameter + end + end + class PuppetType < BasePuppetObject attr_accessor :doc attr_accessor :attributes diff --git a/spec/languageserver/spec_helper.rb b/spec/languageserver/spec_helper.rb index dfe4795b..a071d9a1 100644 --- a/spec/languageserver/spec_helper.rb +++ b/spec/languageserver/spec_helper.rb @@ -68,9 +68,29 @@ def random_sidecar_puppet_class def random_sidecar_puppet_function result = add_random_basepuppetobject_values!(PuppetLanguageServer::Sidecar::Protocol::PuppetFunction.new()) result.doc = 'doc' + rand(1000).to_s - result.arity = rand(1000) - result.type = ('type' + rand(1000).to_s).intern result.function_version = rand(1) + 3 + result.signatures << random_sidecar_puppet_function_signature + result.signatures << random_sidecar_puppet_function_signature + result.signatures << random_sidecar_puppet_function_signature + result +end + +def random_sidecar_puppet_function_signature + result = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignature.new + result.key = 'key' + + rand(1000).to_s + '(a,b,c)' + result.doc = 'doc' + rand(1000).to_s + result.return_types = [rand(1000).to_s, rand(1000).to_s, rand(1000).to_s] + result.parameters << random_sidecar_puppet_function_signature_parameter + result.parameters << random_sidecar_puppet_function_signature_parameter + result.parameters << random_sidecar_puppet_function_signature_parameter + result +end + +def random_sidecar_puppet_function_signature_parameter + result = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignatureParameter.new + result.name = 'param' + rand(1000).to_s + result.types = [rand(1000).to_s, rand(1000).to_s] + result.doc = result.name + ' documentation' result end diff --git a/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_objects_spec.rb b/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_objects_spec.rb index 4826723e..b9ef8caa 100644 --- a/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_objects_spec.rb +++ b/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_objects_spec.rb @@ -46,7 +46,7 @@ it_should_behave_like 'a base Puppet object' - [:doc, :arity, :type].each do |testcase| + [:doc, :function_version, :signatures].each do |testcase| it "instance should respond to #{testcase}" do expect(subject).to respond_to(testcase) end @@ -63,8 +63,8 @@ expect(subject.char).to eq(sidecar_puppet_func.char) expect(subject.length).to eq(sidecar_puppet_func.length) expect(subject.doc).to eq(sidecar_puppet_func.doc) - expect(subject.arity).to eq(sidecar_puppet_func.arity) - expect(subject.type).to eq(sidecar_puppet_func.type) + expect(subject.function_version).to eq(sidecar_puppet_func.function_version) + expect(subject.signatures).to eq(sidecar_puppet_func.signatures) end end end diff --git a/spec/languageserver/unit/puppet-languageserver/sidecar_protocol_spec.rb b/spec/languageserver/unit/puppet-languageserver/sidecar_protocol_spec.rb index 8aaea921..071f3c40 100644 --- a/spec/languageserver/unit/puppet-languageserver/sidecar_protocol_spec.rb +++ b/spec/languageserver/unit/puppet-languageserver/sidecar_protocol_spec.rb @@ -55,7 +55,9 @@ basepuppetobject_properties = [:key, :calling_source, :source, :line, :char, :length] nodegraph_properties = [:dot_content, :error_content] puppetclass_properties = [:doc, :parameters] - puppetfunction_properties = [:doc, :arity, :type, :function_version] + puppetfunction_properties = [:doc, :function_version, :signatures] + puppetfunctionsignature_properties = [:key, :doc, :return_types, :parameters] + puppetfunctionsignatureparameter_properties = [:name, :types, :doc] puppettype_properties = [:doc, :attributes] resource_properties = [:manifest] @@ -190,8 +192,11 @@ let(:subject) { value = subject_klass.new value.doc = 'doc' - value.arity = 'arity' - value.type = :type + value.function_version = 4 + value.signatures = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignatureList.new + value.signatures << random_sidecar_puppet_function_signature + value.signatures << random_sidecar_puppet_function_signature + value.signatures << random_sidecar_puppet_function_signature add_default_basepuppetobject_values!(value) } @@ -229,11 +234,107 @@ it_should_behave_like 'a serializable object list' - it "instance should have a childtype of PuppetClass" do + it "instance should have a childtype of PuppetClass" do # TODO This is a typo expect(subject.child_type).to eq(PuppetLanguageServer::Sidecar::Protocol::PuppetFunction) end end + describe 'PuppetFunctionSignature' do + let(:subject_klass) { PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignature } + let(:subject) { + value = subject_klass.new + value.key = 'something(Any a, String[1,1] b' + value.doc = 'doc' + value.return_types = ['Any', 'Undef'] + value.parameters << random_sidecar_puppet_function_signature_parameter + value.parameters << random_sidecar_puppet_function_signature_parameter + value + } + + puppetfunctionsignature_properties.each do |testcase| + it "instance should respond to #{testcase}" do + expect(subject).to respond_to(testcase) + end + end + + describe '#from_json!' do + (puppetfunctionsignature_properties).each do |testcase| + it "should deserialize a serialized #{testcase} value" do + serial = subject.to_json + deserial = subject_klass.new.from_json!(serial) + + expect(deserial.send(testcase)).to eq(subject.send(testcase)) + end + end + end + end + + describe 'PuppetFunctionSignatureList' do + let(:subject_klass) { PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignatureList } + let(:subject) { + value = subject_klass.new + value << random_sidecar_puppet_function_signature + value << random_sidecar_puppet_function_signature + value << random_sidecar_puppet_function_signature + value + } + + it_should_behave_like 'a base Sidecar Protocol Puppet object list' + + it_should_behave_like 'a serializable object list' + + it "instance should have a childtype of PuppetFunctionSignature" do + expect(subject.child_type).to eq(PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignature) + end + end + + describe 'PuppetFunctionSignatureParameter' do + let(:subject_klass) { PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignatureParameter } + let(:subject) { + value = subject_klass.new + value.name = 'param1' + value.types = ['Undef'] + value.doc = 'doc' + value + } + + puppetfunctionsignatureparameter_properties.each do |testcase| + it "instance should respond to #{testcase}" do + expect(subject).to respond_to(testcase) + end + end + + describe '#from_json!' do + (puppetfunctionsignatureparameter_properties).each do |testcase| + it "should deserialize a serialized #{testcase} value" do + serial = subject.to_json + deserial = subject_klass.new.from_json!(serial) + + expect(deserial.send(testcase)).to eq(subject.send(testcase)) + end + end + end + end + + describe 'PuppetFunctionSignatureParameterList' do + let(:subject_klass) { PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignatureParameterList } + let(:subject) { + value = subject_klass.new + value << random_sidecar_puppet_function_signature_parameter + value << random_sidecar_puppet_function_signature_parameter + value << random_sidecar_puppet_function_signature_parameter + value + } + + it_should_behave_like 'a base Sidecar Protocol Puppet object list' + + it_should_behave_like 'a serializable object list' + + it "instance should have a childtype of PuppetFunctionSignatureParameter" do + expect(subject.child_type).to eq(PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionSignatureParameter) + end + end + describe 'PuppetType' do let(:subject_klass) { PuppetLanguageServer::Sidecar::Protocol::PuppetType } let(:subject) { @@ -280,7 +381,7 @@ it_should_behave_like 'a serializable object list' - it "instance should have a childtype of PuppetClass" do + it "instance should have a childtype of PuppetClass" do #TODO: Typo expect(subject.child_type).to eq(PuppetLanguageServer::Sidecar::Protocol::PuppetType) end end