| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with this |
| # work for additional information regarding copyright ownership. The ASF |
| # licenses this file to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| |
| require 'rexml/document' |
| require 'rexml/element' |
| |
| module RSpec |
| module Matchers |
| |
| # check if the xpath exists one or more times |
| class HaveXpath |
| def initialize(xpath) |
| @xpath = xpath |
| end |
| |
| def matches?(response) |
| @response = response |
| doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response) |
| match = REXML::XPath.match(doc, @xpath) |
| !match.empty? |
| end |
| |
| def failure_message |
| "Did not find expected xpath #{@xpath}" |
| end |
| |
| def negative_failure_message |
| "Did find unexpected xpath #{@xpath}" |
| end |
| |
| def description |
| "match the xpath expression #{@xpath}" |
| end |
| end |
| |
| def have_xpath(xpath) |
| HaveXpath.new(xpath) |
| end |
| |
| # check if the xpath has the specified value |
| # value is a string and there must be a single result to match its |
| # equality against |
| class MatchXpath |
| def initialize(xpath, val) |
| @xpath = xpath |
| @val= val |
| end |
| |
| def matches?(response) |
| @response = response |
| doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response) |
| ok = false |
| REXML::XPath.each(doc, @xpath) do |e| |
| @actual_val = case e |
| when REXML::Attribute |
| e.to_s |
| when REXML::Element |
| e.text |
| else |
| e.to_s |
| end |
| ok = true |
| return false unless @val == @actual_val |
| end |
| return true if !ok && @val.nil? |
| return ok |
| end |
| |
| def failure_message |
| "The xpath #{@xpath} did not have the value #{@val.inspect} it was #{@actual_val.inspect}" |
| end |
| |
| def description |
| "match the xpath expression #{@xpath} with #{@val}" |
| end |
| end |
| |
| def match_xpath(xpath, val) |
| MatchXpath.new(xpath, val) |
| end |
| |
| # checks if the given xpath occurs num times |
| class HaveNodes #:nodoc: |
| def initialize(xpath, num) |
| @xpath= xpath |
| @num = num |
| end |
| |
| def matches?(response) |
| @response = response |
| doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response) |
| match = REXML::XPath.match(doc, @xpath) |
| @num_found= match.size |
| @num_found == @num |
| end |
| |
| def failure_message |
| "Did not find expected number of nodes #{@num} in xpath #{@xpath} Found #{@num_found}" |
| end |
| |
| def description |
| "match the number of nodes #{@num}" |
| end |
| end |
| |
| def have_nodes(xpath, num) |
| HaveNodes.new(xpath, num) |
| end |
| |
| end |
| end |