Skip to content
This repository
  • 4 commits
  • 7 files changed
  • 0 comments
  • 1 contributor
87  lib/rspec/core/configuration.rb
@@ -799,6 +799,79 @@ def randomize?
799 799
         order.to_s.match(/rand/)
800 800
       end
801 801
 
  802
+      # @private
  803
+      DEFAULT_ORDERING = lambda { |list| list }
  804
+
  805
+      # @private
  806
+      RANDOM_ORDERING = lambda do |list|
  807
+        Kernel.srand RSpec.configuration.seed
  808
+        list.sort_by { Kernel.rand(list.size) }
  809
+      end
  810
+
  811
+      # Sets a strategy by which to order examples.
  812
+      #
  813
+      # @example
  814
+      #   RSpec.configure do |config|
  815
+      #     config.order_examples do |examples|
  816
+      #       examples.reverse
  817
+      #     end
  818
+      #   end
  819
+      #
  820
+      # @see #order_groups
  821
+      # @see #order_groups_and_examples
  822
+      # @see #order=
  823
+      # @see #seed=
  824
+      def order_examples(&block)
  825
+        @example_ordering_block = block
  826
+        @order = "custom" unless built_in_orderer?(block)
  827
+      end
  828
+
  829
+      # @private
  830
+      def example_ordering_block
  831
+        @example_ordering_block ||= DEFAULT_ORDERING
  832
+      end
  833
+
  834
+      # Sets a strategy by which to order groups.
  835
+      #
  836
+      # @example
  837
+      #   RSpec.configure do |config|
  838
+      #     config.order_groups do |groups|
  839
+      #       groups.reverse
  840
+      #     end
  841
+      #   end
  842
+      #
  843
+      # @see #order_examples
  844
+      # @see #order_groups_and_examples
  845
+      # @see #order=
  846
+      # @see #seed=
  847
+      def order_groups(&block)
  848
+        @group_ordering_block = block
  849
+        @order = "custom" unless built_in_orderer?(block)
  850
+      end
  851
+
  852
+      # @private
  853
+      def group_ordering_block
  854
+        @group_ordering_block ||= DEFAULT_ORDERING
  855
+      end
  856
+
  857
+      # Sets a strategy by which to order groups and examples.
  858
+      #
  859
+      # @example
  860
+      #   RSpec.configure do |config|
  861
+      #     config.order_groups_and_examples do |groups_or_examples|
  862
+      #       groups_or_examples.reverse
  863
+      #     end
  864
+      #   end
  865
+      #
  866
+      # @see #order_groups
  867
+      # @see #order_examples
  868
+      # @see #order=
  869
+      # @see #seed=
  870
+      def order_groups_and_examples(&block)
  871
+        order_groups(&block)
  872
+        order_examples(&block)
  873
+      end
  874
+
802 875
     private
803 876
 
804 877
       def get_files_to_run(paths)
@@ -923,6 +996,7 @@ def file_at(path)
923 996
       end
924 997
 
925 998
       def order_and_seed_from_seed(value)
  999
+        order_groups_and_examples(&RANDOM_ORDERING)
926 1000
         @order, @seed = 'rand', value.to_i
927 1001
       end
928 1002
 
@@ -935,10 +1009,21 @@ def order_and_seed_from_order(type)
935 1009
         order, seed = type.to_s.split(':')
936 1010
         @order = order
937 1011
         @seed  = seed = seed.to_i if seed
938  
-        @order, @seed = nil, nil if order == 'default'
  1012
+
  1013
+        if randomize?
  1014
+          order_groups_and_examples(&RANDOM_ORDERING)
  1015
+        elsif order == 'default'
  1016
+          @order, @seed = nil, nil
  1017
+          order_groups_and_examples(&DEFAULT_ORDERING)
  1018
+        end
  1019
+
939 1020
         return order, seed
940 1021
       end
941 1022
 
  1023
+      def built_in_orderer?(block)
  1024
+        [DEFAULT_ORDERING, RANDOM_ORDERING].include?(block)
  1025
+      end
  1026
+
942 1027
     end
943 1028
   end
944 1029
 end
2  lib/rspec/core/example_group.rb
@@ -241,7 +241,7 @@ def self.subclass(parent, args, &example_group_block)
241 241
 
242 242
       # @private
243 243
       def self.children
244  
-        @children ||= [].extend(Extensions::Ordered)
  244
+        @children ||= [].extend(Extensions::Ordered::ExampleGroups)
245 245
       end
246 246
 
247 247
       # @private
18  lib/rspec/core/extensions/ordered.rb
@@ -7,12 +7,18 @@ module Extensions
7 7
       # strategies like randomization.
8 8
       module Ordered
9 9
         # @private
10  
-        def ordered
11  
-          if RSpec.configuration.randomize?
12  
-            Kernel.srand RSpec.configuration.seed
13  
-            sort_by { Kernel.rand size }
14  
-          else
15  
-            self
  10
+        module ExampleGroups
  11
+          # @private
  12
+          def ordered
  13
+            RSpec.configuration.group_ordering_block.call(self)
  14
+          end
  15
+        end
  16
+
  17
+        # @private
  18
+        module Examples
  19
+          # @private
  20
+          def ordered
  21
+            RSpec.configuration.example_ordering_block.call(self)
16 22
           end
17 23
         end
18 24
       end
4  lib/rspec/core/world.rb
@@ -9,14 +9,14 @@ class World
9 9
 
10 10
       def initialize(configuration=RSpec.configuration)
11 11
         @configuration = configuration
12  
-        @example_groups = [].extend(Extensions::Ordered)
  12
+        @example_groups = [].extend(Extensions::Ordered::ExampleGroups)
13 13
         @shared_example_groups = {}
14 14
         @filtered_examples = Hash.new { |hash,group|
15 15
           hash[group] = begin
16 16
             examples = group.examples.dup
17 17
             examples = filter_manager.prune(examples)
18 18
             examples.uniq
19  
-            examples.extend(Extensions::Ordered)
  19
+            examples.extend(Extensions::Ordered::Examples)
20 20
           end
21 21
         }
22 22
       end
33  spec/command_line/order_spec.rb
@@ -110,6 +110,39 @@
110 110
     end
111 111
   end
112 112
 
  113
+  context 'when a custom order is configured' do
  114
+    before do
  115
+      write_file 'spec/custom_order_spec.rb', """
  116
+        RSpec.configure do |config|
  117
+          config.order_groups_and_examples do |list|
  118
+            list.sort_by { |item| item.description }
  119
+          end
  120
+        end
  121
+
  122
+        describe 'group B' do
  123
+          specify('group B example D')  {}
  124
+          specify('group B example B')  {}
  125
+          specify('group B example A')  {}
  126
+          specify('group B example C')  {}
  127
+        end
  128
+
  129
+        describe 'group A' do
  130
+          specify('group A example 1')  {}
  131
+        end
  132
+      """
  133
+    end
  134
+
  135
+    it 'orders the groups and examples by the provided strategy' do
  136
+      run_command 'tmp/aruba/spec/custom_order_spec.rb -f doc'
  137
+
  138
+      top_level_groups    { |groups| groups.flatten.should eq(['group A', 'group B']) }
  139
+      examples('group B') do |examples|
  140
+        letters = examples.flatten.map { |e| e[/(.)\z/, 1] }
  141
+        letters.should eq(['A', 'B', 'C', 'D'])
  142
+      end
  143
+    end
  144
+  end
  145
+
113 146
   def examples(group)
114 147
     yield split_in_half(stdout.string.scan(/^\s+#{group} example.*$/))
115 148
   end
84  spec/rspec/core/configuration_spec.rb
@@ -1128,6 +1128,14 @@ def metadata_hash(*args)
1128 1128
         config.order.should eq("rand")
1129 1129
       end
1130 1130
 
  1131
+      it 'can set random ordering' do
  1132
+        config.force :seed => "rand:37"
  1133
+        RSpec.stub(:configuration => config)
  1134
+        list = [1, 2, 3, 4].extend(Extensions::Ordered::Examples)
  1135
+        Kernel.should_receive(:rand).and_return(3, 1, 4, 2)
  1136
+        list.ordered.should eq([2, 4, 1, 3])
  1137
+      end
  1138
+
1131 1139
       it "forces 'false' value" do
1132 1140
         config.add_setting :custom_option
1133 1141
         config.custom_option = true
@@ -1175,6 +1183,13 @@ def metadata_hash(*args)
1175 1183
         it 'sets seed to 123' do
1176 1184
           config.seed.should eq(123)
1177 1185
         end
  1186
+
  1187
+        it 'sets up random ordering' do
  1188
+          RSpec.stub(:configuration => config)
  1189
+          list = [1, 2, 3, 4].extend(Extensions::Ordered::Examples)
  1190
+          Kernel.should_receive(:rand).and_return(3, 1, 4, 2)
  1191
+          list.ordered.should eq([2, 4, 1, 3])
  1192
+        end
1178 1193
       end
1179 1194
 
1180 1195
       context 'given "default"' do
@@ -1190,6 +1205,75 @@ def metadata_hash(*args)
1190 1205
         it "sets the seed to nil" do
1191 1206
           config.seed.should be_nil
1192 1207
         end
  1208
+
  1209
+        it 'clears the random ordering' do
  1210
+          RSpec.stub(:configuration => config)
  1211
+          list = [1, 2, 3, 4].extend(Extensions::Ordered::Examples)
  1212
+          Kernel.should_not_receive(:rand)
  1213
+          list.ordered.should eq([1, 2, 3, 4])
  1214
+        end
  1215
+      end
  1216
+    end
  1217
+
  1218
+    describe "#order_examples" do
  1219
+      before { RSpec.stub(:configuration => config) }
  1220
+
  1221
+      it 'sets a block that determines the ordering of a collection extended with Extensions::Ordered::Examples' do
  1222
+        examples = [1, 2, 3, 4]
  1223
+        examples.extend Extensions::Ordered::Examples
  1224
+        config.order_examples { |examples| examples.reverse }
  1225
+        examples.ordered.should eq([4, 3, 2, 1])
  1226
+      end
  1227
+
  1228
+      it 'sets #order to "custom"' do
  1229
+        config.order_examples { |examples| examples.reverse }
  1230
+        config.order.should eq("custom")
  1231
+      end
  1232
+    end
  1233
+
  1234
+    describe "#example_ordering_block" do
  1235
+      it 'defaults to a block that returns the passed argument' do
  1236
+        config.example_ordering_block.call([1, 2, 3]).should eq([1, 2, 3])
  1237
+      end
  1238
+    end
  1239
+
  1240
+    describe "#order_groups" do
  1241
+      before { RSpec.stub(:configuration => config) }
  1242
+
  1243
+      it 'sets a block that determines the ordering of a collection extended with Extensions::Ordered::ExampleGroups' do
  1244
+        groups = [1, 2, 3, 4]
  1245
+        groups.extend Extensions::Ordered::ExampleGroups
  1246
+        config.order_groups { |groups| groups.reverse }
  1247
+        groups.ordered.should eq([4, 3, 2, 1])
  1248
+      end
  1249
+
  1250
+      it 'sets #order to "custom"' do
  1251
+        config.order_groups { |groups| groups.reverse }
  1252
+        config.order.should eq("custom")
  1253
+      end
  1254
+    end
  1255
+
  1256
+    describe "#group_ordering_block" do
  1257
+      it 'defaults to a block that returns the passed argument' do
  1258
+        config.group_ordering_block.call([1, 2, 3]).should eq([1, 2, 3])
  1259
+      end
  1260
+    end
  1261
+
  1262
+    describe "#order_groups_and_examples" do
  1263
+      let(:examples) { [1, 2, 3, 4].extend Extensions::Ordered::Examples }
  1264
+      let(:groups)   { [1, 2, 3, 4].extend Extensions::Ordered::ExampleGroups }
  1265
+
  1266
+      before do
  1267
+        RSpec.stub(:configuration => config)
  1268
+        config.order_groups_and_examples { |list| list.reverse }
  1269
+      end
  1270
+
  1271
+      it 'sets a block that determines the ordering of a collection extended with Extensions::Ordered::Examples' do
  1272
+        examples.ordered.should eq([4, 3, 2, 1])
  1273
+      end
  1274
+
  1275
+      it 'sets a block that determines the ordering of a collection extended with Extensions::Ordered::ExampleGroups' do
  1276
+        groups.ordered.should eq([4, 3, 2, 1])
1193 1277
       end
1194 1278
     end
1195 1279
   end
6  spec/rspec/core/example_group_spec.rb
@@ -716,7 +716,7 @@ def metadata_hash(*args)
716 716
           example('ex 1') { 1.should eq(1) }
717 717
           example('ex 2') { 1.should eq(1) }
718 718
         end
719  
-        group.stub(:filtered_examples) { group.examples.extend(Extensions::Ordered) }
  719
+        group.stub(:filtered_examples) { group.examples.extend(Extensions::Ordered::Examples) }
720 720
         group.run(reporter).should be_true
721 721
       end
722 722
 
@@ -725,7 +725,7 @@ def metadata_hash(*args)
725 725
           example('ex 1') { 1.should eq(1) }
726 726
           example('ex 2') { 1.should eq(2) }
727 727
         end
728  
-        group.stub(:filtered_examples) { group.examples.extend(Extensions::Ordered) }
  728
+        group.stub(:filtered_examples) { group.examples.extend(Extensions::Ordered::Examples) }
729 729
         group.run(reporter).should be_false
730 730
       end
731 731
 
@@ -734,7 +734,7 @@ def metadata_hash(*args)
734 734
           example('ex 1') { 1.should eq(2) }
735 735
           example('ex 2') { 1.should eq(1) }
736 736
         end
737  
-        group.stub(:filtered_examples) { group.examples.extend(Extensions::Ordered) }
  737
+        group.stub(:filtered_examples) { group.examples.extend(Extensions::Ordered::Examples) }
738 738
         group.filtered_examples.each do |example|
739 739
           example.should_receive(:run)
740 740
         end

No commit comments for this range

Something went wrong with that request. Please try again.