moduleRSpecmoduleCore# Shared example groups let you define common context and/or common# examples that you wish to use in multiple example groups.## When defined, the shared group block is stored for later evaluation.# It can later be included in an example group either explicitly# (using `include_examples`, `include_context` or `it_behaves_like`)# or implicitly (via matching metadata).## Named shared example groups are scoped based on where they are# defined. Shared groups defined in an example group are available# for inclusion in that example group or any child example groups,# but not in any parent or sibling example groups. Shared example# groups defined at the top level can be included from any example group.moduleSharedExampleGroup# @overload shared_examples(name, &block)# @param name [String, Symbol, Module] identifer to use when looking up this shared group# @param block The block to be eval'd# @overload shared_examples(name, metadata, &block)# @param name [String, Symbol, Module] identifer to use when looking up this shared group# @param metadata [Array<Symbol>, Hash] metadata to attach to this group; any example group# with matching metadata will automatically include this shared example group.# @param block The block to be eval'd# @overload shared_examples(metadata, &block)# @param metadata [Array<Symbol>, Hash] metadata to attach to this group; any example group# with matching metadata will automatically include this shared example group.# @param block The block to be eval'd## Stores the block for later use. The block will be evaluated# in the context of an example group via `include_examples`,# `include_context`, or `it_behaves_like`.## @example# shared_examples "auditable" do# it "stores an audit record on save!" do# expect { auditable.save! }.to change(Audit, :count).by(1)# end# end## describe Account do# it_behaves_like "auditable" do# let(:auditable) { Account.new }# end# end## @see ExampleGroup.it_behaves_like# @see ExampleGroup.include_examples# @see ExampleGroup.include_contextdefshared_examples(name,*args,&block)top_level=self==ExampleGroupiftop_level&&RSpec.thread_local_metadata[:in_example_group]raise"Creating isolated shared examples from within a context is "+"not allowed. Remove `RSpec.` prefix or move this to a "+"top-level scope."endRSpec.world.shared_example_group_registry.add(self,name,*args,&block)endaliasshared_contextshared_examplesaliasshared_examples_forshared_examples# @api private## Shared examples top level DSLmoduleTopLevelDSL# @privatedefself.definitionsprocdodefshared_examples(name,*args,&block)RSpec.world.shared_example_group_registry.add(:main,name,*args,&block)endaliasshared_contextshared_examplesaliasshared_examples_forshared_examplesendend# @privatedefself.exposed_globally?@exposed_globally||=falseend# @api private## Adds the top level DSL methods to Module and the top level bindingdefself.expose_globally!returnifexposed_globally?Core::DSL.change_global_dsl(&definitions)@exposed_globally=trueend# @api private## Removes the top level DSL methods to Module and the top level bindingdefself.remove_globally!returnunlessexposed_globally?Core::DSL.change_global_dsldoundefshared_examplesundefshared_contextundefshared_examples_forend@exposed_globally=falseendend# @privateclassRegistrydefadd(context,name,*metadata_args,&block)ensure_block_has_source_location(block){CallerFilter.first_non_rspec_line}ifvalid_name?(name)warn_if_key_takencontext,name,blockshared_example_groups[context][name]=blockelsemetadata_args.unshiftnameendunlessmetadata_args.empty?mod=Module.new(class<<mod;self;end).__send__(:define_method,:included)do|host|host.class_exec(&block)endRSpec.configuration.includemod,*metadata_argsendenddeffind(lookup_contexts,name)lookup_contexts.eachdo|context|found=shared_example_groups[context][name]returnfoundiffoundendshared_example_groups[:main][name]endprivatedefshared_example_groups@shared_example_groups||=Hash.new{|hash,context|hash[context]={}}enddefvalid_name?(candidate)casecandidatewhenString,Symbol,Modulethentrueelsefalseendenddefwarn_if_key_taken(context,key,new_block)returnunlessexisting_block=shared_example_groups[context][key]RSpec.warn_with<<-WARNING.gsub(/^ +\|/,''),:call_site=>nil
|WARNING: Shared example group '#{key}' has been previously defined at:
| #{formatted_locationexisting_block}
|...and you are now defining it at:
| #{formatted_locationnew_block}
|The new definition will overwrite the original one.
WARNINGenddefformatted_location(block)block.source_location.join":"endifProc.method_defined?(:source_location)defensure_block_has_source_location(block);endelse# for 1.8.7defensure_block_has_source_location(block)source_location=yield.split(':')block.extendModule.new{define_method(:source_location){source_location}}endendendendendinstance_exec(&Core::SharedExampleGroup::TopLevelDSL.definitions)end