lib/polytrix/validation.rb in polytrix-0.1.2 vs lib/polytrix/validation.rb in polytrix-0.1.3
- old
+ new
@@ -1,20 +1,59 @@
require 'hashie/dash'
module Polytrix
class Validation < Polytrix::ManifestSection
+ # TODO: Should we have (expectation) 'failed' vs (unexpected) 'error'?
ALLOWABLE_STATES = %w(passed pending failed skipped)
- property :validated_by, required: true
- property :result
+ property :result, required: true
+ property :error
+
def result=(state)
+ state = state.to_s
fail invalidate_state_error unless ALLOWABLE_STATES.include? state
super
end
+ ALLOWABLE_STATES.each do |state|
+ define_method "#{state}?" do
+ result == state?
+ end
+ end
+
+ # Gets the source of the validation code block where a ValidationFailure occurred.
+ def error_source
+ return nil if error.nil?
+ source_from_error(error)
+ end
+
protected
def invalidate_state_error(state)
ArgumentError.new "Invalid result state: #{state}, should be one of #{ALLOWABLE_STATES.inspect}"
+ end
+
+ def source_from_error(e)
+ error_location = e.backtrace_locations.delete_if { |l| l.absolute_path =~ /gems\/rspec-/ }.first
+ error_source = File.read(error_location.absolute_path)
+ error_lineno = error_location.lineno - 1 # lineno counts from 1
+ get_dedented_block(error_source, error_lineno)
+ end
+
+ def get_dedented_block(source_text, target_lineno)
+ block = []
+ lines = source_text.lines
+ target_indent = lines[target_lineno][/\A */].size
+ lines[0...target_lineno].reverse.each do |line|
+ indent = line[/\A */].size
+ block.prepend line
+ break if indent < target_indent
+ end
+ lines[target_lineno..lines.size].each do |line|
+ indent = line[/\A */].size
+ block.push line
+ break if indent < target_indent
+ end
+ block.join
end
end
end