C0 code coverage information
Generated on Fri Jul 11 15:55:35 -0700 2008 with rcov 0.7.0
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # This file contains functions and classes used for extracting
2 # endpoint information out of a Yadis XRD file using the REXML
3 # XML parser.
4
5 #
6 module OpenID
7 module Yadis
8 class BasicServiceEndpoint
9 attr_reader :type_uris, :yadis_url, :uri, :service_element
10
11 # Generic endpoint object that contains parsed service
12 # information, as well as a reference to the service element
13 # from which it was generated. If there is more than one
14 # xrd:Type or xrd:URI in the xrd:Service, this object represents
15 # just one of those pairs.
16 #
17 # This object can be used as a filter, because it implements
18 # fromBasicServiceEndpoint.
19 #
20 # The simplest kind of filter you can write implements
21 # fromBasicServiceEndpoint, which takes one of these objects.
22 def initialize(yadis_url, type_uris, uri, service_element)
23 @type_uris = type_uris
24 @yadis_url = yadis_url
25 @uri = uri
26 @service_element = service_element
27 end
28
29 # Query this endpoint to see if it has any of the given type
30 # URIs. This is useful for implementing other endpoint classes
31 # that e.g. need to check for the presence of multiple
32 # versions of a single protocol.
33 def match_types(type_uris)
34 return @type_uris & type_uris
35 end
36
37 # Trivial transform from a basic endpoint to itself. This
38 # method exists to allow BasicServiceEndpoint to be used as a
39 # filter.
40 #
41 # If you are subclassing this object, re-implement this function.
42 def self.from_basic_service_endpoint(endpoint)
43 return endpoint
44 end
45
46 # A hack to make both this class and its instances respond to
47 # this message since Ruby doesn't support static methods.
48 def from_basic_service_endpoint(endpoint)
49 return self.class.from_basic_service_endpoint(endpoint)
50 end
51
52 end
53
54 # Take a list of basic filters and makes a filter that
55 # transforms the basic filter into a top-level filter. This is
56 # mostly useful for the implementation of make_filter, which
57 # should only be needed for special cases or internal use by
58 # this library.
59 #
60 # This object is useful for creating simple filters for services
61 # that use one URI and are specified by one Type (we expect most
62 # Types will fit this paradigm).
63 #
64 # Creates a BasicServiceEndpoint object and apply the filter
65 # functions to it until one of them returns a value.
66 class TransformFilterMaker
67 attr_reader :filter_procs
68
69 # Initialize the filter maker's state
70 #
71 # filter_functions are the endpoint transformer
72 # Procs to apply to the basic endpoint. These are called in
73 # turn until one of them does not return nil, and the result
74 # of that transformer is returned.
75 def initialize(filter_procs)
76 @filter_procs = filter_procs
77 end
78
79 # Returns an array of endpoint objects produced by the
80 # filter procs.
81 def get_service_endpoints(yadis_url, service_element)
82 endpoints = []
83
84 # Do an expansion of the service element by xrd:Type and
85 # xrd:URI
86 Yadis::expand_service(service_element).each { |type_uris, uri, _|
87 # Create a basic endpoint object to represent this
88 # yadis_url, Service, Type, URI combination
89 endpoint = BasicServiceEndpoint.new(
90 yadis_url, type_uris, uri, service_element)
91
92 e = apply_filters(endpoint)
93 if !e.nil?
94 endpoints << e
95 end
96 }
97 return endpoints
98 end
99
100 def apply_filters(endpoint)
101 # Apply filter procs to an endpoint until one of them returns
102 # non-nil.
103 @filter_procs.each { |filter_proc|
104 e = filter_proc.call(endpoint)
105 if !e.nil?
106 # Once one of the filters has returned an endpoint, do not
107 # apply any more.
108 return e
109 end
110 }
111
112 return nil
113 end
114 end
115
116 class CompoundFilter
117 attr_reader :subfilters
118
119 # Create a new filter that applies a set of filters to an
120 # endpoint and collects their results.
121 def initialize(subfilters)
122 @subfilters = subfilters
123 end
124
125 # Generate all endpoint objects for all of the subfilters of
126 # this filter and return their concatenation.
127 def get_service_endpoints(yadis_url, service_element)
128 endpoints = []
129 @subfilters.each { |subfilter|
130 endpoints += subfilter.get_service_endpoints(yadis_url, service_element)
131 }
132 return endpoints
133 end
134 end
135
136 # Exception raised when something is not able to be turned into a
137 # filter
138 @@filter_type_error = TypeError.new(
139 'Expected a filter, an endpoint, a callable or a list of any of these.')
140
141 # Convert a filter-convertable thing into a filter
142 #
143 # parts should be a filter, an endpoint, a callable, or a list of
144 # any of these.
145 def self.make_filter(parts)
146 # Convert the parts into a list, and pass to mk_compound_filter
147 if parts.nil?
148 parts = [BasicServiceEndpoint]
149 end
150
151 if parts.is_a?(Array)
152 return mk_compound_filter(parts)
153 else
154 return mk_compound_filter([parts])
155 end
156 end
157
158 # Create a filter out of a list of filter-like things
159 #
160 # Used by make_filter
161 #
162 # parts should be a list of things that can be passed to make_filter
163 def self.mk_compound_filter(parts)
164
165 if !parts.respond_to?('each')
166 raise TypeError, "#{parts.inspect} is not iterable"
167 end
168
169 # Separate into a list of callables and a list of filter objects
170 transformers = []
171 filters = []
172 parts.each { |subfilter|
173 if !subfilter.is_a?(Array)
174 # If it's not an iterable
175 if subfilter.respond_to?('get_service_endpoints')
176 # It's a full filter
177 filters << subfilter
178 elsif subfilter.respond_to?('from_basic_service_endpoint')
179 # It's an endpoint object, so put its endpoint conversion
180 # attribute into the list of endpoint transformers
181 transformers << subfilter.method('from_basic_service_endpoint')
182 elsif subfilter.respond_to?('call')
183 # It's a proc, so add it to the list of endpoint
184 # transformers
185 transformers << subfilter
186 else
187 raise @@filter_type_error
188 end
189 else
190 filters << mk_compound_filter(subfilter)
191 end
192 }
193
194 if transformers.length > 0
195 filters << TransformFilterMaker.new(transformers)
196 end
197
198 if filters.length == 1
199 return filters[0]
200 else
201 return CompoundFilter.new(filters)
202 end
203 end
204 end
205 end
Generated using the rcov code coverage analysis tool for Ruby version 0.7.0.