rspec-core 3.0.4 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +67 -0
  5. data/lib/rspec/core.rb +3 -1
  6. data/lib/rspec/core/backtrace_formatter.rb +13 -10
  7. data/lib/rspec/core/configuration.rb +123 -57
  8. data/lib/rspec/core/configuration_options.rb +12 -12
  9. data/lib/rspec/core/drb.rb +11 -11
  10. data/lib/rspec/core/dsl.rb +0 -1
  11. data/lib/rspec/core/example.rb +39 -12
  12. data/lib/rspec/core/example_group.rb +31 -98
  13. data/lib/rspec/core/filter_manager.rb +16 -17
  14. data/lib/rspec/core/formatters.rb +14 -13
  15. data/lib/rspec/core/formatters/base_formatter.rb +8 -113
  16. data/lib/rspec/core/formatters/base_text_formatter.rb +3 -5
  17. data/lib/rspec/core/formatters/console_codes.rb +1 -2
  18. data/lib/rspec/core/formatters/deprecation_formatter.rb +2 -3
  19. data/lib/rspec/core/formatters/documentation_formatter.rb +3 -4
  20. data/lib/rspec/core/formatters/helpers.rb +5 -6
  21. data/lib/rspec/core/formatters/html_formatter.rb +20 -19
  22. data/lib/rspec/core/formatters/html_printer.rb +6 -5
  23. data/lib/rspec/core/formatters/json_formatter.rb +3 -2
  24. data/lib/rspec/core/formatters/profile_formatter.rb +0 -2
  25. data/lib/rspec/core/formatters/progress_formatter.rb +4 -4
  26. data/lib/rspec/core/formatters/protocol.rb +163 -0
  27. data/lib/rspec/core/formatters/snippet_extractor.rb +7 -6
  28. data/lib/rspec/core/hooks.rb +25 -10
  29. data/lib/rspec/core/memoized_helpers.rb +7 -5
  30. data/lib/rspec/core/metadata.rb +29 -30
  31. data/lib/rspec/core/metadata_filter.rb +66 -66
  32. data/lib/rspec/core/minitest_assertions_adapter.rb +1 -1
  33. data/lib/rspec/core/mocking_adapters/flexmock.rb +3 -1
  34. data/lib/rspec/core/mocking_adapters/mocha.rb +3 -1
  35. data/lib/rspec/core/mocking_adapters/null.rb +2 -0
  36. data/lib/rspec/core/mocking_adapters/rr.rb +3 -1
  37. data/lib/rspec/core/mocking_adapters/rspec.rb +3 -1
  38. data/lib/rspec/core/notifications.rb +36 -29
  39. data/lib/rspec/core/option_parser.rb +29 -25
  40. data/lib/rspec/core/ordering.rb +8 -9
  41. data/lib/rspec/core/pending.rb +6 -8
  42. data/lib/rspec/core/project_initializer.rb +4 -2
  43. data/lib/rspec/core/project_initializer/.rspec +0 -1
  44. data/lib/rspec/core/project_initializer/spec/spec_helper.rb +37 -26
  45. data/lib/rspec/core/rake_task.rb +37 -19
  46. data/lib/rspec/core/reporter.rb +13 -16
  47. data/lib/rspec/core/ruby_project.rb +2 -2
  48. data/lib/rspec/core/runner.rb +11 -14
  49. data/lib/rspec/core/shared_example_group.rb +14 -13
  50. data/lib/rspec/core/test_unit_assertions_adapter.rb +1 -1
  51. data/lib/rspec/core/version.rb +1 -1
  52. data/lib/rspec/core/warnings.rb +4 -4
  53. data/lib/rspec/core/world.rb +22 -24
  54. metadata +6 -5
  55. metadata.gz.sig +0 -0
@@ -123,29 +123,29 @@ module RSpec
123
123
 
124
124
  def order=(type)
125
125
  order, seed = type.to_s.split(':')
126
- @seed = seed = seed.to_i if seed
126
+ @seed = seed.to_i if seed
127
127
 
128
128
  ordering_name = if order.include?('rand')
129
- :random
130
- elsif order == 'defined'
131
- :defined
132
- end
129
+ :random
130
+ elsif order == 'defined'
131
+ :defined
132
+ end
133
133
 
134
134
  register_ordering(:global, ordering_registry.fetch(ordering_name)) if ordering_name
135
135
  end
136
136
 
137
137
  def force(hash)
138
- if hash.has_key?(:seed)
138
+ if hash.key?(:seed)
139
139
  self.seed = hash[:seed]
140
140
  @seed_forced = true
141
141
  @order_forced = true
142
- elsif hash.has_key?(:order)
142
+ elsif hash.key?(:order)
143
143
  self.order = hash[:order]
144
144
  @order_forced = true
145
145
  end
146
146
  end
147
147
 
148
- def register_ordering(name, strategy = Custom.new(Proc.new { |l| yield l }))
148
+ def register_ordering(name, strategy=Custom.new(Proc.new { |l| yield l }))
149
149
  return if @order_forced && name == :global
150
150
  ordering_registry.register(name, strategy)
151
151
  end
@@ -153,4 +153,3 @@ module RSpec
153
153
  end
154
154
  end
155
155
  end
156
-
@@ -89,7 +89,7 @@ module RSpec
89
89
  elsif current_example
90
90
  Pending.mark_pending! current_example, message
91
91
  else
92
- raise "`pending` may not be used outside of examples, such as in " +
92
+ raise "`pending` may not be used outside of examples, such as in " \
93
93
  "before(:context). Maybe you want `skip`?"
94
94
  end
95
95
  end
@@ -116,9 +116,7 @@ module RSpec
116
116
  def skip(message=nil)
117
117
  current_example = RSpec.current_example
118
118
 
119
- if current_example
120
- Pending.mark_skipped! current_example, message
121
- end
119
+ Pending.mark_skipped!(current_example, message) if current_example
122
120
 
123
121
  raise SkipDeclaredInExample.new(message)
124
122
  end
@@ -142,10 +140,10 @@ module RSpec
142
140
  # @param message_or_bool [Boolean, String] the message to use, or true
143
141
  def self.mark_pending!(example, message_or_bool)
144
142
  message = if !message_or_bool || !(String === message_or_bool)
145
- NO_REASON_GIVEN
146
- else
147
- message_or_bool
148
- end
143
+ NO_REASON_GIVEN
144
+ else
145
+ message_or_bool
146
+ end
149
147
 
150
148
  example.metadata[:pending] = true
151
149
  example.execution_result.pending_message = message
@@ -1,3 +1,5 @@
1
+ RSpec::Support.require_rspec_support "directory_maker"
2
+
1
3
  module RSpec
2
4
  module Core
3
5
  # @private
@@ -8,7 +10,7 @@ module RSpec
8
10
  DOT_RSPEC_FILE = '.rspec'
9
11
  SPEC_HELPER_FILE = 'spec/spec_helper.rb'
10
12
 
11
- def initialize(opts = {})
13
+ def initialize(opts={})
12
14
  @destination = opts.fetch(:destination, Dir.getwd)
13
15
  @stream = opts.fetch(:report_stream, $stdout)
14
16
  @template_path = opts.fetch(:template_path) do
@@ -28,7 +30,7 @@ module RSpec
28
30
  return report_exists(file) if File.exist?(destination_file)
29
31
 
30
32
  report_creating(file)
31
- FileUtils.mkdir_p(File.dirname(destination_file))
33
+ RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(destination_file))
32
34
  File.open(destination_file, 'w') do |f|
33
35
  f.write File.read(File.join(template_path, file))
34
36
  end
@@ -1,3 +1,2 @@
1
1
  --color
2
- --warnings
3
2
  --require spec_helper
@@ -6,15 +6,38 @@
6
6
  # Given that it is always loaded, you are encouraged to keep this file as
7
7
  # light-weight as possible. Requiring heavyweight dependencies from this file
8
8
  # will add to the boot time of your test suite on EVERY test run, even for an
9
- # individual file that may not need all of that loaded. Instead, make a
10
- # separate helper file that requires this one and then use it only in the specs
11
- # that actually need it.
9
+ # individual file that may not need all of that loaded. Instead, consider making
10
+ # a separate helper file that requires the additional dependencies and performs
11
+ # the additional setup, and require it from the spec files that actually need it.
12
12
  #
13
13
  # The `.rspec` file also contains a few flags that are not defaults but that
14
14
  # users commonly want.
15
15
  #
16
16
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
17
  RSpec.configure do |config|
18
+ # rspec-expectations config goes here. You can use an alternate
19
+ # assertion/expectation library such as wrong or the stdlib/minitest
20
+ # assertions if you prefer.
21
+ config.expect_with :rspec do |expectations|
22
+ # This option will default to `true` in RSpec 4. It makes the `description`
23
+ # and `failure_message` of custom matchers include text for helper methods
24
+ # defined using `chain`, e.g.:
25
+ # be_bigger_than(2).and_smaller_than(4).description
26
+ # # => "be bigger than 2 and smaller than 4"
27
+ # ...rather than:
28
+ # # => "be bigger than 2"
29
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
30
+ end
31
+
32
+ # rspec-mocks config goes here. You can use an alternate test double
33
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
34
+ config.mock_with :rspec do |mocks|
35
+ # Prevents you from mocking or stubbing a method that does not exist on
36
+ # a real object. This is generally recommended, and will default to
37
+ # `true` in RSpec 4.
38
+ mocks.verify_partial_doubles = true
39
+ end
40
+
18
41
  # The settings below are suggested to provide a good initial experience
19
42
  # with RSpec, but feel free to customize to your heart's content.
20
43
  =begin
@@ -25,6 +48,17 @@ RSpec.configure do |config|
25
48
  config.filter_run :focus
26
49
  config.run_all_when_everything_filtered = true
27
50
 
51
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
52
+ # For more details, see:
53
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
54
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
55
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
56
+ config.disable_monkey_patching!
57
+
58
+ # This setting enables warnings. It's recommended, but in some cases may
59
+ # be too noisy due to issues in dependencies.
60
+ config.warnings = true
61
+
28
62
  # Many RSpec users commonly either run the entire suite or an individual
29
63
  # file, and it's useful to allow more verbose output when running an
30
64
  # individual spec file.
@@ -51,28 +85,5 @@ RSpec.configure do |config|
51
85
  # test failures related to randomization by passing the same `--seed` value
52
86
  # as the one that triggered the failure.
53
87
  Kernel.srand config.seed
54
-
55
- # rspec-expectations config goes here. You can use an alternate
56
- # assertion/expectation library such as wrong or the stdlib/minitest
57
- # assertions if you prefer.
58
- config.expect_with :rspec do |expectations|
59
- # Enable only the newer, non-monkey-patching expect syntax.
60
- # For more details, see:
61
- # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
62
- expectations.syntax = :expect
63
- end
64
-
65
- # rspec-mocks config goes here. You can use an alternate test double
66
- # library (such as bogus or mocha) by changing the `mock_with` option here.
67
- config.mock_with :rspec do |mocks|
68
- # Enable only the newer, non-monkey-patching expect syntax.
69
- # For more details, see:
70
- # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
71
- mocks.syntax = :expect
72
-
73
- # Prevents you from mocking or stubbing a method that does not exist on
74
- # a real object. This is generally recommended.
75
- mocks.verify_partial_doubles = true
76
- end
77
88
  =end
78
89
  end
@@ -1,7 +1,3 @@
1
- require 'rspec/support'
2
- require 'rspec/core/version'
3
- RSpec::Support.require_rspec_support "warnings"
4
-
5
1
  require 'rake'
6
2
  require 'rake/tasklib'
7
3
  require 'shellwords'
@@ -18,7 +14,7 @@ module RSpec
18
14
  DEFAULT_RSPEC_PATH = File.expand_path('../../../../exe/rspec', __FILE__)
19
15
 
20
16
  # Default pattern for spec files.
21
- DEFAULT_PATTERN = './spec{,/*/**}/*_spec.rb'
17
+ DEFAULT_PATTERN = 'spec/**{,/*/**}/*_spec.rb'
22
18
 
23
19
  # Name of task.
24
20
  #
@@ -26,12 +22,18 @@ module RSpec
26
22
  # :spec
27
23
  attr_accessor :name
28
24
 
29
- # Glob pattern to match files.
25
+ # Files matching this pattern will be loaded.
30
26
  #
31
27
  # default:
32
- # 'spec/**/*_spec.rb'
28
+ # 'spec/**{,/*/**}/*_spec.rb'
33
29
  attr_accessor :pattern
34
30
 
31
+ # Files matching this pattern will be excluded.
32
+ #
33
+ # default:
34
+ # 'spec/**/*_spec.rb'
35
+ attr_accessor :exclude_pattern
36
+
35
37
  # Whether or not to fail Rake when an error occurs (typically when examples fail).
36
38
  #
37
39
  # default:
@@ -88,10 +90,11 @@ module RSpec
88
90
  rescue
89
91
  puts failure_message if failure_message
90
92
  end
91
- if fail_on_error && !success
92
- $stderr.puts "#{command} failed"
93
- exit $?.exitstatus
94
- end
93
+
94
+ return unless fail_on_error && !success
95
+
96
+ $stderr.puts "#{command} failed"
97
+ exit $?.exitstatus
95
98
  end
96
99
 
97
100
  private
@@ -108,33 +111,48 @@ module RSpec
108
111
  end
109
112
  end
110
113
 
111
- def files_to_run
114
+ def file_inclusion_specification
112
115
  if ENV['SPEC']
113
- FileList[ ENV['SPEC'] ].sort
116
+ FileList[ ENV['SPEC']].sort
117
+ elsif File.exist?(pattern)
118
+ # The provided pattern is a directory or a file, not a file glob. Historically, this
119
+ # worked because `FileList[some_dir]` would return `[some_dir]` which would
120
+ # get passed to `rspec` and cause it to load files under that dir that match
121
+ # the default pattern. To continue working, we need to pass it on to `rspec`
122
+ # directly rather than treating it as a `--pattern` option.
123
+ #
124
+ # TODO: consider deprecating support for this and removing it in RSpec 4.
125
+ pattern.shellescape
114
126
  else
115
- FileList[ pattern ].sort.map(&:shellescape)
127
+ "--pattern #{pattern.shellescape}"
116
128
  end
117
129
  end
118
130
 
131
+ def file_exclusion_specification
132
+ " --exclude-pattern #{exclude_pattern.shellescape}" if exclude_pattern
133
+ end
134
+
119
135
  def spec_command
120
136
  cmd_parts = []
121
137
  cmd_parts << RUBY
122
138
  cmd_parts << ruby_opts
123
139
  cmd_parts << rspec_load_path
124
- cmd_parts << "-S" << rspec_path
125
- cmd_parts << files_to_run
140
+ cmd_parts << rspec_path
141
+ cmd_parts << file_inclusion_specification
142
+ cmd_parts << file_exclusion_specification
126
143
  cmd_parts << rspec_opts
127
144
  cmd_parts.flatten.reject(&blank).join(" ")
128
145
  end
129
146
 
130
147
  def blank
131
- lambda {|s| s.nil? || s == ""}
148
+ lambda { |s| s.nil? || s == "" }
132
149
  end
133
150
 
134
151
  def rspec_load_path
135
152
  @rspec_load_path ||= begin
136
- core_and_support = $LOAD_PATH.grep \
137
- %r{#{File::SEPARATOR}rspec-(core|support)[^#{File::SEPARATOR}]*#{File::SEPARATOR}lib}
153
+ core_and_support = $LOAD_PATH.grep(
154
+ /#{File::SEPARATOR}rspec-(core|support)[^#{File::SEPARATOR}]*#{File::SEPARATOR}lib/
155
+ )
138
156
 
139
157
  "-I#{core_and_support.map(&:shellescape).join(File::PATH_SEPARATOR)}"
140
158
  end
@@ -2,10 +2,9 @@ module RSpec::Core
2
2
  # A reporter will send notifications to listeners, usually formatters for the
3
3
  # spec suite run.
4
4
  class Reporter
5
-
6
5
  def initialize(configuration)
7
6
  @configuration = configuration
8
- @listeners = Hash.new { |h,k| h[k] = Set.new }
7
+ @listeners = Hash.new { |h, k| h[k] = Set.new }
9
8
  @examples = []
10
9
  @failed_examples = []
11
10
  @pending_examples = []
@@ -58,7 +57,7 @@ module RSpec::Core
58
57
  end
59
58
 
60
59
  # @private
61
- def start(expected_example_count, time = RSpec::Core::Time.now)
60
+ def start(expected_example_count, time=RSpec::Core::Time.now)
62
61
  @start = time
63
62
  @load_time = (@start - @configuration.start_time).to_f
64
63
  notify :start, Notifications::StartNotification.new(expected_example_count, @load_time)
@@ -109,20 +108,18 @@ module RSpec::Core
109
108
 
110
109
  # @private
111
110
  def finish
112
- begin
113
- stop
114
- notify :start_dump, Notifications::NullNotification
115
- notify :dump_pending, Notifications::ExamplesNotification.new(self)
116
- notify :dump_failures, Notifications::ExamplesNotification.new(self)
117
- notify :deprecation_summary, Notifications::NullNotification
118
- notify :dump_summary, Notifications::SummaryNotification.new(@duration, @examples, @failed_examples, @pending_examples, @load_time)
119
- unless mute_profile_output?
120
- notify :dump_profile, Notifications::ProfileNotification.new(@duration, @examples, @configuration.profile_examples)
121
- end
122
- notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?)
123
- ensure
124
- notify :close, Notifications::NullNotification
111
+ stop
112
+ notify :start_dump, Notifications::NullNotification
113
+ notify :dump_pending, Notifications::ExamplesNotification.new(self)
114
+ notify :dump_failures, Notifications::ExamplesNotification.new(self)
115
+ notify :deprecation_summary, Notifications::NullNotification
116
+ notify :dump_summary, Notifications::SummaryNotification.new(@duration, @examples, @failed_examples, @pending_examples, @load_time)
117
+ unless mute_profile_output?
118
+ notify :dump_profile, Notifications::ProfileNotification.new(@duration, @examples, @configuration.profile_examples)
125
119
  end
120
+ notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?)
121
+ ensure
122
+ notify :close, Notifications::NullNotification
126
123
  end
127
124
 
128
125
  # @private
@@ -9,7 +9,7 @@ module RSpec
9
9
  # @private
10
10
  module RubyProject
11
11
  def add_to_load_path(*dirs)
12
- dirs.map {|dir| add_dir_to_load_path(File.join(root, dir))}
12
+ dirs.map { |dir| add_dir_to_load_path(File.join(root, dir)) }
13
13
  end
14
14
 
15
15
  def add_dir_to_load_path(dir)
@@ -25,7 +25,7 @@ module RSpec
25
25
  end
26
26
 
27
27
  def find_first_parent_containing(dir)
28
- ascend_until {|path| File.exist?(File.join(path, dir))}
28
+ ascend_until { |path| File.exist?(File.join(path, dir)) }
29
29
  end
30
30
 
31
31
  def ascend_until
@@ -2,7 +2,6 @@ module RSpec
2
2
  module Core
3
3
  # Provides the main entry point to run a suite of RSpec examples.
4
4
  class Runner
5
-
6
5
  # Register an `at_exit` hook that runs the suite when the process exits.
7
6
  #
8
7
  # @note This is not generally needed. The `rspec` command takes care
@@ -22,7 +21,7 @@ module RSpec
22
21
  # Don't bother running any specs and just let the program terminate
23
22
  # if we got here due to an unrescued exception (anything other than
24
23
  # SystemExit, which is raised when somebody calls Kernel#exit).
25
- next unless $!.nil? || $!.kind_of?(SystemExit)
24
+ next unless $!.nil? || $!.is_a?(SystemExit)
26
25
 
27
26
  # We got here because either the end of the program was reached or
28
27
  # somebody called Kernel#exit. Run the specs and then override any
@@ -132,21 +131,19 @@ module RSpec
132
131
  end
133
132
 
134
133
  # @private
134
+ # rubocop:disable Lint/EnsureReturn
135
135
  def self.running_in_drb?
136
- begin
137
- if defined?(DRb) && DRb.current_server
138
- require 'socket'
139
- require 'uri'
140
-
141
- local_ipv4 = IPSocket.getaddress(Socket.gethostname)
142
-
143
- local_drb = ["127.0.0.1", "localhost", local_ipv4].any? { |addr| addr == URI(DRb.current_server.uri).host }
144
- end
145
- rescue DRb::DRbServerNotFound
146
- ensure
147
- return local_drb || false
136
+ if defined?(DRb) && DRb.current_server
137
+ require 'socket'
138
+ require 'uri'
139
+ local_ipv4 = IPSocket.getaddress(Socket.gethostname)
140
+ local_drb = ["127.0.0.1", "localhost", local_ipv4].any? { |addr| addr == URI(DRb.current_server.uri).host }
148
141
  end
142
+ rescue DRb::DRbServerNotFound
143
+ ensure
144
+ return local_drb || false
149
145
  end
146
+ # rubocop:enable Lint/EnsureReturn
150
147
 
151
148
  # @private
152
149
  def self.trap_interrupt
@@ -50,8 +50,8 @@ module RSpec
50
50
  def shared_examples(name, *args, &block)
51
51
  top_level = self == ExampleGroup
52
52
  if top_level && RSpec.thread_local_metadata[:in_example_group]
53
- raise "Creating isolated shared examples from within a context is " +
54
- "not allowed. Remove `RSpec.` prefix or move this to a " +
53
+ raise "Creating isolated shared examples from within a context is " \
54
+ "not allowed. Remove `RSpec.` prefix or move this to a " \
55
55
  "top-level scope."
56
56
  end
57
57
 
@@ -103,7 +103,6 @@ module RSpec
103
103
 
104
104
  @exposed_globally = false
105
105
  end
106
-
107
106
  end
108
107
 
109
108
  # @private
@@ -118,13 +117,13 @@ module RSpec
118
117
  metadata_args.unshift name
119
118
  end
120
119
 
121
- unless metadata_args.empty?
122
- mod = Module.new
123
- (class << mod; self; end).__send__(:define_method, :included) do |host|
124
- host.class_exec(&block)
125
- end
126
- RSpec.configuration.include mod, *metadata_args
120
+ return if metadata_args.empty?
121
+
122
+ mod = Module.new
123
+ (class << mod; self; end).__send__(:define_method, :included) do |host|
124
+ host.class_exec(&block)
127
125
  end
126
+ RSpec.configuration.include mod, *metadata_args
128
127
  end
129
128
 
130
129
  def find(lookup_contexts, name)
@@ -144,13 +143,15 @@ module RSpec
144
143
 
145
144
  def valid_name?(candidate)
146
145
  case candidate
147
- when String, Symbol, Module then true
148
- else false
146
+ when String, Symbol, Module then true
147
+ else false
149
148
  end
150
149
  end
151
150
 
152
151
  def warn_if_key_taken(context, key, new_block)
153
- return unless existing_block = shared_example_groups[context][key]
152
+ existing_block = shared_example_groups[context][key]
153
+
154
+ return unless existing_block
154
155
 
155
156
  RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil
156
157
  |WARNING: Shared example group '#{key}' has been previously defined at:
@@ -166,7 +167,7 @@ module RSpec
166
167
  end
167
168
 
168
169
  if Proc.method_defined?(:source_location)
169
- def ensure_block_has_source_location(block); end
170
+ def ensure_block_has_source_location(_block); end
170
171
  else # for 1.8.7
171
172
  def ensure_block_has_source_location(block)
172
173
  source_location = yield.split(':')