diff --git a/toys-dev b/toys-dev index d5ddb780..c7eaf6dc 100755 --- a/toys-dev +++ b/toys-dev @@ -4,4 +4,5 @@ dir=$(cd `dirname $0` && pwd) export TOYS_DEV=true export TOYS_LIB_PATH="$dir/toys/lib" export TOYS_CORE_LIB_PATH="$dir/toys-core/lib" -exec ruby --disable=gems "$dir/toys/bin/toys" "$@" +export TOYS_BIN_PATH="$dir/toys/bin/toys" +exec ruby --disable=gems "$TOYS_BIN_PATH" "$@" diff --git a/toys/.rubocop.yml b/toys/.rubocop.yml index 9e91af8a..f3b6cac2 100644 --- a/toys/.rubocop.yml +++ b/toys/.rubocop.yml @@ -3,6 +3,7 @@ inherit_from: "../.rubocop-common.yml" AllCops: Exclude: - "test/rubocop-cases/**/*" + - "test/rspec-cases/**/*" - "core-docs/**/*" Layout/LineLength: Exclude: diff --git a/toys/lib/toys.rb b/toys/lib/toys.rb index 605c8402..bbef9f95 100644 --- a/toys/lib/toys.rb +++ b/toys/lib/toys.rb @@ -8,6 +8,7 @@ # don't get clobbered in case someone sets up bundler later. unless ::ENV.key?("TOYS_CORE_LIB_PATH") path = ::File.expand_path("../../toys-core-#{::Toys::VERSION}/lib", __dir__) + path = ::File.expand_path("../../toys-core/lib", __dir__) unless path && ::File.directory?(path) unless path && ::File.directory?(path) require "rubygems" dep = ::Gem::Dependency.new("toys-core", "= #{::Toys::VERSION}") diff --git a/toys/lib/toys/templates/minitest.rb b/toys/lib/toys/templates/minitest.rb index fc73a22a..6e2baa3d 100644 --- a/toys/lib/toys/templates/minitest.rb +++ b/toys/lib/toys/templates/minitest.rb @@ -269,13 +269,6 @@ def bundler_settings libs = Array(template.libs) ruby_args << "-I#{libs.join(::File::PATH_SEPARATOR)}" unless libs.empty? ruby_args << "-w" if warnings - ruby_args << "-" - ruby_args << "--seed" << seed if seed - vv = verbosity - vv += 1 if template.verbose - ruby_args << "--verbose" if vv.positive? - ruby_args << "--name" << name if name - ruby_args << "--exclude" << exclude if exclude if tests.empty? Array(template.files).each do |pattern| @@ -283,13 +276,18 @@ def bundler_settings end tests.uniq! end + code = ["require 'minitest/autorun'"] + tests.map { |file| "load '#{file}'" } + ruby_args << "-e" << code.join("\n") - result = exec_ruby(ruby_args, in: :controller) do |controller| - controller.in.puts("require 'minitest/autorun'") - tests.each do |file| - controller.in.puts("load '#{file}'") - end - end + ruby_args << "--" + ruby_args << "--seed" << seed if seed + vv = verbosity + vv += 1 if template.verbose + ruby_args << "--verbose" if vv.positive? + ruby_args << "--name" << name if name + ruby_args << "--exclude" << exclude if exclude + + result = exec_ruby(ruby_args) if result.error? logger.error("Minitest failed!") exit(result.exit_code) diff --git a/toys/lib/toys/templates/rdoc.rb b/toys/lib/toys/templates/rdoc.rb index 43ac7b03..16f62544 100644 --- a/toys/lib/toys/templates/rdoc.rb +++ b/toys/lib/toys/templates/rdoc.rb @@ -322,11 +322,12 @@ def bundler_settings args << "-T" << template.template if template.template args << "-f" << template.generator if template.generator - exec_ruby([], in: :controller) do |controller| - controller.in.puts("gem 'rdoc', *#{gem_requirements.inspect}") - controller.in.puts("require 'rdoc'") - controller.in.puts("::RDoc::RDoc.new.document(#{(args + files).inspect})") - end + code = <<~CODE + gem 'rdoc', *#{gem_requirements.inspect} + require 'rdoc' + ::RDoc::RDoc.new.document(#{(args + files).inspect}) + CODE + exec_ruby(["-e", code]) end end end diff --git a/toys/lib/toys/templates/rspec.rb b/toys/lib/toys/templates/rspec.rb index 57b35251..2a351b71 100644 --- a/toys/lib/toys/templates/rspec.rb +++ b/toys/lib/toys/templates/rspec.rb @@ -352,7 +352,15 @@ def bundler_settings libs = Array(template.libs) ruby_args << "-I#{libs.join(::File::PATH_SEPARATOR)}" unless libs.empty? ruby_args << "-w" if warnings - ruby_args << "-" + + code = <<~CODE + gem 'rspec', *#{gem_requirements.inspect} + require 'rspec/core' + ::RSpec::Core::Runner.invoke + CODE + ruby_args << "-e" << code + + ruby_args << "--" ruby_args << "--options" << template.options if template.options ruby_args << "--order" << order if order ruby_args << "--format" << format if format @@ -364,11 +372,7 @@ def bundler_settings ruby_args << "--tag" << tag if tag ruby_args.concat(files) - result = exec_ruby(ruby_args, in: :controller) do |controller| - controller.in.puts("gem 'rspec', *#{gem_requirements.inspect}") - controller.in.puts("require 'rspec/core'") - controller.in.puts("::RSpec::Core::Runner.invoke") - end + result = exec_ruby(ruby_args) if result.error? logger.error("RSpec failed!") exit(result.exit_code) diff --git a/toys/lib/toys/templates/rubocop.rb b/toys/lib/toys/templates/rubocop.rb index 23465d08..5d4bdf6f 100644 --- a/toys/lib/toys/templates/rubocop.rb +++ b/toys/lib/toys/templates/rubocop.rb @@ -184,11 +184,12 @@ def bundler_settings ::Dir.chdir(context_directory || ::Dir.getwd) do logger.info "Running RuboCop..." - result = exec_ruby([], in: :controller) do |controller| - controller.in.puts("gem 'rubocop', *#{template.gem_version.inspect}") - controller.in.puts("require 'rubocop'") - controller.in.puts("exit(::RuboCop::CLI.new.run(#{template.options.inspect}))") - end + code = <<~CODE + gem 'rubocop', *#{template.gem_version.inspect} + require 'rubocop' + exit(::RuboCop::CLI.new.run(#{template.options.inspect})) + CODE + result = exec_ruby(["-e", code]) if result.error? logger.error "RuboCop failed!" exit(1) if template.fail_on_error diff --git a/toys/lib/toys/templates/yardoc.rb b/toys/lib/toys/templates/yardoc.rb index e4cab82d..26d32702 100644 --- a/toys/lib/toys/templates/yardoc.rb +++ b/toys/lib/toys/templates/yardoc.rb @@ -503,21 +503,23 @@ def bundler_settings end run_options.concat(files) - result = exec_ruby([], in: :controller) do |controller| - controller.in.puts("gem 'yard', *#{gem_requirements.inspect}") - controller.in.puts("require 'yard'") - controller.in.puts("::YARD::CLI::Yardoc.run(*#{run_options.inspect})") - end + code = <<~CODE + gem 'yard', *#{gem_requirements.inspect} + require 'yard' + ::YARD::CLI::Yardoc.run(*#{run_options.inspect}) + CODE + result = exec_ruby(["-e", code]) if result.error? puts("Yardoc encountered errors", :red, :bold) unless verbosity.negative? exit(1) end unless stats_options.empty? - result = exec_ruby([], in: :controller, out: :capture) do |controller| - controller.in.puts("gem 'yard', *#{gem_requirements.inspect}") - controller.in.puts("require 'yard'") - controller.in.puts("::YARD::CLI::Stats.run(*#{stats_options.inspect})") - end + code = <<~CODE + gem 'yard', *#{gem_requirements.inspect} + require 'yard' + ::YARD::CLI::Stats.run(*#{stats_options.inspect}) + CODE + result = exec_ruby(["-e", code], out: :capture) puts result.captured_out if result.error? puts("Yardoc encountered errors", :red, :bold) unless verbosity.negative? diff --git a/toys/test/minitest-cases/stream/.toys.rb b/toys/test/minitest-cases/stream/.toys.rb new file mode 100644 index 00000000..5d7f225a --- /dev/null +++ b/toys/test/minitest-cases/stream/.toys.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +truncate_load_path! + +expand :minitest, files: "foo.rb" diff --git a/toys/test/minitest-cases/stream/foo.rb b/toys/test/minitest-cases/stream/foo.rb new file mode 100644 index 00000000..1cbd2489 --- /dev/null +++ b/toys/test/minitest-cases/stream/foo.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require "minitest/autorun" + +describe "foo" do + it "reads hello" do + assert_equal("hello\n", $stdin.read) + end +end diff --git a/toys/test/rspec-cases/lib1/spec_fixture.rb b/toys/test/rspec-cases/lib1/spec_fixture.rb index a3b7f0c1..197ea74e 100644 --- a/toys/test/rspec-cases/lib1/spec_fixture.rb +++ b/toys/test/rspec-cases/lib1/spec_fixture.rb @@ -2,6 +2,6 @@ module SpecFixture def self.foo - :foo + "foo" end end diff --git a/toys/test/rspec-cases/lib2/spec_fixture.rb b/toys/test/rspec-cases/lib2/spec_fixture.rb index 97d016b0..2ecddc33 100644 --- a/toys/test/rspec-cases/lib2/spec_fixture.rb +++ b/toys/test/rspec-cases/lib2/spec_fixture.rb @@ -2,6 +2,6 @@ module SpecFixture def self.foo - :bar + "bar" end end diff --git a/toys/test/rspec-cases/spec/my_spec.rb b/toys/test/rspec-cases/spec/my_spec.rb index 25ff15d6..316c04a7 100644 --- a/toys/test/rspec-cases/spec/my_spec.rb +++ b/toys/test/rspec-cases/spec/my_spec.rb @@ -4,6 +4,6 @@ describe SpecFixture do it "returns foo" do - expect(SpecFixture.foo).to eql(:foo) + expect(SpecFixture.foo).to eql("foo") end end diff --git a/toys/test/rspec-cases/stream/.toys.rb b/toys/test/rspec-cases/stream/.toys.rb new file mode 100644 index 00000000..056116a5 --- /dev/null +++ b/toys/test/rspec-cases/stream/.toys.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +truncate_load_path! + +expand :rspec, pattern: "*_spec.rb" diff --git a/toys/test/rspec-cases/stream/my_spec.rb b/toys/test/rspec-cases/stream/my_spec.rb new file mode 100644 index 00000000..a6f14b44 --- /dev/null +++ b/toys/test/rspec-cases/stream/my_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +describe "streams" do + it "returns foo" do + expect($stdin.read.strip).to eql("foo") + end +end diff --git a/toys/test/test_minitest.rb b/toys/test/test_minitest.rb index b993c040..dad03661 100644 --- a/toys/test/test_minitest.rb +++ b/toys/test/test_minitest.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "helper" +require "toys/utils/exec" describe "minitest template" do let(:template_lookup) { Toys::ModuleLookup.new.add_path("toys/templates") } @@ -128,6 +129,7 @@ let(:cli) { Toys::CLI.new(middleware_stack: [], template_lookup: template_lookup) } let(:loader) { cli.loader } let(:cases_dir) { File.join(__dir__, "minitest-cases") } + let(:exec_service) { Toys::Utils::Exec.new } it "runs passing tests" do dir = cases_dir @@ -163,5 +165,17 @@ end assert_match(/1 failure/, out) end + + it "supports input streams" do + dir = "#{cases_dir}/stream" + args = ["--disable=gems", Toys.executable_path, "test"] + result = exec_service.exec_ruby(args, chdir: dir, + in: :controller, out: :capture) do |controller| + controller.in.puts "hello" + end + assert(result.success?) + assert_match(/0 failures/, result.captured_out) + assert_match(/0 errors/, result.captured_out) + end end end diff --git a/toys/test/test_rspec.rb b/toys/test/test_rspec.rb index e123039f..6ba0164e 100644 --- a/toys/test/test_rspec.rb +++ b/toys/test/test_rspec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "helper" +require "toys/utils/exec" describe "rspec template" do let(:template_lookup) { Toys::ModuleLookup.new.add_path("toys/templates") } @@ -155,12 +156,14 @@ describe "integration functionality" do let(:cli) { Toys::CLI.new(middleware_stack: [], template_lookup: template_lookup) } let(:loader) { cli.loader } + let(:cases_dir) { File.join(__dir__, "rspec-cases") } + let(:exec_service) { Toys::Utils::Exec.new } it "executes a successful spec" do - cases_dir = File.join(__dir__, "rspec-cases") + dir = cases_dir loader.add_block do - expand :rspec, libs: File.join(cases_dir, "lib1"), - pattern: File.join(cases_dir, "spec", "*_spec.rb") + set_context_directory dir + expand :rspec, libs: "lib1", pattern: "spec/*_spec.rb" end out, _err = capture_subprocess_io do assert_equal(0, cli.run("spec")) @@ -169,10 +172,10 @@ end it "executes an unsuccessful spec" do - cases_dir = File.join(__dir__, "rspec-cases") + dir = cases_dir loader.add_block do - expand :rspec, libs: File.join(cases_dir, "lib2"), - pattern: File.join(cases_dir, "spec", "*_spec.rb") + set_context_directory dir + expand :rspec, libs: "lib2", pattern: "spec/*_spec.rb" end out, _err = capture_subprocess_io do refute_equal(0, cli.run("spec")) @@ -181,14 +184,25 @@ end it "honors the context_directory setting" do - cases_dir = File.join(__dir__, "rspec-cases") + dir = cases_dir loader.add_block do - expand :rspec, libs: "lib1", pattern: "spec/*_spec.rb", context_directory: cases_dir + expand :rspec, libs: "lib1", pattern: "spec/*_spec.rb", context_directory: dir end out, _err = capture_subprocess_io do assert_equal(0, cli.run("spec")) end assert_match(/1 example, 0 failures/, out) end + + it "supports input streams" do + dir = "#{cases_dir}/stream" + args = ["--disable=gems", Toys.executable_path, "spec"] + result = exec_service.exec_ruby(args, chdir: dir, + in: :controller, out: :capture) do |controller| + controller.in.puts "foo" + end + assert(result.success?) + assert_match(/0 failures/, result.captured_out) + end end end