Bee C0 Coverage Information - RCov

lib/bee_context.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
lib/bee_context.rb 201 130
100.00%
100.00%

Key

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.

Coverage Details

1 # Copyright 2006-2012 Michel Casabianca <michel.casabianca@gmail.com>
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 require 'rubygems'
16 require 'bee_util'
17 require 'bee_properties'
18 
19 module Bee
20 
21   # Class for build context where properties live as local variables and where
22   # all scripts (from context or in Ruby tasks) are evaluated.
23   class Context
24 
25     include Bee::Util::BuildErrorMixin
26 
27     # The context binding
28     attr_reader :context_binding
29 
30     # Constructor.
31     # - properties: properties as a hash that gives expression for a given
32     #   property.
33     # - scripts: list of script files to run in context.
34     def initialize(properties={}, scripts=[])
35       @context_binding = get_binding
36       @properties = properties
37       @scripts = scripts
38     end
39 
40     # Evaluate properties and scripts in the context. Should run while running
41     # the build, not while loading it.
42     def evaluate
43       evaluate_default_properties
44       evaluate_scripts
45       evaluate_properties
46     end
47 
48     # Return the list of properties (that is the list of local variables of
49     # context) as an unsorted list of strings.
50     def properties
51       return eval('local_variables', @context_binding).map{|var| var.to_s}
52     end
53 
54     # Set a given property in context.
55     # - name: the property name as a string or symbol.
56     # - value: the property value as an object.
57     def set_property(name, value)
58       begin
59         eval("#{name} = #{value.inspect}", @context_binding)
60       rescue Exception
61         error "Error setting property '#{name} = #{value.inspect}': #{$!}"
62       end
63     end
64 
65     # Get a given property in context. Raises an error if the property was not
66     # set.
67     # - name: the property name.
68     def get_property(name)
69       begin
70         eval("#{name}", @context_binding)
71       rescue NameError
72         error "Property '#{name}' was not set"
73       rescue Exception
74         error "Error getting property '#{name}': #{$!}"
75       end
76     end
77 
78     # Evaluate a script in context.
79     # - source: source of the script to evaluate.
80     def evaluate_script(source)
81       eval(source, @context_binding)
82     end
83 
84     # Process a given object, replacing properties references with their
85     # string value, symbol with their raw value. Property references have
86     # same form than variable references in ruby strings: '#{variable}'
87     # will be replaced with variable string value.
88     # - object: object to process.
89     def evaluate_object(object)
90       case object
91       when NilClass
92         # nil: return nil
93         return nil
94       when String
95         # string: replace embedded Ruby expressions
96         object = object.gsub(/#\{.+?\}/) do |match|
97           expression = match[2..-2]
98           begin
99             value = eval(expression, @context_binding)
100           rescue
101             error "Error evaluating expression '#{expression}': #{$!}"
102           end
103           value
104         end
105         return object 
106       when Symbol
107         # symbol: return property object
108         property = object.to_s
109         begin
110           value = eval("#{property}", @context_binding)
111         rescue
112           error "Property '#{property}' was not set"
113         end
114         return evaluate_object(value)
115       when Array
116         # array: evaluate each element
117         return object.collect { |element| evaluate_object(element) }
118       when Hash
119         # hash: evaluate all keys and values
120         evaluated = {}
121         object.each_pair do |key, value| 
122           evaluated[evaluate_object(key)] = evaluate_object(value)
123         end
124         return evaluated
125       else
126         return object
127       end
128     end
129 
130     private
131 
132     # Evaluate properties in context, except system properties.
133     def evaluate_properties
134       for name in (@properties.keys - Bee::Properties::SYSTEM_PROPERTIES)
135         begin
136           Thread.current[:stack] = []
137           evaluate_property(name)
138         ensure
139           Thread.current[:stack] = nil
140         end
141       end
142     end
143 
144     # Evaluate default properties in context.
145     def evaluate_default_properties
146       for name in Bee::Properties::SYSTEM_PROPERTIES
147         begin
148           Thread.current[:stack] = []
149           evaluate_property(name)
150         ensure
151           Thread.current[:stack] = nil
152         end
153       end
154     end
155 
156     # Evaluate a property with given name.
157     # - name: the name of the property to evaluate.
158     def evaluate_property(name)
159       stack = Thread.current[:stack]
160       error "Circular properties: #{stack.join(', ')}" if stack.include?(name)
161       begin
162         stack.push(name)
163         value = evaluate_object(@properties[name])
164         stack.pop
165         set_property(name, value)
166         return value
167       rescue
168         error "Error evaluating property '#{name}': #{$!}"
169       end
170     end
171 
172     # Evaluate scripts in the context.
173     def evaluate_scripts
174       for script in @scripts
175         begin
176           source = Bee::Util::get_file(script, @base)
177           evaluate_script(source)
178         rescue Exception
179           error "Error loading context '#{script}': #{$!}"
180         end
181       end
182     end
183 
184     # Catch missing properties as missing methods.
185     # - name: the name of the missing property or method.
186     def method_missing(name, *args, &block)
187       if Thread.current[:stack]
188         return evaluate_property(name)
189       else
190         raise NoMethodError.new("undefined method `#{name}'", name, args)
191       end
192     end
193 
194     # Get a binding as script context.
195     def get_binding
196       return binding
197     end
198 
199   end
200 
201 end

Generated on Fri Oct 09 02:07:49 +0200 2015 with rcov 1.0.0