require 'rbconfig' require 'tempfile' require 'open4' require Pathname(__FILE__).dirname + 'project_helper' module Montage module Spec # Runs montage commands in a subprocess and reports back on their exit # status and output. # # See spec/montage/commands/*_spec.rb. # class CommandRunner < ProjectHelper # Path to the Ruby binary. RUBY = Pathname.new(Config::CONFIG['bindir']) + Config::CONFIG['ruby_install_name'] # Path to the montage executable. EXECUTABLE = Pathname.new(__FILE__).dirname. expand_path + '../../bin/montage' attr_reader :status, :stderr, :stdout # ---------------------------------------------------------------------- # Creates a new CommandRunner instance. # # @param [String] command # The command to be run (exactly as it would be on the command-line). # def initialize(command) super() @command = command end # Runs the command in the test directory. # # @return [CommandRunner] # Returns self. # def run!(&block) run(@command, &block) end # Runs the given command in the test directory. # # @param [String] command # The command to be run. # # @return [CommandRunner] # Returns self. # def run(command, &block) if command =~ /^montage(.*)$/ command = "#{RUBY} #{EXECUTABLE}#{$1} --no-color" end @status, @stderr, @stdout = nil, nil, nil in_project_dir do @status = Open4.popen4(command.to_s) do |_, stdin, stdout, stderr| yield stdin if block_given? @stdout = stdout.read @stderr = stderr.read end.exitstatus end self end # Returns if the latest command completed successfully. # # @return [Boolean] # def success? @status == 0 end # Returns if the latest command failed to complete successfully. # # @return [Boolean] # def failure? not success? end # Returns the dimensions of a generated sprite image. # # @param [String] name # The name of the sprite file. # # @return [Array] # def dimensions_of(name) info = Magick::Image.ping path_to_sprite(name) [info.first.columns, info.first.rows] end private # -------------------------------------------------------------- # Temporarily switches to the test directory for running commands. def in_project_dir(&blk) Dir.chdir(project_dir, &blk) end end # CommandRunner # Runs the montage init command, providing the command with the various # inputs it wants. # class InitCommandRunner < CommandRunner # Creates a new InitCommandRunner instance. # # @param [Hash] responses # Takes inputs to be given to the highline GUI. Accepts :sources and # :sprites # def initialize(responses = {}) super 'montage init' @responses = responses end # Runs the command in the test directory. # # @return [InitCommandRunner] # Returns self. # def run! super do |stdin| stdin.puts @responses.fetch(:sprites, "\n") stdin.puts @responses.fetch(:sources, "\n") end end end end # Spec end # Montage