From 3300a6df49bd00c36ffbcfbe34acbabd06956850 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Wed, 8 Jul 2015 00:56:05 +0200 Subject: [PATCH] Added XPath::Compiler.compile_with_cache --- lib/oga/xpath/compiler.rb | 12 ++++++++++++ spec/oga/xpath/compiler_spec.rb | 30 ++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/lib/oga/xpath/compiler.rb b/lib/oga/xpath/compiler.rb index 1872b0e..56e275f 100644 --- a/lib/oga/xpath/compiler.rb +++ b/lib/oga/xpath/compiler.rb @@ -9,9 +9,21 @@ module Oga # recompiling the same expression over and over again. # class Compiler + # @return [Oga::LRU] + CACHE = LRU.new + # Wildcard for node names/namespace prefixes. STAR = '*' + ## + # Compiles and caches an AST. + # + # @see [#compile] + # + def self.compile_with_cache(ast) + CACHE.get_or_set(ast) { new.compile(ast) } + end + ## # Compiles an XPath AST into a Ruby Proc. # diff --git a/spec/oga/xpath/compiler_spec.rb b/spec/oga/xpath/compiler_spec.rb index 3e4f372..c5b5954 100644 --- a/spec/oga/xpath/compiler_spec.rb +++ b/spec/oga/xpath/compiler_spec.rb @@ -5,6 +5,32 @@ describe Oga::XPath::Compiler do @compiler = described_class.new end + describe 'compile_with_cache' do + before do + described_class::CACHE.clear + end + + it 'returns a Proc as a lambda' do + ast = parse_xpath('foo') + block = described_class.compile_with_cache(ast) + + block.should be_an_instance_of(Proc) + block.lambda?.should == true + end + + it 'caches a compiled Proc' do + ast = parse_xpath('foo') + + described_class.any_instance + .should_receive(:compile) + .once + .and_call_original + + described_class.compile_with_cache(ast).should be_an_instance_of(Proc) + described_class.compile_with_cache(ast).should be_an_instance_of(Proc) + end + end + describe '#compile' do it 'returns a Proc as a lambda' do ast = parse_xpath('foo') @@ -21,10 +47,6 @@ describe Oga::XPath::Compiler do @compiler.compile(ast).arity.should == 1 end - xit 'caches a compiled Proc for a given XPath AST' do - # TODO - end - describe 'calling the compiled Proc' do it 'returns a NodeSet' do doc = parse('')