Class: Spectre::RunContext
Overview
The run context is passed to all specs and provides the DSL for assertions, expectations, logging, etc.
Constant Summary collapse
- DEFAULT_ASYNC_NAME =
The default identifier of
asyncblocks. 'default'- @@current =
nil- @@skip_count =
0
Instance Attribute Summary collapse
-
#bag ⇒ Object
readonly
A variable bag to store values across
setup,teardown,before,afteranditblocks. -
#context ⇒ Object
readonly
:stopdoc:.
-
#data ⇒ Object
readonly
:stopdoc:.
-
#error ⇒ Object
readonly
:stopdoc:.
-
#evaluations ⇒ Object
readonly
:stopdoc:.
-
#finished ⇒ Object
readonly
:stopdoc:.
-
#logs ⇒ Object
readonly
:stopdoc:.
-
#name ⇒ Object
readonly
:stopdoc:.
-
#parent ⇒ Object
readonly
:stopdoc:.
-
#properties ⇒ Object
readonly
:stopdoc:.
-
#started ⇒ Object
readonly
:stopdoc:.
-
#type ⇒ Object
readonly
:stopdoc:.
Class Method Summary collapse
-
.current ⇒ Object
The current executing
RunContext.
Instance Method Summary collapse
-
#async(name = DEFAULT_ASYNC_NAME) ⇒ Object
Executes the given block asyncronously in a new thread.
-
#await(name = DEFAULT_ASYNC_NAME) ⇒ Object
- returns
-
An
Arrayof previously executedasyncblocks with the same name.
-
#duration ⇒ Object
- returns
-
The duration of the previously executed
measureblock.
-
#execute(data) ⇒ Object
Executes the given block in the context of this
RunContext. -
#fail_with(message) ⇒ Object
- deprecated
-
use
reportinstead.
-
#group(desc) ⇒ Object
Groups code in a block.
-
#initialize(engine, parent, type, bag = nil) ⇒ RunContext
constructor
A new instance of RunContext.
-
#measure ⇒ Object
Takes a block and measures the time of the execution.
-
#method ⇒ Object
:method: expect :args: desc, &.
-
#observe(desc) ⇒ Object
Observes the given block and catches all errors within this block.
-
#property(**kwargs) ⇒ Object
Adds the given key-value arguments to the run report.
-
#resources ⇒ Object
Access the loaded resources (files).
-
#run(desc, with: nil) ⇒ Object
(also: #also)
Run the mixin with the given name and parameters.
-
#skip(message) ⇒ Object
Skip the run for this spec.
-
#status ⇒ Object
The status of the current run.
-
#success? ⇒ Boolean
Returns the status of the pervious
observeblock.
Methods included from Delegate
#instance_eval, #instance_exec, #method_missing, #respond_to_missing?
Constructor Details
#initialize(engine, parent, type, bag = nil) ⇒ RunContext
Returns a new instance of RunContext.
819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 |
# File 'lib/spectre.rb', line 819 def initialize engine, parent, type, bag = nil @engine = engine @parent = parent @type = type @logs = [] @threads = {} @name = parent.name # If the run type is an actual spec, the context # of the run is its parent +Specification+ 's parent. if type == :spec @context = parent.parent else # Otherwise the run context is the parent itself # This is the case when a setup or teardown block # is executet, which uses its own run context. @context = parent @name += "-#{type}" end @bag = OpenStruct.new(bag) @properties = {} @evaluations = [] @error = nil @skipped = false @started = Time.now begin @@current = self yield self ensure @finished = Time.now @@current = nil end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Spectre::Delegate
Instance Attribute Details
#bag ⇒ Object (readonly)
A variable bag to store values across setup, teardown, before, after and it blocks.
setup do
bag.foo = 'bar'
end
it 'does something' do
assert bag.foo.to be 'bar'
end
797 798 799 |
# File 'lib/spectre.rb', line 797 def bag @bag end |
#context ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def context @context end |
#data ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def data @data end |
#error ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def error @error end |
#evaluations ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def evaluations @evaluations end |
#finished ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def finished @finished end |
#logs ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def logs @logs end |
#name ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def name @name end |
#parent ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def parent @parent end |
#properties ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def properties @properties end |
#started ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def started @started end |
#type ⇒ Object (readonly)
:stopdoc:
801 802 803 |
# File 'lib/spectre.rb', line 801 def type @type end |
Class Method Details
.current ⇒ Object
The current executing RunContext
815 816 817 |
# File 'lib/spectre.rb', line 815 def self.current @@current end |
Instance Method Details
#async(name = DEFAULT_ASYNC_NAME) ⇒ Object
Executes the given block asyncronously in a new thread. This thread can be awaited with await and the given name. You can start multiple threads with the same name. Using this name with await will wait for all threads to finish.
The last line in the async block will be returned as a result. and is available when await ing the threads.
async do
info 'do some async stuff'
'a result'
end
result = await
1063 1064 1065 1066 |
# File 'lib/spectre.rb', line 1063 def async(name = DEFAULT_ASYNC_NAME, &) @threads[name] ||= [] @threads[name] << Thread.new(&) end |
#await(name = DEFAULT_ASYNC_NAME) ⇒ Object
- returns
-
An
Arrayof previously executedasyncblocks
with the same name.
Waits for the threads created with async to finish. Awaits all threads with the given name.
1075 1076 1077 1078 1079 1080 |
# File 'lib/spectre.rb', line 1075 def await name = DEFAULT_ASYNC_NAME return unless @threads.key? name threads = @threads.delete(name) threads.map(&:join) end |
#duration ⇒ Object
- returns
-
The duration of the previously executed
measureblock.
The duration optained by measure.
1042 1043 1044 |
# File 'lib/spectre.rb', line 1042 def duration @measured_duration end |
#execute(data) ⇒ Object
Executes the given block in the context of this RunContext. For internal use only. Do not execute within an it block.
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 |
# File 'lib/spectre.rb', line 864 def execute(data, &) @data = data instance_exec(data.is_a?(Hash) ? OpenStruct.new(data) : data, &) rescue AbortException # Do nothing. The run will be ended here rescue Interrupt @skipped = true @engine.formatter.log(:debug, nil, :skipped, 'canceled by user') @engine.logger.info("#{@parent.desc} - canceled by user") raise Interrupt if (@@skip_count += 1) > 2 rescue StandardError => e @error = e @engine.formatter.log(:fatal, e., :error, e.class.name) @engine.logger.fatal("#{e.}\n#{e.backtrace.join("\n")}") end |
#fail_with(message) ⇒ Object
- deprecated
-
use
reportinstead.
Raise a failure error. Using this method within an assert or expect block will report an error and aborts the run immediately.
assert 'something' do
fail_with 'a detailed message'
end
946 947 948 |
# File 'lib/spectre.rb', line 946 def fail_with raise Failure, end |
#group(desc) ⇒ Object
Groups code in a block. This is solely used for structuring tests and will not have effect on test reports.
1087 1088 1089 1090 1091 1092 |
# File 'lib/spectre.rb', line 1087 def group(desc, &) @engine.logger.correlate do @engine.logger.debug("group \"#{desc}\"") @engine.formatter.scope(desc, :group, &) end end |
#measure ⇒ Object
Takes a block and measures the time of the execution. The duration in seconds is available through duration.
measure do
info 'do some long running stuff'
sleep 1
end
info "run duration was #{duration}"
1028 1029 1030 1031 1032 1033 1034 |
# File 'lib/spectre.rb', line 1028 def measure start_time = Time.now yield end_time = Time.now @measured_duration = end_time - start_time end |
#method ⇒ Object
:method: expect :args: desc, &
Expect a specific condition. If a block is given it creates an EvaluationContext and its methods are available. If a failure is reported within this block, the run will continue.
foo = 'bar'
expect foo.to be 'bar'
expect 'a certain condition to be true' do
report 'it was not' if foo == 'bar'
end
915 916 917 918 919 920 921 |
# File 'lib/spectre.rb', line 915 %i[debug info warn].each do |method| define_method(method) do || = .to_s @engine.logger.send(method, ) @engine.formatter.log(method, ) end end |
#observe(desc) ⇒ Object
Observes the given block and catches all errors within this block. If errors or failures occur the test will not fail or aborted.
The result of the observation can be retreived through success?
observe do
info 'do some stuff'
end
assert success?.to be true
observe do
raise StandardError, 'Oops!'
end
assert success?.to be false
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 |
# File 'lib/spectre.rb', line 1114 def observe desc @engine.formatter.log(:info, "observe #{desc}") do yield @success = true [:info, :ok, nil] rescue StandardError => e @success = false @engine.logger.warn("#{e.}\n#{e.backtrace.join("\n")}") [:info, :warn, e.] end end |
#property(**kwargs) ⇒ Object
Adds the given key-value arguments to the run report. Use this to add generated values during the run to the test report.
property key: 'value'
1013 1014 1015 |
# File 'lib/spectre.rb', line 1013 def property **kwargs @properties.merge!(kwargs) end |
#resources ⇒ Object
Access the loaded resources (files). The path parameter is relative to the resource directory.
resources['path/to/some.txt']
931 932 933 |
# File 'lib/spectre.rb', line 931 def resources @engine.resources end |
#run(desc, with: nil) ⇒ Object Also known as: also
Run the mixin with the given name and parameters
run 'additional actions' do
with some_param: 42,
another_param: 'foo'
end
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 |
# File 'lib/spectre.rb', line 1141 def run(desc, with: nil, &) @engine.formatter.scope(desc, :mixin) do raise "mixin \"#{desc}\" not found" unless @engine.mixins.key? desc mixin = @engine.mixins[desc] mixin.instance_eval(&) if block_given? @engine.logger.correlate do @engine.logger.debug("execute mixin \"#{desc}\"") result = mixin.run(self, with) return result.is_a?(Hash) ? OpenStruct.new(result) : result end end end |
#skip(message) ⇒ Object
Skip the run for this spec. This can be used to skip spec runs when a certain condition occurs.
skip 'subject is not yet ready to be tested' unless service_is_ready()
1167 1168 1169 1170 1171 |
# File 'lib/spectre.rb', line 1167 def skip @skipped = true @engine.logger.info("#{} - canceled by user") raise AbortException end |
#status ⇒ Object
The status of the current run. One of :error, :failed, :skipped or :success
884 885 886 887 888 889 890 |
# File 'lib/spectre.rb', line 884 def status return :error if @error return :failed if @evaluations.any? { |x| x.failures.any? } return :skipped if @skipped :success end |
#success? ⇒ Boolean
Returns the status of the pervious observe block
1129 1130 1131 |
# File 'lib/spectre.rb', line 1129 def success? @success.nil? || @success end |