diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c34e040..8e2058db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- The `specify-groups` option supports reading from STDIN when set to `-` + ### Breaking Changes ### Added diff --git a/Readme.md b/Readme.md index 9c6480ca..1943f8f7 100644 --- a/Readme.md +++ b/Readme.md @@ -258,7 +258,8 @@ Options are: --failure-exit-code INT Specify the exit code to use when tests fail --specify-groups SPECS Use 'specify-groups' if you want to specify multiple specs running in multiple processes in a specific formation. Commas indicate specs in the same process, - pipes indicate specs in a new process. Cannot use with --single, --isolate, or + pipes indicate specs in a new process. If SPECS is a `-` the value for this + option is read from STDIN instead. Cannot use with --single, --isolate, or --isolate-n. Ex. $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb' Process 1 will contain 1_spec.rb and 2_spec.rb diff --git a/lib/parallel_tests/cli.rb b/lib/parallel_tests/cli.rb index 56b51dbc..7bebffcd 100644 --- a/lib/parallel_tests/cli.rb +++ b/lib/parallel_tests/cli.rb @@ -254,7 +254,8 @@ def parse_options!(argv) <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}") Use 'specify-groups' if you want to specify multiple specs running in multiple processes in a specific formation. Commas indicate specs in the same process, - pipes indicate specs in a new process. Cannot use with --single, --isolate, or + pipes indicate specs in a new process. If SPECS is a '-' the value for this + option is read from STDIN instead. Cannot use with --single, --isolate, or --isolate-n. Ex. $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb' Process 1 will contain 1_spec.rb and 2_spec.rb diff --git a/lib/parallel_tests/grouper.rb b/lib/parallel_tests/grouper.rb index 44402764..b444a5e6 100644 --- a/lib/parallel_tests/grouper.rb +++ b/lib/parallel_tests/grouper.rb @@ -48,8 +48,15 @@ def in_even_groups_by_size(items, num_groups, options = {}) private + def specified_groups(options) + groups = options[:specify_groups] + return groups if groups != '-' + + $stdin.read.chomp + end + def specify_groups(items, num_groups, options, groups) - specify_test_process_groups = options[:specify_groups].split('|') + specify_test_process_groups = specified_groups(options).split('|') if specify_test_process_groups.count > num_groups raise 'Number of processes separated by pipe must be less than or equal to the total number of processes' end diff --git a/spec/parallel_tests/grouper_spec.rb b/spec/parallel_tests/grouper_spec.rb index 57f0764c..0240c066 100644 --- a/spec/parallel_tests/grouper_spec.rb +++ b/spec/parallel_tests/grouper_spec.rb @@ -76,50 +76,116 @@ def call(num_groups, options = {}) ) end - it "groups specify_groups as specified when specify_groups is just one spec" do - expect(call(3, specify_groups: '1')).to eq([["1"], ["2", "5"], ["3", "4"]]) - end + context 'with specific groups provided directly' do + it "groups specify_groups as specified when specify_groups is just one spec" do + expect(call(3, specify_groups: '1')).to eq([["1"], ["2", "5"], ["3", "4"]]) + end - it "groups specify_groups as specified when specify_groups is just multiple specs in one process" do - expect(call(3, specify_groups: '3,1')).to eq([["3", "1"], ["5"], ["2", "4"]]) - end + it "groups specify_groups as specified when specify_groups is just multiple specs in one process" do + expect(call(3, specify_groups: '3,1')).to eq([["3", "1"], ["5"], ["2", "4"]]) + end - it "groups specify_groups as specified when specify_groups is multiple specs" do - expect(call(3, specify_groups: '1,2|4')).to eq([["1", "2"], ["4"], ["3", "5"]]) - end + it "groups specify_groups as specified when specify_groups is multiple specs" do + expect(call(3, specify_groups: '1,2|4')).to eq([["1", "2"], ["4"], ["3", "5"]]) + end - it "specify_groups aborts when number of specs separated by pipe is out of bounds" do - expect do - call(3, specify_groups: '1|2|3|4') - end.to raise_error( - "Number of processes separated by pipe must be less than or equal to the total number of processes" - ) - end + it "specify_groups aborts when number of specs separated by pipe is out of bounds" do + expect do + call(3, specify_groups: '1|2|3|4') + end.to raise_error( + "Number of processes separated by pipe must be less than or equal to the total number of processes" + ) + end - it "specify_groups aborts when spec passed in doesn't match existing specs" do - expect do - call(3, specify_groups: '1|2|6') - end.to raise_error( - "Could not find [\"6\"] from --specify-groups in the selected files & folders" - ) - end + it "specify_groups aborts when spec passed in doesn't match existing specs" do + expect do + call(3, specify_groups: '1|2|6') + end.to raise_error( + "Could not find [\"6\"] from --specify-groups in the selected files & folders" + ) + end - it "specify_groups aborts when spec passed in doesn't match existing specs again" do - expect do - call(3, specify_groups: '1,6|2') - end.to raise_error( - "Could not find [\"6\"] from --specify-groups in the selected files & folders" - ) - end + it "specify_groups aborts when spec passed in doesn't match existing specs again" do + expect do + call(3, specify_groups: '1,6|2') + end.to raise_error( + "Could not find [\"6\"] from --specify-groups in the selected files & folders" + ) + end - it "specify_groups aborts when number of specs is equal to number passed in" do - expect do - call(3, specify_groups: '1|2|3') - end.to raise_error(/The specs that aren't run:\n\["4", "5"\]/) + it "specify_groups aborts when number of specs is equal to number passed in" do + expect do + call(3, specify_groups: '1|2|3') + end.to raise_error(/The specs that aren't run:\n\["4", "5"\]/) + end + + it "specify_groups does not abort when the every single spec is specified in it" do + expect(call(3, specify_groups: '1,2|3,4|5')).to eq([["1", "2"], ["3", "4"], ["5"]]) + end end - it "specify_groups does not abort when the every single spec is specified in it" do - expect(call(3, specify_groups: '1,2|3,4|5')).to eq([["1", "2"], ["3", "4"], ["5"]]) + context 'with specific groups provided through STDIN' do + it "groups specify_groups as specified when specify_groups is just one spec" do + allow($stdin).to receive(:read).and_return("1\n") + + expect(call(3, specify_groups: '-')).to eq([["1"], ["2", "5"], ["3", "4"]]) + end + + it "groups specify_groups as specified when specify_groups is just multiple specs in one process" do + allow($stdin).to receive(:read).and_return("3,1\n") + + expect(call(3, specify_groups: '-')).to eq([["3", "1"], ["5"], ["2", "4"]]) + end + + it "groups specify_groups as specified when specify_groups is multiple specs" do + allow($stdin).to receive(:read).and_return("1,2|4\n") + + expect(call(3, specify_groups: '-')).to eq([["1", "2"], ["4"], ["3", "5"]]) + end + + it "specify_groups aborts when number of specs separated by pipe is out of bounds" do + allow($stdin).to receive(:read).and_return("1|2|3|4\n") + + expect do + call(3, specify_groups: '-') + end.to raise_error( + "Number of processes separated by pipe must be less than or equal to the total number of processes" + ) + end + + it "specify_groups aborts when spec passed in doesn't match existing specs" do + allow($stdin).to receive(:read).and_return("1|2|6\n") + + expect do + call(3, specify_groups: '-') + end.to raise_error( + "Could not find [\"6\"] from --specify-groups in the selected files & folders" + ) + end + + it "specify_groups aborts when spec passed in doesn't match existing specs again" do + allow($stdin).to receive(:read).and_return("1,6|2\n") + + expect do + call(3, specify_groups: '-') + end.to raise_error( + "Could not find [\"6\"] from --specify-groups in the selected files & folders" + ) + end + + it "specify_groups aborts when number of specs is equal to number passed in" do + allow($stdin).to receive(:read).and_return("1|2|3\n") + + expect do + call(3, specify_groups: '-') + end.to raise_error(/The specs that aren't run:\n\["4", "5"\]/) + end + + it "specify_groups does not abort when the every single spec is specified in it" do + allow($stdin).to receive(:read).and_return("1,2|3,4|5\n") + + expect(call(3, specify_groups: '-')).to eq([["1", "2"], ["3", "4"], ["5"]]) + end end end