diff --git a/lib/puppet-languageserver/manifest/completion_provider.rb b/lib/puppet-languageserver/manifest/completion_provider.rb index 969e9ebc..1654644e 100644 --- a/lib/puppet-languageserver/manifest/completion_provider.rb +++ b/lib/puppet-languageserver/manifest/completion_provider.rb @@ -58,7 +58,7 @@ def self.complete(content, line_num, char_num, options = {}) item_object = PuppetLanguageServer::PuppetHelper.get_type(item.type_name.value) unless item_object.nil? # Add Parameters - item_object.parameters.each_key do |name| + item_object.attributes.select { |_name, data| data[:type] == :param }.each_key do |name| items << LSP::CompletionItem.new( 'label' => name.to_s, 'kind' => LSP::CompletionItemKind::PROPERTY, @@ -71,7 +71,7 @@ def self.complete(content, line_num, char_num, options = {}) ) end # Add Properties - item_object.properties.each_key do |name| + item_object.attributes.select { |_name, data| data[:type] == :property }.each_key do |name| items << LSP::CompletionItem.new( 'label' => name.to_s, 'kind' => LSP::CompletionItemKind::PROPERTY, @@ -249,7 +249,7 @@ def self.resolve(completion_item) # The param/property list should initially sorted alphabetically attr_names.sort! # Add the 'ensure' param/property at the top if the resource supports it - attr_names.insert(0, 'ensure') unless item_type.allattrs.find_index(:ensure).nil? + attr_names.insert(0, 'ensure') unless item_type.attributes.keys.find_index(:ensure).nil? # Get the longest string length for later hash-rocket padding max_length = -1 attr_names.each { |name| max_length = name.length if name.length > max_length } @@ -269,7 +269,7 @@ def self.resolve(completion_item) when 'resource_parameter' item_type = PuppetLanguageServer::PuppetHelper.get_type(data['resource_type']) return result if item_type.nil? - param_type = item_type.parameters[data['param'].intern] + param_type = item_type.attributes[data['param'].intern] unless param_type.nil? # TODO: More things? result.documentation = param_type[:doc] unless param_type[:doc].nil? @@ -278,7 +278,7 @@ def self.resolve(completion_item) when 'resource_property' item_type = PuppetLanguageServer::PuppetHelper.get_type(data['resource_type']) return result if item_type.nil? - prop_type = item_type.properties[data['prop'].intern] + prop_type = item_type.attributes[data['prop'].intern] unless prop_type.nil? # TODO: More things? result.documentation = prop_type[:doc] unless prop_type[:doc].nil? diff --git a/lib/puppet-languageserver/manifest/document_symbol_provider.rb b/lib/puppet-languageserver/manifest/document_symbol_provider.rb index 7c3fe8cf..7dffc87d 100644 --- a/lib/puppet-languageserver/manifest/document_symbol_provider.rb +++ b/lib/puppet-languageserver/manifest/document_symbol_provider.rb @@ -3,14 +3,14 @@ module PuppetLanguageServer module Manifest module DocumentSymbolProvider - def self.workspace_symbols(query) + def self.workspace_symbols(query, object_cache) query = '' if query.nil? result = [] - PuppetLanguageServer::PuppetHelper.all_objects do |key, item| + object_cache.all_objects do |key, item| key_string = key.to_s - next unless key_string.include?(query) + next unless query.empty? || key_string.include?(query) case item - when PuppetLanguageServer::PuppetHelper::PuppetType + when PuppetLanguageServer::Sidecar::Protocol::PuppetType result << LSP::SymbolInformation.new( 'name' => key_string, 'kind' => LSP::SymbolKind::METHOD, @@ -21,7 +21,7 @@ def self.workspace_symbols(query) } ) - when PuppetLanguageServer::PuppetHelper::PuppetFunction + when PuppetLanguageServer::Sidecar::Protocol::PuppetFunction result << LSP::SymbolInformation.new( 'name' => key_string, 'kind' => LSP::SymbolKind::FUNCTION, @@ -32,7 +32,7 @@ def self.workspace_symbols(query) } ) - when PuppetLanguageServer::PuppetHelper::PuppetClass + when PuppetLanguageServer::Sidecar::Protocol::PuppetClass result << LSP::SymbolInformation.new( 'name' => key_string, 'kind' => LSP::SymbolKind::CLASS, @@ -42,6 +42,9 @@ def self.workspace_symbols(query) 'range' => LSP.create_range(item.line, 0, item.line, 1024) } ) + + else + PuppetLanguageServer.log_message(:warn, "[Manifest::DocumentSymbolProvider] Unknown object type #{item.class}") end end result diff --git a/lib/puppet-languageserver/manifest/hover_provider.rb b/lib/puppet-languageserver/manifest/hover_provider.rb index dabfd3dc..30327431 100644 --- a/lib/puppet-languageserver/manifest/hover_provider.rb +++ b/lib/puppet-languageserver/manifest/hover_provider.rb @@ -49,10 +49,10 @@ def self.resolve(content, line_num, char_num, options = {}) resource_object = PuppetLanguageServer::PuppetHelper.get_type(resource_type_name) unless resource_object.nil? # Check if it's a property - attribute = resource_object.properties.key?(item.attribute_name.intern) - if attribute != false + attribute = resource_object.attributes[item.attribute_name.intern] + if attribute[:type] == :property content = get_attribute_type_property_content(resource_object, item.attribute_name.intern) - elsif resource_object.parameters.key?(item.attribute_name.intern) + elsif attribute[:type] == :param content = get_attribute_type_parameter_content(resource_object, item.attribute_name.intern) end end @@ -114,14 +114,14 @@ def self.get_fact_content(factname) end def self.get_attribute_type_parameter_content(item_type, param) - param_type = item_type.parameters[param] + param_type = item_type.attributes[param] content = "**#{param}** Parameter" content += "\n\n#{param_type[:doc]}" unless param_type[:doc].nil? content end def self.get_attribute_type_property_content(item_type, property) - prop_type = item_type.properties[property] + prop_type = item_type.attributes[property] content = "**#{property}** Property" content += "\n\n(_required_)" if prop_type[:required?] content += "\n\n#{prop_type[:doc]}" unless prop_type[:doc].nil? @@ -161,7 +161,7 @@ def self.get_puppet_type_content(item_type) content = "**#{item_type.key}** Resource\n\n" content += "\n\n#{item_type.doc}" unless item_type.doc.nil? content += "\n\n---\n" - item_type.allattrs.sort.each do |attr| + item_type.attributes.keys.sort.each do |attr| content += "* #{attr}\n" end diff --git a/lib/puppet-languageserver/message_router.rb b/lib/puppet-languageserver/message_router.rb index 7aeb2882..fc82166e 100644 --- a/lib/puppet-languageserver/message_router.rb +++ b/lib/puppet-languageserver/message_router.rb @@ -187,7 +187,12 @@ def receive_request(request) begin case documents.document_type(file_uri) when :manifest - request.reply_result(PuppetLanguageServer::Manifest::SignatureProvider.signature_help(content, line_num, char_num, :tasks_mode => PuppetLanguageServer::DocumentStore.module_plan_file?(file_uri))) + request.reply_result(PuppetLanguageServer::Manifest::SignatureProvider.signature_help( + content, + line_num, + char_num, + :tasks_mode => PuppetLanguageServer::DocumentStore.plan_file?(file_uri) + )) else raise "Unable to provide signatures on #{file_uri}" end @@ -199,7 +204,7 @@ def receive_request(request) when 'workspace/symbol' begin result = [] - result.concat(PuppetLanguageServer::Manifest::DocumentSymbolProvider.workspace_symbols(request.params['query'])) + result.concat(PuppetLanguageServer::Manifest::DocumentSymbolProvider.workspace_symbols(request.params['query'], PuppetLanguageServer::PuppetHelper.cache)) request.reply_result(result) rescue StandardError => e PuppetLanguageServer.log_message(:error, "(workspace/symbol) #{e}") diff --git a/lib/puppet-languageserver/puppet_helper.rb b/lib/puppet-languageserver/puppet_helper.rb index 7b256dfb..3977ae2c 100644 --- a/lib/puppet-languageserver/puppet_helper.rb +++ b/lib/puppet-languageserver/puppet_helper.rb @@ -3,7 +3,7 @@ require 'pathname' require 'tempfile' -%w[puppet_helper/cache_objects puppet_helper/cache].each do |lib| +%w[puppet_helper/cache].each do |lib| begin require "puppet-languageserver/#{lib}" rescue LoadError @@ -28,14 +28,6 @@ def self.initialize_helper(options = {}) sidecar_queue.cache = @inmemory_cache end - def self.all_objects(&_block) - return nil if @default_types_loaded == false - raise('Puppet Helper Cache has not been configured') if @inmemory_cache.nil? - @inmemory_cache.all_objects do |key, item| - yield key, item - end - end - # Node Graph def self.get_node_graph(content, local_workspace) with_temporary_file(content) do |filepath| @@ -174,8 +166,8 @@ def self.class_names @inmemory_cache.object_names_by_section(:class).map(&:to_s) end - # The object cache. Note this should only be used for testing def self.cache + raise('Puppet Helper Cache has not been configured') if @inmemory_cache.nil? @inmemory_cache end diff --git a/lib/puppet-languageserver/puppet_helper/cache.rb b/lib/puppet-languageserver/puppet_helper/cache.rb index a119e2ff..db29d5a0 100644 --- a/lib/puppet-languageserver/puppet_helper/cache.rb +++ b/lib/puppet-languageserver/puppet_helper/cache.rb @@ -3,36 +3,34 @@ module PuppetLanguageServer module PuppetHelper class Cache + SECTIONS = %i[class type function].freeze + ORIGINS = %i[default workspace].freeze + def initialize(_options = {}) @cache_lock = Mutex.new - @inmemory_cache = [] - # The cache consists of an array of module PuppetLanguageServer::PuppetHelper objects + @inmemory_cache = {} + # The cache consists of hash of hashes + # @inmemory_cache[][
] = [ Array of SidecarProtocol Objects ] end - def import_sidecar_list!(list, section, origin = nil) - section_object = section_to_object(section) - return if section_object.nil? + def import_sidecar_list!(list, section, origin) + return if origin.nil? + return if section.nil? list = [] if list.nil? @cache_lock.synchronize do # Remove the existing items - @inmemory_cache.reject! { |item| item.is_a?(section_object) && (origin.nil? || item.origin == origin) } - # Append the list - list.each do |item| - object = sidecar_protocol_to_cache_object(item) - object.origin = origin - @inmemory_cache << object - end + remove_section_impl(section, origin) + # Set the list + @inmemory_cache[origin] = {} if @inmemory_cache[origin].nil? + @inmemory_cache[origin][section] = list end nil end def remove_section!(section, origin = nil) - section_object = section_to_object(section) - return if section_object.nil? - @cache_lock.synchronize do - @inmemory_cache.reject! { |item| item.is_a?(section_object) && (origin.nil? || item.origin == origin) } + remove_section_impl(section, origin) end nil end @@ -40,12 +38,13 @@ def remove_section!(section, origin = nil) # section => def object_by_name(section, name) name = name.intern if name.is_a?(String) - section_object = section_to_object(section) - return nil if section_object.nil? + return nil if section.nil? @cache_lock.synchronize do - @inmemory_cache.each do |item| - next unless item.is_a?(section_object) && item.key == name - return item + @inmemory_cache.each do |_, sections| + next if sections[section].nil? || sections[section].empty? + sections[section].each do |item| + return item if item.key == name + end end end nil @@ -54,12 +53,11 @@ def object_by_name(section, name) # section => def object_names_by_section(section) result = [] - section_object = section_to_object(section) - return result if section_object.nil? + return result if section.nil? @cache_lock.synchronize do - @inmemory_cache.each do |item| - next unless item.is_a?(section_object) - result << item.key + @inmemory_cache.each do |_, sections| + next if sections[section].nil? || sections[section].empty? + result.concat(sections[section].map { |i| i.key }) end end result.uniq! @@ -68,44 +66,33 @@ def object_names_by_section(section) # section => def objects_by_section(section, &_block) - section_object = section_to_object(section) - return if section_object.nil? + return if section.nil? @cache_lock.synchronize do - @inmemory_cache.each do |item| - next unless item.is_a?(section_object) - yield item.key, item + @inmemory_cache.each do |_, sections| + next if sections[section].nil? || sections[section].empty? + sections[section].each { |i| yield i.key, i } end end end def all_objects(&_block) @cache_lock.synchronize do - @inmemory_cache.each do |item| - yield item.key, item + @inmemory_cache.each do |_origin, sections| + sections.each do |_section_name, list| + list.each { |i| yield i.key, i } + end end end end private - # - def section_to_object(section) - case section - when :class - PuppetLanguageServer::PuppetHelper::PuppetClass - when :function - PuppetLanguageServer::PuppetHelper::PuppetFunction - when :type - PuppetLanguageServer::PuppetHelper::PuppetType + def remove_section_impl(section, origin = nil) + @inmemory_cache.each do |list_origin, sections| + next unless origin.nil? || list_origin == origin + sections[section].clear unless sections[section].nil? end end - - def sidecar_protocol_to_cache_object(value) - return PuppetLanguageServer::PuppetHelper::PuppetClass.new.from_sidecar!(value) if value.is_a?(PuppetLanguageServer::Sidecar::Protocol::PuppetClass) - return PuppetLanguageServer::PuppetHelper::PuppetFunction.new.from_sidecar!(value) if value.is_a?(PuppetLanguageServer::Sidecar::Protocol::PuppetFunction) - return PuppetLanguageServer::PuppetHelper::PuppetType.new.from_sidecar!(value) if value.is_a?(PuppetLanguageServer::Sidecar::Protocol::PuppetType) - nil - end end end end diff --git a/lib/puppet-languageserver/puppet_helper/cache_objects.rb b/lib/puppet-languageserver/puppet_helper/cache_objects.rb deleted file mode 100644 index cf4a564c..00000000 --- a/lib/puppet-languageserver/puppet_helper/cache_objects.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -module PuppetLanguageServer - module PuppetHelper - module CacheExtensions - # origin is used to store where this cache entry came from, for example, workspace or - # default environment - attr_accessor :origin - - def from_sidecar!(value) - (value.class.instance_methods - Object.instance_methods).reject { |name| name.to_s.end_with?('=') || name.to_s.end_with?('!') } - .reject { |name| %i[to_h to_json].include?(name) } - .each do |method_name| - send("#{method_name}=", value.send(method_name)) - end - self - end - end - - class PuppetClass < PuppetLanguageServer::Sidecar::Protocol::PuppetClass - include CacheExtensions - end - - class PuppetFunction < PuppetLanguageServer::Sidecar::Protocol::PuppetFunction - include CacheExtensions - end - - class PuppetType < PuppetLanguageServer::Sidecar::Protocol::PuppetType - include CacheExtensions - - def allattrs - @attributes.keys - end - - def parameters - @attributes.select { |_name, data| data[:type] == :param } - end - - def properties - @attributes.select { |_name, data| data[:type] == :property } - end - - def meta_parameters - @attributes.select { |_name, data| data[:type] == :meta } - end - end - end -end diff --git a/spec/languageserver/integration/puppet-languageserver/manifest/completion_provider_spec.rb b/spec/languageserver/integration/puppet-languageserver/manifest/completion_provider_spec.rb index 38364a9e..44aa19f7 100644 --- a/spec/languageserver/integration/puppet-languageserver/manifest/completion_provider_spec.rb +++ b/spec/languageserver/integration/puppet-languageserver/manifest/completion_provider_spec.rb @@ -34,8 +34,8 @@ def retrieve_completion_response(label, kind) end end -def create_mock_resource(parameters = [], properties = []) - object = PuppetLanguageServer::PuppetHelper::PuppetType.new +def create_mock_type(parameters = [], properties = []) + object = PuppetLanguageServer::Sidecar::Protocol::PuppetType.new object.doc = 'mock documentation' object.attributes = {} parameters.each { |name| object.attributes[name] = { @@ -474,7 +474,7 @@ class Alice { } let(:line_num) { 0 } let(:char_num) { 0 } - let(:mock_resource) { create_mock_resource([:param1, :param2], [:prop1, :prop2]) } + let(:mock_resource) { create_mock_type([:param1, :param2], [:prop1, :prop2]) } before(:each) do # Generate the resolution request based on a completion response diff --git a/spec/languageserver/spec_helper.rb b/spec/languageserver/spec_helper.rb index 3a516145..9210dc1b 100644 --- a/spec/languageserver/spec_helper.rb +++ b/spec/languageserver/spec_helper.rb @@ -55,8 +55,9 @@ def add_random_basepuppetobject_values!(value) value end -def random_sidecar_puppet_class +def random_sidecar_puppet_class(key = nil) result = add_random_basepuppetobject_values!(PuppetLanguageServer::Sidecar::Protocol::PuppetClass.new()) + result.key = key unless key.nil? result.doc = 'doc' + rand(1000).to_s result.parameters = { "attr_name1" => { :type => "Optional[String]", :doc => 'attr_doc1' }, @@ -65,8 +66,9 @@ def random_sidecar_puppet_class result end -def random_sidecar_puppet_function +def random_sidecar_puppet_function(key = nil) result = add_random_basepuppetobject_values!(PuppetLanguageServer::Sidecar::Protocol::PuppetFunction.new()) + result.key = key unless key.nil? result.doc = 'doc' + rand(1000).to_s result.function_version = rand(1) + 3 result.signatures << random_sidecar_puppet_function_signature @@ -96,8 +98,9 @@ def random_sidecar_puppet_function_signature_parameter result end -def random_sidecar_puppet_type +def random_sidecar_puppet_type(key = nil) result = add_random_basepuppetobject_values!(PuppetLanguageServer::Sidecar::Protocol::PuppetType.new()) + result.key = key unless key.nil? result.doc = 'doc' + rand(1000).to_s result.attributes = { :attr_name1 => { :type => :attr_type, :doc => 'attr_doc1', :required? => false, :isnamevar? => true }, diff --git a/spec/languageserver/unit/puppet-languageserver/manifest/document_symbol_provider_spec.rb b/spec/languageserver/unit/puppet-languageserver/manifest/document_symbol_provider_spec.rb index 1ea6b60e..d6734b28 100644 --- a/spec/languageserver/unit/puppet-languageserver/manifest/document_symbol_provider_spec.rb +++ b/spec/languageserver/unit/puppet-languageserver/manifest/document_symbol_provider_spec.rb @@ -22,9 +22,56 @@ end end +RSpec::Matchers.define :be_symbol_information do |name, kind| + match do |actual| + actual.name == name && + actual.kind == kind + end + + failure_message do |actual| + "expected that symbol called '#{actual.name}' of type '#{actual.kind}' would be " + + "a symbol called '#{name}', of type '#{kind}'" + end + + description do + "be a document symbol called '#{name}' of type #{kind} located at #{start_line}, #{start_char}, #{end_line}, #{end_char}" + end +end + describe 'PuppetLanguageServer::Manifest::DocumentSymbolProvider' do let(:subject) { PuppetLanguageServer::Manifest::DocumentSymbolProvider } + describe '#workspace_symbols' do + let(:cache) { PuppetLanguageServer::PuppetHelper::Cache.new } + + before(:each) do + # Add test objects + origin = :default + cache.import_sidecar_list!([random_sidecar_puppet_class(:class1)], :class, origin) + cache.import_sidecar_list!([random_sidecar_puppet_function(:func1)], :function, origin) + cache.import_sidecar_list!([random_sidecar_puppet_type(:type1)], :type, origin) + end + + it 'should emit all known objects for an empty query' do + result = subject.workspace_symbols(nil, cache) + + expect(result[0]).to be_symbol_information('class1', LSP::SymbolKind::CLASS) + expect(result[1]).to be_symbol_information('func1', LSP::SymbolKind::FUNCTION) + expect(result[2]).to be_symbol_information('type1', LSP::SymbolKind::METHOD) + + all_cache_names = [] + cache.all_objects { |key, _| all_cache_names << key.to_s } + expect(result.count).to eq(all_cache_names.count) + end + + it 'should only emit objects that match a simple text query' do + result = subject.workspace_symbols('func', cache) + + expect(result.count).to eq(1) + expect(result[0]).to be_symbol_information('func1', LSP::SymbolKind::FUNCTION) + end + end + context 'with Puppet 4.0 and below', :if => Gem::Version.new(Puppet.version) < Gem::Version.new('5.0.0') do describe '#extract_document_symbols' do it 'should always return an empty array' do 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 deleted file mode 100644 index b9ef8caa..00000000 --- a/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_objects_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -require 'spec_helper' - -describe 'PuppetLanguageServer::PuppetHelper' do - - shared_examples_for 'a base Puppet object' do - [:key, :calling_source, :source, :line, :char, :length, :origin, :from_sidecar!].each do |testcase| - it "instance should respond to #{testcase}" do - expect(subject).to respond_to(testcase) - end - end - end - - describe 'PuppetClass' do - let(:subject) { PuppetLanguageServer::PuppetHelper::PuppetClass.new } - - let(:puppet_classname) { :rspec_class } - let(:sidecar_puppet_class) { random_sidecar_puppet_class } - - it_should_behave_like 'a base Puppet object' - - # No additional methods to test - [:doc, :parameters].each do |testcase| - it "instance should respond to #{testcase}" do - expect(subject).to respond_to(testcase) - end - end - - describe '#from_sidecar!' do - it 'should populate from a sidecar function object' do - subject.from_sidecar!(sidecar_puppet_class) - - expect(subject.key).to eq(sidecar_puppet_class.key) - expect(subject.calling_source).to eq(sidecar_puppet_class.calling_source) - expect(subject.source).to eq(sidecar_puppet_class.source) - expect(subject.line).to eq(sidecar_puppet_class.line) - expect(subject.char).to eq(sidecar_puppet_class.char) - expect(subject.length).to eq(sidecar_puppet_class.length) - end - end - end - - describe 'PuppetFunction' do - let(:subject) { PuppetLanguageServer::PuppetHelper::PuppetFunction.new } - - let(:sidecar_puppet_func) { random_sidecar_puppet_function } - - it_should_behave_like 'a base Puppet object' - - [:doc, :function_version, :signatures].each do |testcase| - it "instance should respond to #{testcase}" do - expect(subject).to respond_to(testcase) - end - end - - describe '#from_sidecar!' do - it 'should populate from a sidecar function object' do - subject.from_sidecar!(sidecar_puppet_func) - - expect(subject.key).to eq(sidecar_puppet_func.key) - expect(subject.calling_source).to eq(sidecar_puppet_func.calling_source) - expect(subject.source).to eq(sidecar_puppet_func.source) - expect(subject.line).to eq(sidecar_puppet_func.line) - 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.function_version).to eq(sidecar_puppet_func.function_version) - expect(subject.signatures).to eq(sidecar_puppet_func.signatures) - end - end - end - - describe 'PuppetType' do - let(:subject) { PuppetLanguageServer::PuppetHelper::PuppetType.new } - - let(:sidecar_puppet_type) { random_sidecar_puppet_type } - - it_should_behave_like 'a base Puppet object' - - [:doc, :attributes, :allattrs, :parameters, :properties, :meta_parameters].each do |testcase| - it "instance should respond to #{testcase}" do - expect(subject).to respond_to(testcase) - end - end - - describe '#from_sidecar!' do - it 'should populate from a sidecar type object' do - subject.from_sidecar!(sidecar_puppet_type) - - expect(subject.key).to eq(sidecar_puppet_type.key) - expect(subject.calling_source).to eq(sidecar_puppet_type.calling_source) - expect(subject.source).to eq(sidecar_puppet_type.source) - expect(subject.line).to eq(sidecar_puppet_type.line) - expect(subject.char).to eq(sidecar_puppet_type.char) - expect(subject.length).to eq(sidecar_puppet_type.length) - expect(subject.doc).to eq(sidecar_puppet_type.doc) - expect(subject.attributes).to eq(sidecar_puppet_type.attributes) - end - end - end -end diff --git a/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_spec.rb b/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_spec.rb index 21668d77..c54a7275 100644 --- a/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_spec.rb +++ b/spec/languageserver/unit/puppet-languageserver/puppet_helper/cache_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' describe 'PuppetLanguageServer::PuppetHelper::Cache' do - let(:section_existing) { :function } - let(:section_new) { :type } + let(:section_function) { :function } let(:origin_default) { :default } + let(:origin_workspace) { :workspace } let(:subject) { PuppetLanguageServer::PuppetHelper::Cache.new() } @@ -15,9 +15,9 @@ obj1.key = :func1 obj2 = random_sidecar_puppet_function obj2.key = :func2 - subject.import_sidecar_list!([obj1, obj2], section_existing, origin_default) + subject.import_sidecar_list!([obj1, obj2], section_function, origin_default) - expect(subject.object_names_by_section(section_existing)).to eq([:func1, :func2]) + expect(subject.object_names_by_section(section_function)).to eq([:func1, :func2]) end end @@ -36,10 +36,20 @@ obj4.key = :class4 obj5 = random_sidecar_puppet_class obj5.key = :class5 - subject.import_sidecar_list!([obj1, obj2], :function, origin_default) - subject.import_sidecar_list!([obj3], :class, origin_default) - subject.import_sidecar_list!([obj4], :class, origin_foo) - subject.import_sidecar_list!([obj5], :class, origin_bar) + + list = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionList.new + list << obj1 + list << obj2 + subject.import_sidecar_list!(list, :function, origin_default) + list = PuppetLanguageServer::Sidecar::Protocol::PuppetClassList.new + list << obj3 + subject.import_sidecar_list!(list, :class, origin_default) + list = PuppetLanguageServer::Sidecar::Protocol::PuppetClassList.new + list << obj4 + subject.import_sidecar_list!(list, :class, origin_foo) + list = PuppetLanguageServer::Sidecar::Protocol::PuppetClassList.new + list << obj5 + subject.import_sidecar_list!(list, :class, origin_bar) end it 'should not remove non-matching section' do @@ -82,23 +92,39 @@ func4 = random_sidecar_puppet_function func4.key = :func4 - subject.import_sidecar_list!([func1, func2, func3, func4], section_existing, origin_default) + class1 = random_sidecar_puppet_class + class1.key = :class1 + class2 = random_sidecar_puppet_class + class2.key = :class2 + + list = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionList.new + list << func1 + list << func2 + subject.import_sidecar_list!(list, section_function, origin_default) + list = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionList.new + list << func3 + list << func4 + subject.import_sidecar_list!(list, section_function, origin_workspace) + list = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionList.new + list << class1 + list << class2 + subject.import_sidecar_list!(list, :class, origin_workspace) end describe '#object_by_name' do it 'should get existing items from the cache' do - expect(subject.object_by_name(section_existing, :func1).key).to eq(:func1) + expect(subject.object_by_name(section_function, :func1).key).to eq(:func1) end it 'should return nil for objects that do not exist' do expect(subject.object_by_name(:doesnotexist, :func1)).to be_nil - expect(subject.object_by_name(section_existing, :doesnotexist)).to be_nil + expect(subject.object_by_name(section_function, :doesnotexist)).to be_nil end end describe '#object_names_by_section' do it 'should get existing items from the cache' do - expect(subject.object_names_by_section(section_existing)).to eq([:func1, :func2, :func3, :func4]) + expect(subject.object_names_by_section(section_function)).to eq([:func1, :func2, :func3, :func4]) end it 'should return empty array for objects that do not exist' do @@ -109,15 +135,23 @@ describe '#objects_by_section' do it 'should get existing items from the cache' do result = [] - subject.objects_by_section(section_existing) { |_name, obj| result << obj.key.to_s } + subject.objects_by_section(section_function) { |_name, obj| result << obj.key.to_s } expect(result).to eq(['func1', 'func2', 'func3', 'func4']) end - it 'should not yield for that do not exist' do + it 'should not yield for sections that do not exist' do result = [] subject.objects_by_section(:doesnotexist) { |_name, obj| result << obj } expect(result).to eq([]) end end + + describe '#all_objects' do + it 'should yield all objects in the cache' do + result = [] + subject.all_objects { |_name, obj| result << obj.key.to_s } + expect(result).to eq(['func1', 'func2', 'func3', 'func4', 'class1', 'class2']) + end + end end end