require 'rake' require 'fileutils' require 'rspec/core/rake_task' module Henry class Task # The Henry Task implementation for Rspec class RspecTask < Task # The temporary output file path for the RspecTask execution. OUT_PATH = 'rspec.out' # The reports path template. REPORTS_DIR = '.henry/reports/${FORMAT}' # Executes the Task and returns its results. def execute begin Rake.application['spec'].invoke self.execution.code = 'OK' self.execution.message = 'OK' self.execution.output = File.open(OUT_PATH, 'r').read self.execution.log = self.logger.log_as_hash rescue Exception => e self.execution.code = 'ERROR' self.execution.message = 'ERROR' self.execution.output = File.open(OUT_PATH, 'r').read self.execution.backtrace = e.message self.execution.log = self.logger.log_as_hash end end # Configures the Task. # # @param [Hash] params the task params. # @param [Hash] extended_context the task extended context. def configure(params, extended_context) File.open(OUT_PATH, 'w') { |f| } # Makes available the spec rake task. RSpec::Core::RakeTask.new do |t| if self.data.options t.pattern = self.data.options['pattern'] || 'spec/*' t.rspec_opts = "#{self.custom_options} #{extended_context['options']}" else t.pattern = 'spec/*' t.rspec_opts = "#{self.default_options} #{extended_context['options']}" end end self.export_params(params) end protected # Returns the custom rspec_opts that user may have passed. # # @return [String] def custom_options "#{self.format_options} #{self.tags_options} #{self.report_options}" end # Returns the default rspec_opts. # # @return [String] def default_options "--color --format documentation --format documentation --out #{OUT_PATH}" end # Returns the rspec_opts related with formatting. # # @return [String] def format_options "--color --format #{self.data.options['format'] || 'documentation'} --format #{self.data.options['format'] || 'documentation'} --out #{OUT_PATH}" end # Returns the rspec_opts related with tags to be run. # # @return [String] def tags_options return '' if self.data.options['tags'].nil? self.data.options['tags'].collect do |tag| "--tag #{tag}" end.join(' ') end # Returns the rspec_opts related with report paaths and formats. # # @return [String] def report_options return '' if self.data.reports.nil? self.data.reports.collect do |report_options| FileUtils.mkdir_p(self.reports_dir(report_options['format'])) "--format #{report_options['format']} --out #{self.report_file_path(report_options['format'], report_options['name'])}" end.join(' ') end # Returns the report file path for the given format and file name. # # @param [String] format the rspec formatter name. # @param [String] file_name the report file name template. # @return [String] the report file path. def report_file_path(format, file_name) "#{self.reports_dir(format)}/#{self.report_file_name(file_name)}" end # Interpolates and returns the report file name. # # @param [String] file_name the report file name. # @returns [String] the report file name. def report_file_name(file_name) file_name.gsub(/\${[A-Z_]+}/, '${TASK_NAME}' => self.name, '${DATE}' => DateTime.now.to_s).gsub(' ', '_') end # Interpolates and returns the reports directory for the given format. # # @param [String] format the formatter name. # @return [Stiring] the reports directory. def reports_dir(format) REPORTS_DIR.gsub(/\${[A-Z_]+}/, '${FORMAT}' => format).gsub(' ', '_') end end end end