require 'rspec/expectations' require 'aruba/runtime' require 'aruba/errors' require 'aruba/setup' # Aruba module Aruba # Api module Api # Core methods of aruba # # Those methods do not depend on any other API method of aruba module Core include ::RSpec::Matchers # Aruba Runtime def aruba # TODO: Check this variable being accessed inconsistently. Should only be using the memo! # Renaming this to `aruba` causes 100's of rspec failures. Needs a deeper dive, approach with caution! @_aruba_runtime ||= Runtime.new end # Clean the working directory of aruba # # This will only clean up aruba's working directory to remove all # artifacts of your tests. This does NOT clean up the current working # directory. def setup_aruba(clobber = true) Aruba::Setup.new(aruba).call(clobber) self end # Execute block in Aruba's current directory # # @yield # The block which should be run in current directory def in_current_directory(&block) create_directory '.' unless directory?('.') cd('.', &block) end # Switch to directory # # @param [String] dir # The directory # # @example Normal directory # cd 'dir' # # @example Move up # cd '..' # # @example Run code in directory # result = cd('some-dir') { Dir.getwd } # # rubocop:disable Metrics/MethodLength def cd(dir, &block) if block_given? begin unless Aruba.platform.directory? expand_path(dir) fail ArgumentError, "#{expand_path(dir)} is not a directory or does not exist." end old_directory = expand_path('.') aruba.current_directory << dir new_directory = expand_path('.') aruba.event_bus.notify Events::ChangedWorkingDirectory.new(old: old_directory, new: new_directory) old_dir = Aruba.platform.getwd Aruba.platform.chdir File.join(aruba.root_directory, aruba.current_directory) result = with_environment( 'OLDPWD' => old_dir, 'PWD' => File.expand_path(File.join(aruba.root_directory, aruba.current_directory)), &block ) ensure aruba.current_directory.pop Aruba.platform.chdir old_dir end return result end unless Aruba.platform.directory? expand_path(dir) fail ArgumentError, "#{expand_path(dir)} is not a directory or does not exist." end old_directory = expand_path('.') aruba.current_directory << dir new_directory = expand_path('.') aruba.event_bus.notify Events::ChangedWorkingDirectory.new(old: old_directory, new: new_directory) self end # rubocop:enable Metrics/MethodLength # Expand file name # # @param [String] file_name # Name of file # # @param [String] dir_string # Name of directory to use as starting point, otherwise current directory is used. # # @return [String] # The full path # # @example Single file name # # # => /tmp/aruba/file # expand_path('file') # # @example Single Dot # # # => /tmp/aruba # expand_path('.') # # @example using home directory # # # => /home//file # expand_path('~/file') # # @example using fixtures directory # # # => /test/fixtures/file # expand_path('%/file') # # @example Absolute directory # # # => /foo/bar # expand_path('/foo/bar') # # rubocop:disable Metrics/MethodLength # rubocop:disable Metrics/CyclomaticComplexity # rubocop:disable Metrics/PerceivedComplexity def expand_path(file_name, dir_string = nil) # rubocop:disable Metrics/LineLength message = %(Filename "#{file_name}" needs to be a string. It cannot be nil or empty either. Please use `expand_path('.')` if you want the current directory to be expanded.) # rubocop:enable Metrics/LineLength fail ArgumentError, message unless file_name.is_a?(String) && !file_name.empty? # rubocop:disable Metrics/LineLength fail %(Aruba's working directory does not exist. Maybe you forgot to run `setup_aruba` before using its API.) unless Aruba.platform.directory? File.join(aruba.config.root_directory, aruba.config.working_directory) # rubocop:enable Metrics/LineLength prefix = file_name[0] rest = file_name[2..-1] if aruba.config.fixtures_path_prefix == prefix path = File.join(*[aruba.fixtures_directory, rest].compact) # rubocop:disable Metrics/LineLength fail ArgumentError, %(Fixture "#{rest}" does not exist in fixtures directory "#{aruba.fixtures_directory}". This was the one we found first on your system from all possible candidates: #{aruba.config.fixtures_directories.map { |p| format('"%s"', p) }.join(', ')}.) unless Aruba.platform.exist? path # rubocop:enable Metrics/LineLength path elsif prefix == '~' path = with_environment do ArubaPath.new(File.expand_path(file_name)) end fail ArgumentError, 'Expanding "~/" to "/" is not allowed' if path.to_s == '/' fail ArgumentError, %(Expanding "~/" to a relative path "#{path}" is not allowed) unless path.absolute? path.to_s elsif absolute? file_name unless aruba.config.allow_absolute_paths aruba.logger.warn 'Using absolute paths in Aruba is not recommended.' \ ' Set config.allow_absolute_paths = true to silence this warning' end file_name else directory = File.join(aruba.root_directory, aruba.current_directory) directory = File.expand_path(dir_string, directory) if dir_string File.expand_path(file_name, directory) end end # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/CyclomaticComplexity # rubocop:enable Metrics/PerceivedComplexity # Run block with environment # # @param [Hash] env (optional) # The variables to be used for block. # # @yield # The block of code which should be run with the changed environment variables def with_environment(env = {}, &block) old_aruba_env = aruba.environment.to_h # make sure the old environment is really restored in "ENV" Aruba.platform.with_environment aruba.environment.update(env).to_h, &block ensure # make sure the old environment is really restored in "aruba.environment" aruba.environment.clear aruba.environment.update old_aruba_env end end end end