# Author:: Nicolas Pouillard . # Copyright:: Copyright (c) 2005 Uttk Team. All rights reserved. # License:: LGPL # Revision:: $Id: /w/fey/uttk/trunk/lib/uttk/strategies/Iterate.rb 8813 2005-10-12T08:41:50.904292Z ertai $ module Uttk module Strategies # _Iterate_ is a generic iteration strategy which bring the full power of # Ruby to your test description. # # The common use case is somthing like that: # # my test: # strategy: Iterate # over: aStructureWichSupportTheMethodMyEach # with: TheMethodMyEach # `uttk_each' by default # iter: MyIterator # test: # my sub test <>: # strategy: AnotherStrategy # argument: <> # # In the real life you can use it like that: # # my test suite: # strategy: Iterator # over: !filelist **/(*).yml # iter: [path, basename] # test: # my sub test <>: # strategy: Import # input: <> # class Iterate < Collection include Concrete include Composite::Ordered alias_method :make_new_symtbl, :new_symtbl attr_reader :new_symtbl, :iterators protected :new_symtbl, :iterators # # Methods # def prologue super if @test.is_a? Hash and @test.size == 1 name, @attributes = @test.to_a.first @attributes[:name] = name @test = {} else name = @test.name end iter1 = iterators.first iteri = "#{iter1}:i" iterstar = "*#{iter1}" unless name.to_s =~ /<<.*>>/ raise ArgumentError, "You cannot provide a static name like (#{name}) because when " + 'iterating with this name all your tests will have the same ' + "name, to avoid this you can add <<#{iteri}>> to your name" end # Iterate over the object `@over' with the method `@with'. turn = 0 @over.send(@with) do |*args| symtbl = make_new_symtbl symtbl[iteri] = turn symtbl[iterstar] = args args.each_with_index do |arg, i| symtbl["#{iter1}:#{i}"] = arg symtbl["#{iterators[i]}"] = arg if i < iterators.size end @new_symtbl = symtbl create @test turn += 1 end end protected :prologue def iter= ( iter ) @iter = iter iter = iter.to_s if iter.is_a? Symbol @iterators = case iter when Array then iter.flatten when /^\[.*\]$/ then eval iter when /,/ then iter.split(/\s*,\s*/) else [iter] end unless iterators.all? { |it| it.is_a? String } raise ArgumentError, 'The iterator name or list of names ' + "must be strings not (#{iterators.inspect})" end end # # Attributes # attribute :over, 'iterate *over* this object', :mandatory attribute :with, 'iterate *with* this method', :uttk_each attribute :iter, 'iterator name or list of names', :mandatory attribute :test, 'the test to run at each time', :mandatory, :invisible, :dont_expand end # class Iterate end # module Strategies end # module Uttk class Object def uttk_each ( *a, &b ) each(*a, &b) end end # class Object class Hash def uttk_each ( *a, &b ) each(*a) { |k, v| b[k, v] } end end # class Hash