Skip to content

Commit

Permalink
Use custom TextFormatter and Runner
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Oct 10, 2013
1 parent ce3dfec commit 5f7467e
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 116 deletions.
93 changes: 12 additions & 81 deletions app/app.rb
Original file line number Diff line number Diff line change
@@ -1,39 +1,6 @@
require 'opal'
require 'opal-rspec'

# make sure should and expect syntax are both loaded
RSpec::Expectations::Syntax.enable_should
RSpec::Expectations::Syntax.enable_expect

# opal doesnt yet support module_exec for defining methods in modules properly
module RSpec::Matchers
alias_method :expect, :expect
end

# enable_should uses module_exec which does not donate methods to bridged classes
module Kernel
alias should should
alias should_not should_not
end

# Module#include should also include constants (as should class subclassing)
RSpec::Core::ExampleGroup::AllHookMemoizedHash = RSpec::Core::MemoizedHelpers::AllHookMemoizedHash

# bad.. something is going wrong inside hooks - so set hooks to empty, for now
# or is it a problem with Array.public_instance_methods(false) adding all array
# methods to this class and thus breaking things like `self.class.new`
class RSpec::Core::Hooks::HookCollection
def for(a)
RSpec::Core::Hooks::HookCollection.new.with(a)
end
end

class RSpec::Core::Hooks::AroundHookCollection
def for(a)
RSpec::Core::Hooks::AroundHookCollection.new.with(a)
end
end

describe "Adam" do
it "should eat" do
1.should == 1
Expand All @@ -50,58 +17,22 @@ def for(a)
end
end

class OpalRSpecFormatter < BasicObject
def method_missing(*args)
Kernel.p args
end
end
describe "Some let tests" do
let(:adam) { 100 }

class OpalRSpecRunner
def initialize(options={}, configuration=RSpec::configuration, world=RSpec::world)
@options = options
@configuration = configuration
@world = world
it "should eat pieee" do
adam.should == 200
end
end

def run(err, out)
# load specs by the time this runs!
@configuration.error_stream = err
@configuration.output_stream ||= out

puts "Examples to run: #{@world.example_count}"
@configuration.formatter = OpalRSpecFormatter
@configuration.reporter.report(@world.example_count) do |reporter|
begin
@configuration.run_hook(:before, :suite)
@world.example_groups.map {|g| g.run(reporter) }.all? ? 0 : @configuration.failure_exit_code
ensure
@configuration.run_hook(:after, :suite)
end
end
describe "Normal errors" do
it "should still work" do
raise "wtf son"
end
end

def reporter
return @reporter if @reporter

@reporter = BasicObject.new
def @reporter.method_missing(*args); Kernel.p args; end
def @reporter.example_failed(example)
exception = example.metadata[:execution_result][:exception]

Kernel.puts "FAILED: #{example.description}"
Kernel.puts "#{exception.class.name}: #{exception.message}"
end

def @reporter.example_started(example)
Kernel.puts "starting: #{example.description}"
end

def @reporter.example_passed(example)
Kernel.puts "PASSED: #{example.description}"
end

@reporter
end
RSpec.configure do |config|
config.formatter = OpalRSpec::TextFormatter
end

OpalRSpecRunner.new.run($stdout, $stdout)
OpalRSpec::Runner.new.run
35 changes: 0 additions & 35 deletions app/opal-rspec.rb

This file was deleted.

1 change: 1 addition & 0 deletions config.ru
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Opal::Processor.source_map_enabled = false
Opal::Processor.dynamic_require_severity = :warning

Opal.append_path 'app' # load first so stub files come before real rspec files
Opal.append_path 'opal' # load first so stub files come before real rspec files
Opal.use_gem 'rspec'
Opal.use_gem 'rspec-expectations'

Expand Down
15 changes: 15 additions & 0 deletions opal/opal-rspec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require 'file'
require 'dir'
require 'thread'

require 'rspec/core'
require 'rspec/mocks'
require 'rspec-expectations'

# For now, we don't support mocking. This placeholder in rspec-core allows that.
# use any mocking. win.
require 'rspec/core/mocking/with_absolutely_nothing'

require 'opal-rspec/fixes'
require 'opal-rspec/text_formatter'
require 'opal-rspec/runner'
57 changes: 57 additions & 0 deletions opal/opal-rspec/fixes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# String#<< is not supported by Opal
module RSpec::Expectations
def self.fail_with(message, expected = nil, actual = nil)
if !message
raise ArgumentError, "Failure message is nil. Does your matcher define the " +
"appropriate failure_message_for_* method to return a string?"
end

raise RSpec::Expectations::ExpectationNotMetError.new(message)
end
end

# Opal does not support mutable strings
module RSpec::Matchers::Pretty
def underscore(camel_cased_word)
word = camel_cased_word.to_s.dup
word = word.gsub(/([A-Z]+)([A-Z][a-z])/,'$1_$2')
word = word.gsub(/([a-z\d])([A-Z])/,'$1_$2')
word = word.tr("-", "_")
word = word.downcase
word
end
end

# make sure should and expect syntax are both loaded
RSpec::Expectations::Syntax.enable_should
RSpec::Expectations::Syntax.enable_expect

# opal doesnt yet support module_exec for defining methods in modules properly
module RSpec::Matchers
alias_method :expect, :expect
end

# enable_should uses module_exec which does not donate methods to bridged classes
module Kernel
alias should should
alias should_not should_not
end

# Module#include should also include constants (as should class subclassing)
RSpec::Core::ExampleGroup::AllHookMemoizedHash = RSpec::Core::MemoizedHelpers::AllHookMemoizedHash

# bad.. something is going wrong inside hooks - so set hooks to empty, for now
# or is it a problem with Array.public_instance_methods(false) adding all array
# methods to this class and thus breaking things like `self.class.new`
class RSpec::Core::Hooks::HookCollection
def for(a)
RSpec::Core::Hooks::HookCollection.new.with(a)
end
end

class RSpec::Core::Hooks::AroundHookCollection
def for(a)
RSpec::Core::Hooks::AroundHookCollection.new.with(a)
end
end

29 changes: 29 additions & 0 deletions opal/opal-rspec/runner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module OpalRSpec
class Runner
def initialize(options={}, configuration=RSpec::configuration, world=RSpec::world)
@options = options
@configuration = configuration
@world = world
end

def run(err=$stdout, out=$stdout)
# load specs by the time this runs!
@configuration.error_stream = err
@configuration.output_stream ||= out

@configuration.reporter.report(@world.example_count) do |reporter|
begin
@configuration.run_hook(:before, :suite)
@world.example_groups.map {|g| g.run(reporter) }.all? ? 0 : @configuration.failure_exit_code
ensure
@configuration.run_hook(:after, :suite)
end
end
end

def reporter
RSpec.configuration.formatter
end
end
end

89 changes: 89 additions & 0 deletions opal/opal-rspec/text_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
module OpalRSpec
class TextFormatter
attr_accessor :example_group
attr_reader :duration, :examples, :output
attr_reader :example_count, :pending_count, :failure_count
attr_reader :failed_examples, :pending_examples

def initialize(*args)
@example_count = @pending_count = @failure_count = 0
@examples = []
@failed_examples = []
@pending_examples = []
@example_group = nil
end

def start(example_count)
@example_count = example_count
end

def example_group_started(example_group)
@example_group = example_group
end

def example_group_finished(example_group)
end

def example_started(example)
examples << example
end

def example_passed(example)
end

def example_pending(example)
@pending_examples << example
end

def example_failed(example)
@failed_examples << example
end

def stop
end

def start_dump
end

def dump_failures
return if failed_examples.empty?
puts "\n"
puts "Failures:"
failed_examples.each_with_index do |example, index|
puts "\n"
dump_failure(example, index)
end
end

def dump_failure(example, index)
puts "#{short_padding}#{index.next}) #{example.full_description}"
dump_failure_info(example)
end

def dump_failure_info(example)
exception = example.execution_result[:exception]
exception_class_name = exception.class.name.to_s
puts "#{long_padding}#{exception_class_name}:"
exception.message.to_s.split("\n").each { |line| puts "#{long_padding} #{line}" }
end

def short_padding
' '
end

def long_padding
' '
end

def dump_summary(duration, example_count, failure_count, pending_count)
@duration = duration
@example_count = example_count
@failure_count = failure_count
@pending_count = pending_count

puts "\nFinished\n"
puts "#{example_count} examples, #{failure_count} failures (time taken: #{duration})"
end
end
end

0 comments on commit 5f7467e

Please sign in to comment.