From 4f0ebc964ada719728e0ae8c897349a4791aa78c Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Sat, 10 Jun 2023 13:07:54 -0700 Subject: [PATCH 1/3] Move to Ruby 3.0, and RSpec expect syntax --- .rubocop.yml | 12 +- lib/xpath/renderer.rb | 2 +- lib/xpath/union.rb | 2 +- spec/spec_helper.rb | 4 - spec/union_spec.rb | 16 +-- spec/xpath_spec.rb | 266 +++++++++++++++++++++--------------------- xpath.gemspec | 5 +- 7 files changed, 157 insertions(+), 150 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index d6d14ff..ec8519e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,10 +1,12 @@ require: - rubocop-rspec - rubocop-performance - + AllCops: DisabledByDefault: false - TargetRubyVersion: 2.5 + TargetRubyVersion: 3.0 + NewCops: enable + SuggestExtensions: false Exclude: - 'xpath.gemspec' @@ -123,6 +125,9 @@ Style/Documentation: Style/EvenOdd: Enabled: false +Style/QuotedSymbols: + Enabled: false + Lint/BooleanSymbol: Enabled: false @@ -149,3 +154,6 @@ RSpec/DescribeClass: RSpec/FilePath: Enabled: false + +RSpec/MultipleExpectations: + Enabled: false diff --git a/lib/xpath/renderer.rb b/lib/xpath/renderer.rb index af3f459..6d1d8aa 100644 --- a/lib/xpath/renderer.rb +++ b/lib/xpath/renderer.rb @@ -120,7 +120,7 @@ def with_element_conditions(expression, element_names) end def valid_xml_name?(name) - name =~ /^[a-zA-Z_:][a-zA-Z0-9_:.\-]*$/ + name =~ /^[a-zA-Z_:][a-zA-Z0-9_:.-]*$/ end end end diff --git a/lib/xpath/union.rb b/lib/xpath/union.rb index 68c5a24..59b9796 100644 --- a/lib/xpath/union.rb +++ b/lib/xpath/union.rb @@ -19,7 +19,7 @@ def each(&block) arguments.each(&block) end - def method_missing(*args) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing + def method_missing(*args) # rubocop:disable Style/MissingRespondToMissing XPath::Union.new(*arguments.map { |e| e.send(*args) }) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8f61314..ed995db 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,7 +2,3 @@ require 'xpath' require 'pry' - -RSpec.configure do |config| - config.expect_with(:rspec) { |c| c.syntax = :should } -end diff --git a/spec/union_spec.rb b/spec/union_spec.rb index 4eba7c5..f43fe7e 100644 --- a/spec/union_spec.rb +++ b/spec/union_spec.rb @@ -11,7 +11,7 @@ @expr1 = XPath.generate { |x| x.descendant(:p) } @expr2 = XPath.generate { |x| x.descendant(:div) } @collection = XPath::Union.new(@expr1, @expr2) - @collection.expressions.should eq [@expr1, @expr2] + expect(@collection.expressions).to eq [@expr1, @expr2] end end @@ -22,7 +22,7 @@ @collection = XPath::Union.new(@expr1, @expr2) exprs = [] @collection.each { |expr| exprs << expr } - exprs.should eq [@expr1, @expr2] + expect(exprs).to eq [@expr1, @expr2] end end @@ -31,7 +31,7 @@ @expr1 = XPath.generate { |x| x.descendant(:p) } @expr2 = XPath.generate { |x| x.descendant(:div) } @collection = XPath::Union.new(@expr1, @expr2) - @collection.map(&:expression).should eq %i[descendant descendant] + expect(@collection.map(&:expression)).to eq %i[descendant descendant] end end @@ -41,9 +41,9 @@ @expr2 = XPath.generate { |x| x.descendant(:div).where(x.attr(:id) == 'foo') } @collection = XPath::Union.new(@expr1, @expr2) @results = doc.xpath(@collection.to_xpath) - @results[0][:title].should eq 'fooDiv' - @results[1].text.should eq 'Blah' - @results[2].text.should eq 'Bax' + expect(@results[0][:title]).to eq 'fooDiv' + expect(@results[1].text).to eq 'Blah' + expect(@results[2].text).to eq 'Bax' end end @@ -55,9 +55,9 @@ @xpath1 = @collection.where(XPath.attr(:id) == 'foo').to_xpath @xpath2 = @collection.where(XPath.attr(:id) == 'fooDiv').to_xpath @results = doc.xpath(@xpath1) - @results[0][:title].should eq 'fooDiv' + expect(@results[0][:title]).to eq 'fooDiv' @results = doc.xpath(@xpath2) - @results[0][:id].should eq 'fooDiv' + expect(@results[0][:id]).to eq 'fooDiv' end end end diff --git a/spec/xpath_spec.rb b/spec/xpath_spec.rb index 2006cc5..ae18db3 100644 --- a/spec/xpath_spec.rb +++ b/spec/xpath_spec.rb @@ -22,14 +22,14 @@ def xpath(type = nil, &block) it 'should work as a mixin' do xpath = Thingy.new.foo_div.to_xpath - doc.xpath(xpath).first[:title].should eq 'fooDiv' + expect(doc.xpath(xpath).first[:title]).to eq 'fooDiv' end describe '#descendant' do it 'should find nodes that are nested below the current node' do @results = xpath { |x| x.descendant(:p) } - @results[0].text.should eq 'Blah' - @results[1].text.should eq 'Bax' + expect(@results[0].text).to eq 'Blah' + expect(@results[1].text).to eq 'Bax' end it 'should not find nodes outside the context' do @@ -37,76 +37,76 @@ def xpath(type = nil, &block) foo_div = x.descendant(:div).where(x.attr(:id) == 'foo') x.descendant(:p).where(x.attr(:id) == foo_div.attr(:title)) end - @results[0].should be_nil + expect(@results[0]).to be_nil end it 'should find multiple kinds of nodes' do @results = xpath { |x| x.descendant(:p, :ul) } - @results[0].text.should eq 'Blah' - @results[3].text.should eq 'A list' + expect(@results[0].text).to eq 'Blah' + expect(@results[3].text).to eq 'A list' end it 'should find all nodes when no arguments given' do @results = xpath { |x| x.descendant[x.attr(:id) == 'foo'].descendant } - @results[0].text.should eq 'Blah' - @results[4].text.should eq 'A list' + expect(@results[0].text).to eq 'Blah' + expect(@results[4].text).to eq 'A list' end end describe '#child' do it 'should find nodes that are nested directly below the current node' do @results = xpath { |x| x.descendant(:div).child(:p) } - @results[0].text.should eq 'Blah' - @results[1].text.should eq 'Bax' + expect(@results[0].text).to eq 'Blah' + expect(@results[1].text).to eq 'Bax' end it 'should not find nodes that are nested further down below the current node' do @results = xpath { |x| x.child(:p) } - @results[0].should be_nil + expect(@results[0]).to be_nil end it 'should find multiple kinds of nodes' do @results = xpath { |x| x.descendant(:div).child(:p, :ul) } - @results[0].text.should eq 'Blah' - @results[3].text.should eq 'A list' + expect(@results[0].text).to eq 'Blah' + expect(@results[3].text).to eq 'A list' end it 'should find all nodes when no arguments given' do @results = xpath { |x| x.descendant[x.attr(:id) == 'foo'].child } - @results[0].text.should eq 'Blah' - @results[3].text.should eq 'A list' + expect(@results[0].text).to eq 'Blah' + expect(@results[3].text).to eq 'A list' end end describe '#axis' do it 'should find nodes given the xpath axis' do @results = xpath { |x| x.axis(:descendant, :p) } - @results[0].text.should eq 'Blah' + expect(@results[0].text).to eq 'Blah' end it 'should find nodes given the xpath axis without a specific tag' do @results = xpath { |x| x.descendant(:div)[x.attr(:id) == 'foo'].axis(:descendant) } - @results[0][:id].should eq 'fooDiv' + expect(@results[0][:id]).to eq 'fooDiv' end end describe '#next_sibling' do it 'should find nodes which are immediate siblings of the current node' do - xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:p) }.first.text.should eq 'Bax' - xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:ul, :p) }.first.text.should eq 'Bax' - xpath { |x| x.descendant(:p)[x.attr(:title) == 'monkey'].next_sibling(:ul, :p) }.first.text.should eq 'A list' - xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:ul, :li) }.first.should be_nil - xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling }.first.text.should eq 'Bax' + expect(xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:p) }.first.text).to eq 'Bax' + expect(xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:ul, :p) }.first.text).to eq 'Bax' + expect(xpath { |x| x.descendant(:p)[x.attr(:title) == 'monkey'].next_sibling(:ul, :p) }.first.text).to eq 'A list' + expect(xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling(:ul, :li) }.first).to be_nil + expect(xpath { |x| x.descendant(:p)[x.attr(:id) == 'fooDiv'].next_sibling }.first.text).to eq 'Bax' end end describe '#previous_sibling' do it 'should find nodes which are exactly preceding the current node' do - xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:p) }.first.text.should eq 'Bax' - xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:ul, :p) }.first.text.should eq 'Bax' - xpath { |x| x.descendant(:p)[x.attr(:title) == 'gorilla'].previous_sibling(:ul, :p) }.first.text.should eq 'A list' - xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:ul, :li) }.first.should be_nil - xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling }.first.text.should eq 'Bax' + expect(xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:p) }.first.text).to eq 'Bax' + expect(xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:ul, :p) }.first.text).to eq 'Bax' + expect(xpath { |x| x.descendant(:p)[x.attr(:title) == 'gorilla'].previous_sibling(:ul, :p) }.first.text).to eq 'A list' + expect(xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling(:ul, :li) }.first).to be_nil + expect(xpath { |x| x.descendant(:p)[x.attr(:id) == 'wooDiv'].previous_sibling }.first.text).to eq 'Bax' end end @@ -116,7 +116,7 @@ def xpath(type = nil, &block) foo_div = x.anywhere(:div).where(x.attr(:id) == 'foo') x.descendant(:p).where(x.attr(:id) == foo_div.attr(:title)) end - @results[0].text.should eq 'Blah' + expect(@results[0].text).to eq 'Blah' end it 'should find multiple kinds of nodes regardless of the context' do @@ -125,10 +125,10 @@ def xpath(type = nil, &block) context.anywhere(:p, :ul) end - @results[0].text.should eq 'Blah' - @results[3].text.should eq 'A list' - @results[4].text.should eq 'A list' - @results[6].text.should eq 'Bax' + expect(@results[0].text).to eq 'Blah' + expect(@results[3].text).to eq 'A list' + expect(@results[4].text).to eq 'A list' + expect(@results[6].text).to eq 'Bax' end it 'should find all nodes when no arguments given regardless of the context' do @@ -136,13 +136,13 @@ def xpath(type = nil, &block) context = x.descendant(:div).where(x.attr(:id) == 'woo') context.anywhere end - @results[0].name.should eq 'html' - @results[1].name.should eq 'head' - @results[2].name.should eq 'body' - @results[6].text.should eq 'Blah' - @results[10].text.should eq 'A list' - @results[13].text.should eq 'A list' - @results[15].text.should eq 'Bax' + expect(@results[0].name).to eq 'html' + expect(@results[1].name).to eq 'head' + expect(@results[2].name).to eq 'body' + expect(@results[6].text).to eq 'Blah' + expect(@results[10].text).to eq 'A list' + expect(@results[13].text).to eq 'A list' + expect(@results[15].text).to eq 'Bax' end end @@ -151,7 +151,7 @@ def xpath(type = nil, &block) @results = xpath do |x| x.descendant(:div).where(x.attr(:title).contains('ooD')) end - @results[0][:id].should eq 'foo' + expect(@results[0][:id]).to eq 'foo' end it 'should find nodes that contain the given expression' do @@ -159,7 +159,7 @@ def xpath(type = nil, &block) expression = x.anywhere(:div).where(x.attr(:title) == 'fooDiv').attr(:id) x.descendant(:div).where(x.attr(:title).contains(expression)) end - @results[0][:id].should eq 'foo' + expect(@results[0][:id]).to eq 'foo' end end @@ -168,9 +168,9 @@ def xpath(type = nil, &block) @results = xpath do |x| x.descendant.where(x.attr(:class).contains_word('fish')) end - @results[0].text.should eq 'Bax' - @results[1].text.should eq 'llama' - @results.length.should eq 2 + expect(@results[0].text).to eq 'Bax' + expect(@results[1].text).to eq 'llama' + expect(@results.length).to eq 2 end end @@ -179,9 +179,9 @@ def xpath(type = nil, &block) @results = xpath do |x| x.descendant(:*).where(x.attr(:id).starts_with('foo')) end - @results.size.should eq 2 - @results[0][:id].should eq 'foo' - @results[1][:id].should eq 'fooDiv' + expect(@results.size).to eq 2 + expect(@results[0][:id]).to eq 'foo' + expect(@results[1][:id]).to eq 'fooDiv' end it 'should find nodes that contain the given expression' do @@ -189,7 +189,7 @@ def xpath(type = nil, &block) expression = x.anywhere(:div).where(x.attr(:title) == 'fooDiv').attr(:id) x.descendant(:div).where(x.attr(:title).starts_with(expression)) end - @results[0][:id].should eq 'foo' + expect(@results[0][:id]).to eq 'foo' end end @@ -198,9 +198,9 @@ def xpath(type = nil, &block) @results = xpath do |x| x.descendant(:*).where(x.attr(:id).ends_with('oof')) end - @results.size.should eq 2 - @results[0][:id].should eq 'oof' - @results[1][:id].should eq 'viDoof' + expect(@results.size).to eq 2 + expect(@results[0][:id]).to eq 'oof' + expect(@results[1][:id]).to eq 'viDoof' end it 'should find nodes that contain the given expression' do @@ -208,7 +208,7 @@ def xpath(type = nil, &block) expression = x.anywhere(:div).where(x.attr(:title) == 'viDoof').attr(:id) x.descendant(:div).where(x.attr(:title).ends_with(expression)) end - @results[0][:id].should eq 'oof' + expect(@results[0][:id]).to eq 'oof' end end @@ -217,7 +217,7 @@ def xpath(type = nil, &block) @results = xpath do |x| x.descendant(:div).where(x.attr(:title).uppercase == 'VIDOOF') end - @results[0][:id].should eq 'oof' + expect(@results[0][:id]).to eq 'oof' end end @@ -226,17 +226,17 @@ def xpath(type = nil, &block) @results = xpath do |x| x.descendant(:div).where(x.attr(:title).lowercase == 'vidoof') end - @results[0][:id].should eq 'oof' + expect(@results[0][:id]).to eq 'oof' end end describe '#text' do it "should select a node's text" do @results = xpath { |x| x.descendant(:p).where(x.text == 'Bax') } - @results[0].text.should eq 'Bax' - @results[1][:title].should eq 'monkey' + expect(@results[0].text).to eq 'Bax' + expect(@results[1][:title]).to eq 'monkey' @results = xpath { |x| x.descendant(:div).where(x.descendant(:p).text == 'Bax') } - @results[0][:title].should eq 'fooDiv' + expect(@results[0][:title]).to eq 'fooDiv' end end @@ -244,14 +244,14 @@ def xpath(type = nil, &block) context 'when called with one argument' do it 'should select the part of a string after the specified character' do @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == 'substring').text.substring(7) } - @results.should eq 'there' + expect(@results).to eq 'there' end end context 'when called with two arguments' do it 'should select the part of a string after the specified character, up to the given length' do @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == 'substring').text.substring(2, 4) } - @results.should eq 'ello' + expect(@results).to eq 'ello' end end end @@ -259,81 +259,81 @@ def xpath(type = nil, &block) describe '#function' do it 'should call the given xpath function' do @results = xpath { |x| x.function(:boolean, x.function(:true) == x.function(:false)) } - @results.should eq false + expect(@results).to be false end end describe '#method' do it 'should call the given xpath function with the current node as the first argument' do @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == 'string-length').text.method(:"string-length") } - @results.should eq 11 + expect(@results).to eq 11 end end describe '#string_length' do it 'should return the length of a string' do @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == 'string-length').text.string_length } - @results.should eq 11 + expect(@results).to eq 11 end end describe '#where' do it 'should limit the expression to find only certain nodes' do - xpath { |x| x.descendant(:div).where(:"@id = 'foo'") }.first[:title].should eq 'fooDiv' + expect(xpath { |x| x.descendant(:div).where(:"@id = 'foo'") }.first[:title]).to eq 'fooDiv' end it 'should be aliased as []' do - xpath { |x| x.descendant(:div)[:"@id = 'foo'"] }.first[:title].should eq 'fooDiv' + expect(xpath { |x| x.descendant(:div)[:"@id = 'foo'"] }.first[:title]).to eq 'fooDiv' end it 'should be a no-op when nil condition is passed' do - XPath.descendant(:div).where(nil).to_s.should eq './/div' + expect(XPath.descendant(:div).where(nil).to_s).to eq './/div' end end describe '#inverse' do it 'should invert the expression' do - xpath { |x| x.descendant(:p).where(x.attr(:id).equals('fooDiv').inverse) }.first.text.should eq 'Bax' + expect(xpath { |x| x.descendant(:p).where(x.attr(:id).equals('fooDiv').inverse) }.first.text).to eq 'Bax' end it 'should be aliased as the unary tilde' do - xpath { |x| x.descendant(:p).where(~x.attr(:id).equals('fooDiv')) }.first.text.should eq 'Bax' + expect(xpath { |x| x.descendant(:p).where(~x.attr(:id).equals('fooDiv')) }.first.text).to eq 'Bax' end it 'should be aliased as the unary bang' do - xpath { |x| x.descendant(:p).where(!x.attr(:id).equals('fooDiv')) }.first.text.should eq 'Bax' + expect(xpath { |x| x.descendant(:p).where(!x.attr(:id).equals('fooDiv')) }.first.text).to eq 'Bax' end end describe '#equals' do it 'should limit the expression to find only certain nodes' do - xpath { |x| x.descendant(:div).where(x.attr(:id).equals('foo')) }.first[:title].should eq 'fooDiv' + expect(xpath { |x| x.descendant(:div).where(x.attr(:id).equals('foo')) }.first[:title]).to eq 'fooDiv' end it 'should be aliased as ==' do - xpath { |x| x.descendant(:div).where(x.attr(:id) == 'foo') }.first[:title].should eq 'fooDiv' + expect(xpath { |x| x.descendant(:div).where(x.attr(:id) == 'foo') }.first[:title]).to eq 'fooDiv' end end describe '#not_equals' do it 'should match only when not equal' do - xpath { |x| x.descendant(:div).where(x.attr(:id).not_equals('bar')) }.first[:title].should eq 'fooDiv' + expect(xpath { |x| x.descendant(:div).where(x.attr(:id).not_equals('bar')) }.first[:title]).to eq 'fooDiv' end it 'should be aliased as !=' do - xpath { |x| x.descendant(:div).where(x.attr(:id) != 'bar') }.first[:title].should eq 'fooDiv' + expect(xpath { |x| x.descendant(:div).where(x.attr(:id) != 'bar') }.first[:title]).to eq 'fooDiv' end end describe '#is' do it 'uses equality when :exact given' do - xpath(:exact) { |x| x.descendant(:div).where(x.attr(:id).is('foo')) }.first[:title].should eq 'fooDiv' - xpath(:exact) { |x| x.descendant(:div).where(x.attr(:id).is('oo')) }.first.should be_nil + expect(xpath(:exact) { |x| x.descendant(:div).where(x.attr(:id).is('foo')) }.first[:title]).to eq 'fooDiv' + expect(xpath(:exact) { |x| x.descendant(:div).where(x.attr(:id).is('oo')) }.first).to be_nil end it 'uses substring matching otherwise' do - xpath { |x| x.descendant(:div).where(x.attr(:id).is('foo')) }.first[:title].should eq 'fooDiv' - xpath { |x| x.descendant(:div).where(x.attr(:id).is('oo')) }.first[:title].should eq 'fooDiv' + expect(xpath { |x| x.descendant(:div).where(x.attr(:id).is('foo')) }.first[:title]).to eq 'fooDiv' + expect(xpath { |x| x.descendant(:div).where(x.attr(:id).is('oo')) }.first[:title]).to eq 'fooDiv' end end @@ -343,9 +343,9 @@ def xpath(type = nil, &block) p = x.anywhere(:div).where(x.attr(:id) == 'foo').attr(:title) x.descendant(:*).where(x.attr(:id).one_of('foo', p, 'baz')) end - @results[0][:title].should eq 'fooDiv' - @results[1].text.should eq 'Blah' - @results[2][:title].should eq 'bazDiv' + expect(@results[0][:title]).to eq 'fooDiv' + expect(@results[1].text).to eq 'Blah' + expect(@results[2][:title]).to eq 'bazDiv' end end @@ -354,14 +354,14 @@ def xpath(type = nil, &block) @results = xpath do |x| x.descendant(:*).where(x.contains('Bax').and(x.attr(:title).equals('monkey'))) end - @results[0][:title].should eq 'monkey' + expect(@results[0][:title]).to eq 'monkey' end it 'should be aliased as ampersand (&)' do @results = xpath do |x| x.descendant(:*).where(x.contains('Bax') & x.attr(:title).equals('monkey')) end - @results[0][:title].should eq 'monkey' + expect(@results[0][:title]).to eq 'monkey' end end @@ -370,57 +370,57 @@ def xpath(type = nil, &block) @results = xpath do |x| x.descendant(:*).where(x.attr(:id).equals('foo').or(x.attr(:id).equals('fooDiv'))) end - @results[0][:title].should eq 'fooDiv' - @results[1].text.should eq 'Blah' + expect(@results[0][:title]).to eq 'fooDiv' + expect(@results[1].text).to eq 'Blah' end it 'should be aliased as pipe (|)' do @results = xpath do |x| x.descendant(:*).where(x.attr(:id).equals('foo') | x.attr(:id).equals('fooDiv')) end - @results[0][:title].should eq 'fooDiv' - @results[1].text.should eq 'Blah' + expect(@results[0][:title]).to eq 'fooDiv' + expect(@results[1].text).to eq 'Blah' end end describe '#attr' do it 'should be an attribute' do @results = xpath { |x| x.descendant(:div).where(x.attr(:id)) } - @results[0][:title].should eq 'barDiv' - @results[1][:title].should eq 'fooDiv' + expect(@results[0][:title]).to eq 'barDiv' + expect(@results[1][:title]).to eq 'fooDiv' end end describe '#css' do it 'should find nodes by the given CSS selector' do @results = xpath { |x| x.css('#preference p') } - @results[0].text.should eq 'allamas' - @results[1].text.should eq 'llama' + expect(@results[0].text).to eq 'allamas' + expect(@results[1].text).to eq 'llama' end it 'should respect previous expression' do @results = xpath { |x| x.descendant[x.attr(:id) == 'moar'].css('p') } - @results[0].text.should eq 'chimp' - @results[1].text.should eq 'flamingo' + expect(@results[0].text).to eq 'chimp' + expect(@results[1].text).to eq 'flamingo' end it 'should be composable' do @results = xpath { |x| x.css('#moar').descendant(:p) } - @results[0].text.should eq 'chimp' - @results[1].text.should eq 'flamingo' + expect(@results[0].text).to eq 'chimp' + expect(@results[1].text).to eq 'flamingo' end it 'should allow comma separated selectors' do @results = xpath { |x| x.descendant[x.attr(:id) == 'moar'].css('div, p') } - @results[0].text.should eq 'chimp' - @results[1].text.should eq 'elephant' - @results[2].text.should eq 'flamingo' + expect(@results[0].text).to eq 'chimp' + expect(@results[1].text).to eq 'elephant' + expect(@results[2].text).to eq 'flamingo' end end describe '#qname' do it "should match the node's name" do - xpath { |x| x.descendant(:*).where(x.qname == 'ul') }.first.text.should eq 'A list' + expect(xpath { |x| x.descendant(:*).where(x.qname == 'ul') }.first.text).to eq 'A list' end end @@ -432,9 +432,9 @@ def xpath(type = nil, &block) @xpath1 = @collection.where(XPath.attr(:id) == 'foo').to_xpath @xpath2 = @collection.where(XPath.attr(:id) == 'fooDiv').to_xpath @results = doc.xpath(@xpath1) - @results[0][:title].should eq 'fooDiv' + expect(@results[0][:title]).to eq 'fooDiv' @results = doc.xpath(@xpath2) - @results[0][:id].should eq 'fooDiv' + expect(@results[0][:id]).to eq 'fooDiv' end it 'should be aliased as +' do @@ -444,119 +444,119 @@ def xpath(type = nil, &block) @xpath1 = @collection.where(XPath.attr(:id) == 'foo').to_xpath @xpath2 = @collection.where(XPath.attr(:id) == 'fooDiv').to_xpath @results = doc.xpath(@xpath1) - @results[0][:title].should eq 'fooDiv' + expect(@results[0][:title]).to eq 'fooDiv' @results = doc.xpath(@xpath2) - @results[0][:id].should eq 'fooDiv' + expect(@results[0][:id]).to eq 'fooDiv' end end describe '#last' do it 'returns the number of elements in the context' do @results = xpath { |x| x.descendant(:p)[XPath.position == XPath.last] } - @results[0].text.should eq 'Bax' - @results[1].text.should eq 'Blah' - @results[2].text.should eq 'llama' + expect(@results[0].text).to eq 'Bax' + expect(@results[1].text).to eq 'Blah' + expect(@results[2].text).to eq 'llama' end end describe '#position' do it 'returns the position of elements in the context' do @results = xpath { |x| x.descendant(:p)[XPath.position == 2] } - @results[0].text.should eq 'Bax' - @results[1].text.should eq 'Bax' + expect(@results[0].text).to eq 'Bax' + expect(@results[1].text).to eq 'Bax' end end describe '#count' do it 'counts the number of occurrences' do @results = xpath { |x| x.descendant(:div)[x.descendant(:p).count == 2] } - @results[0][:id].should eq 'preference' + expect(@results[0][:id]).to eq 'preference' end end describe '#lte' do it 'checks lesser than or equal' do @results = xpath { |x| x.descendant(:p)[XPath.position <= 2] } - @results[0].text.should eq 'Blah' - @results[1].text.should eq 'Bax' - @results[2][:title].should eq 'gorilla' - @results[3].text.should eq 'Bax' + expect(@results[0].text).to eq 'Blah' + expect(@results[1].text).to eq 'Bax' + expect(@results[2][:title]).to eq 'gorilla' + expect(@results[3].text).to eq 'Bax' end end describe '#lt' do it 'checks lesser than' do @results = xpath { |x| x.descendant(:p)[XPath.position < 2] } - @results[0].text.should eq 'Blah' - @results[1][:title].should eq 'gorilla' + expect(@results[0].text).to eq 'Blah' + expect(@results[1][:title]).to eq 'gorilla' end end describe '#gte' do it 'checks greater than or equal' do @results = xpath { |x| x.descendant(:p)[XPath.position >= 2] } - @results[0].text.should eq 'Bax' - @results[1][:title].should eq 'monkey' - @results[2].text.should eq 'Bax' - @results[3].text.should eq 'Blah' + expect(@results[0].text).to eq 'Bax' + expect(@results[1][:title]).to eq 'monkey' + expect(@results[2].text).to eq 'Bax' + expect(@results[3].text).to eq 'Blah' end end describe '#gt' do it 'checks greater than' do @results = xpath { |x| x.descendant(:p)[XPath.position > 2] } - @results[0][:title].should eq 'monkey' - @results[1].text.should eq 'Blah' + expect(@results[0][:title]).to eq 'monkey' + expect(@results[1].text).to eq 'Blah' end end describe '#plus' do it 'adds stuff' do @results = xpath { |x| x.descendant(:p)[XPath.position.plus(1) == 2] } - @results[0][:id].should eq 'fooDiv' - @results[1][:title].should eq 'gorilla' + expect(@results[0][:id]).to eq 'fooDiv' + expect(@results[1][:title]).to eq 'gorilla' end end describe '#minus' do it 'subtracts stuff' do @results = xpath { |x| x.descendant(:p)[XPath.position.minus(1) == 0] } - @results[0][:id].should eq 'fooDiv' - @results[1][:title].should eq 'gorilla' + expect(@results[0][:id]).to eq 'fooDiv' + expect(@results[1][:title]).to eq 'gorilla' end end describe '#multiply' do it 'multiplies stuff' do @results = xpath { |x| x.descendant(:p)[XPath.position * 3 == 3] } - @results[0][:id].should eq 'fooDiv' - @results[1][:title].should eq 'gorilla' + expect(@results[0][:id]).to eq 'fooDiv' + expect(@results[1][:title]).to eq 'gorilla' end end describe '#divide' do it 'divides stuff' do @results = xpath { |x| x.descendant(:p)[XPath.position / 2 == 1] } - @results[0].text.should eq 'Bax' - @results[1].text.should eq 'Bax' + expect(@results[0].text).to eq 'Bax' + expect(@results[1].text).to eq 'Bax' end end describe '#mod' do it 'take modulo' do @results = xpath { |x| x.descendant(:p)[XPath.position % 2 == 1] } - @results[0].text.should eq 'Blah' - @results[1][:title].should eq 'monkey' - @results[2][:title].should eq 'gorilla' + expect(@results[0].text).to eq 'Blah' + expect(@results[1][:title]).to eq 'monkey' + expect(@results[2][:title]).to eq 'gorilla' end end describe '#ancestor' do it 'finds ancestor nodes' do @results = xpath { |x| x.descendant(:p)[1].ancestor } - @results[0].node_name.should eq 'html' - @results[1].node_name.should eq 'body' - @results[2][:id].should eq 'foo' + expect(@results[0].node_name).to eq 'html' + expect(@results[1].node_name).to eq 'body' + expect(@results[2][:id]).to eq 'foo' end end end diff --git a/xpath.gemspec b/xpath.gemspec index dd91680..1669674 100644 --- a/xpath.gemspec +++ b/xpath.gemspec @@ -7,7 +7,7 @@ require 'xpath/version' Gem::Specification.new do |s| s.name = 'xpath' s.version = XPath::VERSION - s.required_ruby_version = '>= 2.5' + s.required_ruby_version = '>= 3.0' s.authors = ['Jonas Nicklas'] s.email = ['jonas.nicklas@gmail.com'] @@ -24,6 +24,9 @@ Gem::Specification.new do |s| s.add_development_dependency('pry') s.add_development_dependency('rake') s.add_development_dependency('rspec', ['~> 3.0']) + s.add_development_dependency('rubocop') + s.add_development_dependency('rubocop-rspec') + s.add_development_dependency('rubocop-performance') s.add_development_dependency('yard', ['>= 0.5.8']) s.signing_key = 'gem-private_key.pem' if File.exist?('gem-private_key.pem') From bc7f9dbf238f2a2307b218fa9aa7027cb095c39d Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Sat, 10 Jun 2023 13:14:59 -0700 Subject: [PATCH 2/3] Use github actions --- .github/workflows/build.yml | 31 +++++++++++++++++++++++++++++++ .travis.yml | 13 ------------- 2 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..fbed829 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,31 @@ +# This workflow will download a prebuilt Ruby version, install dependencies and +# run tests with Rake +# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby + +name: Build + +"on": push + +env: + RUBYOPTS: "--disable-did-you-mean" + JAVA_OPTS: "-Djava.security.egd=file:/dev/urandom" + +jobs: + rake: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + ruby: ["3.0", "3.1", "3.2"] + + steps: + - uses: actions/checkout@v3 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Run tests + run: bundle exec rake diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index feb5b20..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -env: - global: - - JAVA_OPTS=-Djava.security.egd=file:/dev/urandom - -rvm: - - 2.5 - - 2.6 - - 2.7 - - jruby-9.2.12.0 - - -before_install: - - gem update bundler \ No newline at end of file From c26913a4a65c43cd2570679c6c5e6dfbdbe0aa55 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Sat, 10 Jun 2023 13:24:21 -0700 Subject: [PATCH 3/3] Add JRuby to test matrix --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbed829..79b7464 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,13 +11,13 @@ env: JAVA_OPTS: "-Djava.security.egd=file:/dev/urandom" jobs: - rake: + rspec: runs-on: ubuntu-latest strategy: fail-fast: false matrix: - ruby: ["3.0", "3.1", "3.2"] + ruby: ["3.0", "3.1", "3.2", "jruby"] steps: - uses: actions/checkout@v3