• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ruby-rdf / json-ld / 10152630656

29 Jul 2024 10:13PM UTC coverage: 82.898%. Remained the same
10152630656

push

github

gkellogg
Finish 3.3.2

2826 of 3409 relevant lines covered (82.9%)

1236.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

60.27
/lib/json/ld/html/rexml.rb
1
# frozen_string_literal: true
2

3
require 'htmlentities'
2✔
4

5
module JSON
2✔
6
  module LD
2✔
7
    class API
2✔
8
      ##
9
      # REXML implementation of an XML parser.
10
      #
11
      # @see http://www.germane-software.com/software/rexml/
12
      module REXML
2✔
13
        ##
14
        # Returns the name of the underlying XML library.
15
        #
16
        # @return [Symbol]
17
        def self.library
2✔
18
          :rexml
×
19
        end
20

21
        # Proxy class to implement uniform element accessors
22
        class NodeProxy
2✔
23
          attr_reader :node, :parent
2✔
24

25
          def initialize(node, parent = nil)
2✔
26
            @node = node
66✔
27
            @parent = parent
66✔
28
          end
29

30
          ##
31
          # Return xml:base on element, if defined
32
          #
33
          # @return [String]
34
          def base
2✔
35
            @node.attribute("base", RDF::XML.to_s) || @node.attribute('xml:base')
×
36
          end
37

38
          def display_path
2✔
39
            @display_path ||= begin
×
40
              path = []
×
41
              path << parent.display_path if parent
×
42
              path << @node.name
×
43
              case @node
×
44
              when ::REXML::Element   then path.join("/")
×
45
              when ::REXML::Attribute then path.join("@")
×
46
              else path.join("?")
×
47
              end
48
            end
49
          end
50

51
          ##
52
          # Return true of all child elements are text
53
          #
54
          # @return [Array<:text, :element, :attribute>]
55
          def text_content?
2✔
56
            @node.children.all?(::REXML::Text)
×
57
          end
58

59
          ##
60
          # Children of this node
61
          #
62
          # @return [NodeSetProxy]
63
          def children
2✔
64
            NodeSetProxy.new(@node.children, self)
×
65
          end
66

67
          # Ancestors of this element, in order
68
          def ancestors
2✔
69
            @ancestors ||= parent ? parent.ancestors + [parent] : []
×
70
          end
71

72
          ##
73
          # Inner text of an element
74
          #
75
          # @see http://apidock.com/ruby/REXML/Element/get_text#743-Get-all-inner-texts
76
          # @return [String]
77
          def inner_text
2✔
78
            coder = HTMLEntities.new
×
79
            ::REXML::XPath.match(@node, './/text()').map do |e|
×
80
              coder.decode(e)
×
81
            end.join
82
          end
83

84
          ##
85
          # Inner text of an element
86
          #
87
          # @see http://apidock.com/ruby/REXML/Element/get_text#743-Get-all-inner-texts
88
          # @return [String]
89
          def inner_html
2✔
90
            @node.children.map(&:to_s).join
26✔
91
          end
92

93
          def attribute_nodes
2✔
94
            attrs = @node.attributes.dup.keep_if do |name, _attr|
×
95
              !name.start_with?('xmlns')
×
96
            end
97
            @attribute_nodes ||= (attrs.empty? ? attrs : NodeSetProxy.new(attrs, self))
×
98
          end
99

100
          ##
101
          # Node type accessors
102
          #
103
          # @return [Boolean]
104
          def text?
2✔
105
            @node.is_a?(::REXML::Text)
×
106
          end
107

108
          def element?
2✔
109
            @node.is_a?(::REXML::Element)
×
110
          end
111

112
          def blank?
2✔
113
            @node.is_a?(::REXML::Text) && @node.empty?
×
114
          end
115

116
          def to_s
2✔
117
            @node.to_s
4✔
118
          end
119

120
          def xpath(*args)
2✔
121
            ::REXML::XPath.match(@node, *args).map do |n|
64✔
122
              NodeProxy.new(n, parent)
34✔
123
            end
124
          end
125

126
          def at_xpath(*args)
2✔
127
            xpath(*args).first
58✔
128
          end
129

130
          ##
131
          # Proxy for everything else to @node
132
          def method_missing(method, *args)
2✔
133
            @node.send(method, *args)
6✔
134
          end
135
        end
136

137
        ##
138
        # NodeSet proxy
139
        class NodeSetProxy
2✔
140
          attr_reader :node_set, :parent
2✔
141

142
          def initialize(node_set, parent)
2✔
143
            @node_set = node_set
×
144
            @parent = parent
×
145
          end
146

147
          ##
148
          # Return a proxy for each child
149
          #
150
          # @yield child
151
          # @yieldparam [NodeProxy]
152
          def each
2✔
153
            @node_set.each do |c|
×
154
              yield NodeProxy.new(c, parent)
×
155
            end
156
          end
157

158
          ##
159
          def to_html
2✔
160
            node_set.map(&:to_s).join
×
161
          end
162

163
          ##
164
          # Proxy for everything else to @node_set
165
          def method_missing(method, *args)
2✔
166
            @node_set.send(method, *args)
×
167
          end
168
        end
169

170
        ##
171
        # Initializes the underlying XML library.
172
        #
173
        # @param  [Hash{Symbol => Object}] options
174
        # @return [NodeProxy] of document root
175
        def initialize_html_rexml(input, _options = {})
2✔
176
          require 'rexml/document' unless defined?(::REXML)
32✔
177
          doc = case input
32✔
178
          when ::REXML::Document
179
            input
×
180
          else
181
            # Only parse as XML, no HTML mode
182
            ::REXML::Document.new(input.respond_to?(:read) ? input.read : input.to_s)
32✔
183
          end
184

185
          NodeProxy.new(doc.root) if doc&.root
32✔
186
        end
187
        alias initialize_html initialize_html_rexml
2✔
188
      end
189
    end
190
  end
191
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc