tengu 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 12e7d2f0783ace8519c31deb1b36a70057c2ddb2
4
+ data.tar.gz: 22900571d9768970c13b1fe6bb42cdfa220e45b4
5
+ SHA512:
6
+ metadata.gz: 575f49bd06887612dfa45a755047358e2f8ec8b9ad6ad7745cb9c1b7d9b0eabd3356ef7858d8642e9f3f8556d103d4f21ea31b24541919ca481e2884736e2180
7
+ data.tar.gz: a20dc50058a5bc07118fa8cf12d0d5172e1b3f7f9bd05eecc1a25d3be98cc0e9657396960a4e76d400008c7b56f69c5c15f76af5614fe712a1e5afed3ee43533
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tengu.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 halogenandtoast
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # Tengu
2
+
3
+ An object oriented test library with similar syntax to RSpec
4
+
5
+ ## About
6
+
7
+ This is a work in progress and isn't suggested for actual use.
8
+
9
+
10
+ ## Contributing
11
+
12
+ 1. Fork it
13
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
14
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
15
+ 4. Push to the branch (`git push origin my-new-feature`)
16
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'tengu/rake_task'
4
+
5
+ Tengu::RakeTask.new(:spec)
6
+
7
+ task default: :spec
data/bin/tengu ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
4
+
5
+ require "tengu"
6
+
7
+ formatter = Tengu::BaseFormatter.new
8
+ runner = Tengu::Runner.new
9
+
10
+ if ARGV.count < 1
11
+ files = Dir.glob("spec/**/*_spec.rb").map { |filename| ::File.open(filename, "r") }
12
+ else
13
+ files = ARGV.map { |arg| ::File.open(arg, "r") }
14
+ end
15
+
16
+ runner.run(files, [formatter])
data/lib/tengu.rb ADDED
@@ -0,0 +1,19 @@
1
+ require "tengu/base_formatter"
2
+ require "tengu/composite_matcher"
3
+ require "tengu/describe_block.rb"
4
+ require "tengu/expectation"
5
+ require "tengu/file"
6
+ require "tengu/it_block.rb"
7
+ require "tengu/matcher"
8
+ require "tengu/matchers"
9
+ require "tengu/result"
10
+ require "tengu/runner"
11
+ require "tengu/version"
12
+
13
+ module Tengu
14
+ def self.test(file_name, formatter = nil)
15
+ formatters = Array(formatter)
16
+ runner = Runner.new
17
+ runner.run([::File.open(file_name, "r")], formatters)
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ module Tengu
2
+ class Allow
3
+ def initialize(runner, object)
4
+ @runner = runner
5
+ @object = object
6
+ end
7
+
8
+ def to(receiver)
9
+ receiver.setup_allow(@runner, @object)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,57 @@
1
+ module Tengu
2
+ class BaseFormatter
3
+ def initialize(out = $stdout)
4
+ @out = out
5
+ @failures = []
6
+ end
7
+
8
+ def notify(event, object = nil)
9
+ case event
10
+ when :started then started(object)
11
+ when :pending then out.print "P"
12
+ when :success then out.print "."
13
+ when :failure then
14
+ @failures << object
15
+ out.print "F"
16
+ when :finished then finished(object)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :out
23
+
24
+ def started(runner)
25
+ @started = Time.now
26
+ end
27
+
28
+ def finished(result)
29
+ out.puts
30
+ out.puts "Finished in %0.5f seconds" % [Time.now - @started]
31
+ out.puts "#{display(result.total_count, "example")}, #{display(result.failure_count, "failure")}"
32
+ if @failures.count > 0
33
+ puts
34
+ @failures.each do |it_block|
35
+ puts it_block.description
36
+ it_block.expectations.each do |expectation|
37
+ unless expectation.success?
38
+ puts expectation.message
39
+ end
40
+ end
41
+ end
42
+ end
43
+ if result.pending_count > 0
44
+ out.puts "#{result.pending_count} pending"
45
+ end
46
+ end
47
+
48
+ def display(count, word)
49
+ "#{count} " +
50
+ if count == 1
51
+ word
52
+ else
53
+ word + "s"
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,23 @@
1
+ module Tengu
2
+ class CompositeMatcher
3
+ def matches?(object)
4
+ object
5
+ end
6
+
7
+ def > value
8
+ Matcher.new("be greater than #{value.inspect}") { |object| object > value }
9
+ end
10
+
11
+ def >= value
12
+ Matcher.new("be greater than or equal to #{value.inspect}") { |object| object >= value }
13
+ end
14
+
15
+ def < value
16
+ Matcher.new("be less than #{value.inspect}") { |object| object < value }
17
+ end
18
+
19
+ def <= value
20
+ Matcher.new("be less than or equal to #{value.inspect}") { |object| object <= value }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,61 @@
1
+ module Tengu
2
+ class DescribeBlock
3
+ def initialize(description, block)
4
+ @description = description
5
+ @block = block
6
+ @test_cases = []
7
+ @before_hooks = []
8
+ @after_hooks = []
9
+ load_test_cases
10
+ end
11
+
12
+ def run(runner, listeners = [])
13
+ run_test_cases(runner, listeners)
14
+ end
15
+
16
+ def success_count
17
+ @test_cases.count { |test_case| test_case.success? }
18
+ end
19
+
20
+ def test_count
21
+ @test_cases.count { |test_case| !test_case.pending? }
22
+ end
23
+
24
+ def pending_count
25
+ @test_cases.count { |test_case| test_case.pending? }
26
+ end
27
+
28
+ private
29
+
30
+ def include(included_module)
31
+ singleton_class.send(:include, included_module)
32
+ end
33
+
34
+ def before(&block)
35
+ @before_hooks << block
36
+ end
37
+
38
+ def after(&block)
39
+ @after_hooks << block
40
+ end
41
+
42
+
43
+ def load_test_cases
44
+ instance_eval &@block
45
+ end
46
+
47
+ def run_test_cases(runner, listeners = [])
48
+ @test_cases.each do |test_case|
49
+ @before_hooks.each { |hook| hook.call }
50
+ test_case.run(runner, listeners)
51
+ @after_hooks.each { |hook| hook.call }
52
+ end
53
+ end
54
+
55
+ def it(description = nil, &block)
56
+ @test_cases << ItBlock.new(description, block)
57
+ end
58
+
59
+ def xit(description, &block); end
60
+ end
61
+ end
@@ -0,0 +1,22 @@
1
+ module Tengu
2
+ class Double
3
+ def initialize(identifier = nil, methods = {})
4
+ @identifier = identifier
5
+ methods.each do |message, value|
6
+ define_singleton_method message, -> (*args) { _tengu_received[message] << args; value }
7
+ end
8
+ end
9
+
10
+ def _tengu_received
11
+ @_tengu_received ||= Hash.new { |hash, key| hash[key] = [] }
12
+ end
13
+
14
+ def _tengu_received?(message, args = [])
15
+ if args.length > 0
16
+ _tengu_received[message] && _tengu_received[message].include?(args)
17
+ else
18
+ _tengu_received.keys.include?(message)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ module Tengu
2
+ class Expectation
3
+ def initialize(object)
4
+ @object = object
5
+ @success = false
6
+ @positive = true
7
+ @matcher = nil
8
+ end
9
+
10
+ def success?
11
+ @success
12
+ end
13
+
14
+ def to(matcher)
15
+ @matcher = matcher
16
+ @success = @matcher.matches?(@object)
17
+ end
18
+
19
+ def not_to(matcher)
20
+ @positive = false
21
+ @matcher = matcher
22
+ @success = !@matcher.matches?(@object)
23
+ end
24
+
25
+ def message
26
+ if @positive
27
+ "expected #{@object.inspect} to #{@matcher.description}"
28
+ else
29
+ "expected #{@object.inspect} not to #{@matcher.description}"
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/tengu/file.rb ADDED
@@ -0,0 +1,43 @@
1
+ module Tengu
2
+ class File
3
+ def initialize(io)
4
+ @io = io
5
+ @describes = []
6
+ load_tests
7
+ end
8
+
9
+ def run(runner, listeners = [])
10
+ run_tests(runner, listeners)
11
+ end
12
+
13
+ def success_count
14
+ @describes.inject(0) { |sum, n| sum += n.success_count }
15
+ end
16
+
17
+ def test_count
18
+ @describes.inject(0) { |sum, n| sum += n.test_count }
19
+ end
20
+
21
+ def pending_count
22
+ @describes.inject(0) { |sum, n| sum += n.pending_count }
23
+ end
24
+
25
+ private
26
+
27
+ def code
28
+ @code ||= @io.read
29
+ end
30
+
31
+ def load_tests
32
+ instance_eval(code)
33
+ end
34
+
35
+ def run_tests(runner, listeners= [])
36
+ @describes.each { |describe| describe.run(runner, listeners) }
37
+ end
38
+
39
+ def describe(description, &block)
40
+ @describes << DescribeBlock.new(description, block)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,77 @@
1
+ require "tengu/matchers"
2
+ require "tengu/double"
3
+ require "tengu/allow"
4
+ require "tengu/receiver"
5
+
6
+ module Tengu
7
+ class ItBlock
8
+ include Matchers
9
+ attr_reader :description, :expectations
10
+
11
+ def initialize(description, block)
12
+ @description = description
13
+ @block = block
14
+ @success = true
15
+ @pending = false
16
+ @expectations = []
17
+ end
18
+
19
+ def run(runner, listeners = [])
20
+ @runner = runner
21
+ instance_eval(&@block)
22
+ @runner.reset_overrides
23
+ notify(listeners)
24
+ end
25
+
26
+ def success?
27
+ unless pending?
28
+ @expectations.all? { |expectation| expectation.success? }
29
+ end
30
+ end
31
+
32
+ def pending?
33
+ @pending
34
+ end
35
+
36
+ private
37
+
38
+ def allow(object)
39
+ Allow.new(@runner, object)
40
+ end
41
+
42
+ def receive(message)
43
+ Receiver.new(message)
44
+ end
45
+
46
+ def double(identifier = nil, args = {})
47
+ Double.new(identifier, args)
48
+ end
49
+
50
+ def notify(listeners)
51
+ listeners.each do |listener|
52
+ listener.notify(success_state, self)
53
+ end
54
+ end
55
+
56
+ def success_state
57
+ if pending?
58
+ :pending
59
+ elsif success?
60
+ :success
61
+ else
62
+ :failure
63
+ end
64
+ end
65
+
66
+ def pending
67
+ @success = false
68
+ @pending = true
69
+ end
70
+
71
+ def expect(object)
72
+ expectation = Expectation.new(object)
73
+ @expectations << expectation
74
+ expectation
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,13 @@
1
+ module Tengu
2
+ class Matcher
3
+ attr_reader :description
4
+ def initialize(description, &block)
5
+ @description = description
6
+ @block = block
7
+ end
8
+
9
+ def matches?(object)
10
+ @block.call(object)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,57 @@
1
+ require "tengu/receive_matcher"
2
+
3
+ module Tengu
4
+ module Matchers
5
+ def be_true
6
+ eq(true)
7
+ end
8
+
9
+ def be_false
10
+ eq(false)
11
+ end
12
+
13
+ def be_nil
14
+ eq(nil)
15
+ end
16
+
17
+ def have_received(message)
18
+ ReceiveMatcher.new(message, "have received #{message.inspect}") { |object| object._tengu_received?(message) }
19
+ end
20
+
21
+ def include(value)
22
+ Matcher.new("include #{value.inspect}") { |object| object.include?(value) }
23
+ end
24
+
25
+ def eq(value)
26
+ Matcher.new("be eq to #{value.inspect}") { |object| object == value }
27
+ end
28
+
29
+ def eql(value)
30
+ Matcher.new("be eql to #{value.inspect}") { |object| object.eql?(value) }
31
+ end
32
+
33
+ def equal(value)
34
+ Matcher.new("be equal to #{value.inspect}") { |object| object.equal?(value) }
35
+ end
36
+
37
+ def be(value = nil)
38
+ if value
39
+ equal(value)
40
+ else
41
+ CompositeMatcher.new
42
+ end
43
+ end
44
+
45
+ def be_instance_of(value)
46
+ Matcher.new("be instance of #{value.inspect}") { |object| object.instance_of?(value) }
47
+ end
48
+
49
+ def be_kind_of(value)
50
+ Matcher.new("be kind of #{value.inspect}") { |object| object.kind_of?(value) }
51
+ end
52
+
53
+ def match(value)
54
+ Matcher.new("match #{value.inspect}") { |object| object =~ value }
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,19 @@
1
+ require "rake"
2
+ require "rake/tasklib"
3
+ require "tengu"
4
+
5
+ module Tengu
6
+ class RakeTask < ::Rake::TaskLib
7
+ include ::Rake::DSL if defined?(::Rake::DSL)
8
+
9
+ def initialize(name = :spec)
10
+ desc "Run tengu tests"
11
+ task name do |_, task_args|
12
+ files = Dir.glob("spec/**/*_spec.rb").map { |filename| ::File.open(filename, "r") }
13
+ formatter = Tengu::BaseFormatter.new
14
+ runner = Tengu::Runner.new
15
+ runner.run(files, [formatter])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require "tengu/matcher"
2
+
3
+ module Tengu
4
+ class ReceiveMatcher < Matcher
5
+ def initialize(method_message, message, &block)
6
+ @method_message = method_message
7
+ @message = message
8
+ @with = nil
9
+ super(message, &block)
10
+ end
11
+
12
+ def with(*args)
13
+ method_message = @method_message
14
+ @block = -> (object) { object._tengu_received?(method_message, args) }
15
+ self
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,53 @@
1
+ require 'pry'
2
+
3
+ module Tengu
4
+ class Receiver
5
+ def initialize(message)
6
+ @message = message
7
+ @args = nil
8
+ @return = nil
9
+ end
10
+
11
+ def with(*args)
12
+ @args = args
13
+ self
14
+ end
15
+
16
+ def and_return(return_value)
17
+ @return = return_value
18
+ self
19
+ end
20
+
21
+ def setup_allow(runner, object)
22
+ unless object.respond_to?(:_tengu_received?)
23
+ object.instance_eval do
24
+ define_singleton_method(:_tengu_received) do
25
+ @_tengu_received ||= Hash.new { |hash, key| hash[key] = [] }
26
+ end
27
+
28
+ define_singleton_method(:_tengu_received?) do |message, args = []|
29
+ if args.length > 0
30
+ _tengu_received[message] && _tengu_received[message].include?(args)
31
+ else
32
+ _tengu_received.keys.include?(message)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ message = @message
39
+ return_value = @return
40
+ if object.is_a? Tengu::Double
41
+ object.instance_eval do
42
+ define_singleton_method message, -> (*args) { _tengu_received[message] << args; return_value }
43
+ end
44
+ else
45
+ original_method = object.method(@message.to_sym)
46
+ runner.record_override(object, original_method)
47
+ object.instance_eval do
48
+ define_singleton_method message, -> (*args) { _tengu_received[message] << args; return_value }
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,16 @@
1
+ module Tengu
2
+ class Result
3
+ attr_reader :success_count, :total_count, :pending_count
4
+
5
+ def initialize(files)
6
+ @files = files
7
+ @success_count = @files.inject(0) { |sum, n| sum += n.success_count }
8
+ @total_count = @files.inject(0) { |sum, n| sum += n.test_count }
9
+ @pending_count = @files.inject(0) { |sum, n| sum += n.pending_count }
10
+ end
11
+
12
+ def failure_count
13
+ total_count - success_count
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ module Tengu
2
+ class Runner
3
+ def initialize(options = {})
4
+ @options = options
5
+ @overrides = []
6
+ end
7
+
8
+ def record_override(object, method)
9
+ @overrides << [object, method]
10
+ end
11
+
12
+ def reset_overrides
13
+ @overrides.reverse.each do |object, method|
14
+ object.instance_eval do
15
+ define_singleton_method method.name, method
16
+ end
17
+ end
18
+ end
19
+
20
+ def run(ios, formatters = [])
21
+ @files = ios.map { |io| Tengu::File.new(io) }
22
+ formatters.each { |formatter| formatter.notify(:started, self) }
23
+ @files.each { |file| file.run(self, formatters) }
24
+ result = Result.new(@files)
25
+ formatters.each { |formatter| formatter.notify(:finished, result) }
26
+ result
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module Tengu
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,12 @@
1
+ describe Tengu::Allow do
2
+ include Tengu
3
+
4
+ it "sets up the receiver" do
5
+ runner = double
6
+ object = double
7
+ receiver = double
8
+ allow(receiver).to receive(:setup_allow).with(runner, object).and_return("expected")
9
+ tengu_allow = Allow.new(runner, object)
10
+ expect(tengu_allow.to(receiver)).to eq("expected")
11
+ end
12
+ end
@@ -0,0 +1,62 @@
1
+ require "tengu"
2
+ require "stringio"
3
+
4
+ describe "BaseFormatter" do
5
+ it "prints . when notified of success" do
6
+ output = StringIO.new
7
+ formatter = Tengu::BaseFormatter.new(output)
8
+ formatter.notify(:success)
9
+ output.rewind
10
+ expect(output.read).to eq(".")
11
+ end
12
+
13
+ it "prints F when notified of failure" do
14
+ output = StringIO.new
15
+ formatter = Tengu::BaseFormatter.new(output)
16
+ formatter.notify(:failure)
17
+ output.rewind
18
+ expect(output.read).to eq("F")
19
+ end
20
+
21
+ it "prints P when notified of pending" do
22
+ output = StringIO.new
23
+ formatter = Tengu::BaseFormatter.new(output)
24
+ formatter.notify(:pending)
25
+ output.rewind
26
+ expect(output.read).to eq("P")
27
+ end
28
+
29
+ it "tracks the time" do
30
+ output = StringIO.new
31
+ formatter = Tengu::BaseFormatter.new(output)
32
+ allow(Time).to receive(:now).and_return(10)
33
+ formatter.notify(:started, nil)
34
+ allow(Time).to receive(:now).and_return(31)
35
+ result = OpenStruct.new(total_count: 0, failure_count: 0, pending_count: 0)
36
+ formatter.notify(:finished, result)
37
+ output.rewind
38
+ expect(output.read).to match(/Finished in 21.00000 seconds/)
39
+ end
40
+
41
+ it "tracks the example count" do
42
+ allow(Time).to receive(:now).and_return(10)
43
+ output = StringIO.new
44
+ formatter = Tengu::BaseFormatter.new(output)
45
+ formatter.notify(:started, nil)
46
+ result = OpenStruct.new(total_count: 5, failure_count: 0, pending_count: 0)
47
+ formatter.notify(:finished, result)
48
+ output.rewind
49
+ expect(output.read).to match(/5 examples/)
50
+ end
51
+
52
+ it "tracks the failure count" do
53
+ allow(Time).to receive(:now).and_return(10)
54
+ output = StringIO.new
55
+ formatter = Tengu::BaseFormatter.new(output)
56
+ formatter.notify(:started, nil)
57
+ result = OpenStruct.new(total_count: 0, failure_count: 3, pending_count: 0)
58
+ formatter.notify(:finished, result)
59
+ output.rewind
60
+ expect(output.read).to match(/3 failures/)
61
+ end
62
+ end
@@ -0,0 +1,29 @@
1
+ describe Tengu::CompositeMatcher do
2
+ include Tengu
3
+
4
+ it "will check existance" do
5
+ expect(CompositeMatcher.new.matches?("wombat")).to be
6
+ end
7
+
8
+ it "will check >" do
9
+ expect(5).to be > 4
10
+ expect(3).not_to be > 4
11
+ end
12
+
13
+ it "will check >=" do
14
+ expect(5).to be >= 4
15
+ expect(5).to be >= 5
16
+ expect(5).not_to be >= 6
17
+ end
18
+
19
+ it "will check <" do
20
+ expect(5).to be < 6
21
+ expect(6).not_to be < 6
22
+ end
23
+
24
+ it "will check <=" do
25
+ expect(5).to be <= 6
26
+ expect(6).to be <= 6
27
+ expect(7).not_to be <= 6
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ require "tengu"
2
+
3
+ describe Tengu::DescribeBlock do
4
+ include Tengu
5
+
6
+ it "evaluates the code passed in" do
7
+ test = "foo"
8
+ code = -> (wombat) { test = wombat }
9
+ block = DescribeBlock.new("test", code)
10
+ expect(test).to eq block
11
+ end
12
+
13
+ it "will include modules" do
14
+ marsupial = Module.new
15
+ code = -> (wombat) { include marsupial }
16
+ wombat = DescribeBlock.new("test", code)
17
+ expect(wombat).to be_kind_of marsupial
18
+ end
19
+
20
+ it "runs before_hooks" do
21
+ expected = -> {}
22
+ allow(expected).to receive(:call)
23
+ allow(ItBlock).to receive(:new).and_return(double(ItBlock, run: true))
24
+ code = -> (wombat) { before &expected; it {} }
25
+ DescribeBlock.new("test", code).run(nil, [])
26
+ expect(expected).to have_received(:call)
27
+ end
28
+
29
+ it "runs after_hooks" do
30
+ expected = -> {}
31
+ allow(expected).to receive(:call)
32
+ allow(ItBlock).to receive(:new).and_return(double(ItBlock, run: true))
33
+ code = -> (wombat) { after &expected; it {} }
34
+ DescribeBlock.new("test", code).run(nil, [])
35
+ expect(expected).to have_received(:call)
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ describe Tengu::Double do
2
+ include Tengu
3
+ it "creates methods when passed in" do
4
+ test_double = Double.new("test", animal: "wombat")
5
+ expect(test_double.animal).to eq "wombat"
6
+ end
7
+ end
@@ -0,0 +1,43 @@
1
+ describe Tengu::Expectation do
2
+ include Tengu
3
+
4
+ it "sets success to true on postive match" do
5
+ expectation = Expectation.new("wombat")
6
+ matcher = double(Matcher, matches?: true)
7
+ expectation.to(matcher)
8
+ expect(expectation.success?).to be_true
9
+ end
10
+
11
+ it "sets success to false on postive mismatch" do
12
+ expectation = Expectation.new("wombat")
13
+ matcher = double(Matcher, matches?: false)
14
+ expectation.to(matcher)
15
+ expect(expectation.success?).to be_false
16
+ end
17
+
18
+ it "sets success to true on negative mismatch" do
19
+ expectation = Expectation.new("wombat")
20
+ matcher = double(Matcher, matches?: false)
21
+ expectation.not_to(matcher)
22
+ expect(expectation.success?).to be_true
23
+ end
24
+
25
+ it "sets success to false on negative match" do
26
+ expectation = Expectation.new("wombat")
27
+ matcher = double(Matcher, matches?: true)
28
+ expectation.not_to(matcher)
29
+ expect(expectation.success?).to be_false
30
+ end
31
+
32
+ it "returns a formatted positive message" do
33
+ expectation = Expectation.new("wombat")
34
+ expectation.to(double(Matcher, matches?: true, description: "win"))
35
+ expect(expectation.message).to eq 'expected "wombat" to win'
36
+ end
37
+
38
+ it "returns a formatted negative message" do
39
+ expectation = Expectation.new("numbat")
40
+ expectation.not_to(double(Matcher, matches?: true, description: "win"))
41
+ expect(expectation.message).to eq 'expected "numbat" not to win'
42
+ end
43
+ end
data/spec/file_spec.rb ADDED
@@ -0,0 +1,39 @@
1
+ require 'pry'
2
+
3
+ describe Tengu::File do
4
+ include Tengu
5
+
6
+ it "reads the tests" do
7
+ code = double(File, read: "describe('test') {}")
8
+ file = File.new(code)
9
+ expect(code).to have_received(:read)
10
+ end
11
+
12
+ it "runs the tests" do
13
+ describe_block = double(DescribeBlock, run: true)
14
+ allow(DescribeBlock).to receive(:new).and_return(describe_block)
15
+ code = double(File, read: "describe('test') {}")
16
+ file = File.new(code)
17
+ runner = double
18
+ file.run(runner)
19
+ expect(describe_block).to have_received(:run).with(runner, [])
20
+ end
21
+
22
+ it "returns the success count" do
23
+ describe_block = double(DescribeBlock, run: true, success_count: 5)
24
+ allow(DescribeBlock).to receive(:new).and_return(describe_block)
25
+ code = double(File, read: "describe('test') {}")
26
+ file = File.new(code)
27
+ file.run(double)
28
+ expect(file.success_count).to eq 5
29
+ end
30
+
31
+ it "returns the test count" do
32
+ describe_block = double(DescribeBlock, run: true, test_count: 7)
33
+ allow(DescribeBlock).to receive(:new).and_return(describe_block)
34
+ code = double(File, read: "describe('test') {}")
35
+ file = File.new(code)
36
+ file.run(double)
37
+ expect(file.test_count).to eq 7
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ $foo = "bar"
2
+
3
+ describe "True" do
4
+ before do
5
+ $foo = "baz"
6
+ end
7
+
8
+ it "is true" do
9
+ expect($foo).to eq("baz")
10
+ end
11
+
12
+ it "includes pending" do
13
+ pending
14
+ end
15
+
16
+ xit "skips others" do
17
+ expect($foo).to eq("bar")
18
+ end
19
+
20
+ after do
21
+ $foo = "bar"
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ describe Tengu::ItBlock do
2
+ it "runs the tests" do
3
+ pending
4
+ end
5
+
6
+ it "resets the overrides" do
7
+ pending
8
+ end
9
+
10
+ it "notifies the listeners" do
11
+ pending
12
+ end
13
+
14
+ it "returns success" do
15
+ pending
16
+ end
17
+
18
+ it "returns pending" do
19
+ pending
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ describe Tengu::Matcher do
2
+ include Tengu
3
+
4
+ it "checks for matches" do
5
+ pending
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ describe Tengu::ReceiveMatcher do
2
+ include Tengu
3
+
4
+ it "checks for arguments" do
5
+ pending
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ describe Tengu::Receiver do
2
+ it "specified which arguments are allowed" do
3
+ pending
4
+ end
5
+
6
+ it "sets the return value" do
7
+ pending
8
+ end
9
+
10
+ it "sets up the original object" do
11
+ pending
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ describe Tengu::Result do
2
+ include Tengu
3
+
4
+ it "determines the success count" do
5
+ pending
6
+ end
7
+
8
+ it "determines the total count" do
9
+ pending
10
+ end
11
+
12
+ it "determines the pending count" do
13
+ pending
14
+ end
15
+
16
+ it "determines the failure count" do
17
+ pending
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ describe Tengu::Runner do
2
+ include Tengu
3
+
4
+ it "records the overrides" do
5
+ pending
6
+ end
7
+
8
+ it "resets the overrides" do
9
+ pending
10
+ end
11
+
12
+ it "notifies the listeners" do
13
+ pending
14
+ end
15
+
16
+ it "runs the files" do
17
+ pending
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ require "tengu"
2
+
3
+ describe "Tengu" do
4
+ it "will .test a particular file" do
5
+ file_path = "test"
6
+ fake_file = double(::File)
7
+ fake_runner = double(Tengu::Runner)
8
+ allow(::File).to receive(:open).with(file_path, "r").and_return(fake_file)
9
+ allow(Tengu::Runner).to receive(:new).and_return(fake_runner)
10
+ allow(fake_runner).to receive(:run).with([fake_file], []).and_return("expected")
11
+ expect(Tengu.test(file_path)).to eq("expected")
12
+ end
13
+ end
data/tengu.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tengu/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tengu"
8
+ spec.version = Tengu::VERSION
9
+ spec.authors = ["halogenandtoast"]
10
+ spec.email = ["halogenandtoast@gmail.com"]
11
+ spec.description = %q{A truly object oriented testing library}
12
+ spec.summary = %q{A truly object oriented testing library}
13
+ spec.homepage = "http://github.com/halogenandtoast/tengu"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "pry"
25
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tengu
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - halogenandtoast
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A truly object oriented testing library
70
+ email:
71
+ - halogenandtoast@gmail.com
72
+ executables:
73
+ - tengu
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/tengu
83
+ - lib/tengu.rb
84
+ - lib/tengu/allow.rb
85
+ - lib/tengu/base_formatter.rb
86
+ - lib/tengu/composite_matcher.rb
87
+ - lib/tengu/describe_block.rb
88
+ - lib/tengu/double.rb
89
+ - lib/tengu/expectation.rb
90
+ - lib/tengu/file.rb
91
+ - lib/tengu/it_block.rb
92
+ - lib/tengu/matcher.rb
93
+ - lib/tengu/matchers.rb
94
+ - lib/tengu/rake_task.rb
95
+ - lib/tengu/receive_matcher.rb
96
+ - lib/tengu/receiver.rb
97
+ - lib/tengu/result.rb
98
+ - lib/tengu/runner.rb
99
+ - lib/tengu/version.rb
100
+ - spec/allow_spec.rb
101
+ - spec/base_formatter_spec.rb
102
+ - spec/composite_matcher_spec.rb
103
+ - spec/describe_block_spec.rb
104
+ - spec/double_spec.rb
105
+ - spec/expectation_spec.rb
106
+ - spec/file_spec.rb
107
+ - spec/fixtures/example.rb
108
+ - spec/it_block_spec.rb
109
+ - spec/matcher_spec.rb
110
+ - spec/receive_matcher_spec.rb
111
+ - spec/receiver_spec.rb
112
+ - spec/result_spec.rb
113
+ - spec/runner_spec.rb
114
+ - spec/tengu_spec.rb
115
+ - tengu.gemspec
116
+ homepage: http://github.com/halogenandtoast/tengu
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.0.3
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: A truly object oriented testing library
140
+ test_files:
141
+ - spec/allow_spec.rb
142
+ - spec/base_formatter_spec.rb
143
+ - spec/composite_matcher_spec.rb
144
+ - spec/describe_block_spec.rb
145
+ - spec/double_spec.rb
146
+ - spec/expectation_spec.rb
147
+ - spec/file_spec.rb
148
+ - spec/fixtures/example.rb
149
+ - spec/it_block_spec.rb
150
+ - spec/matcher_spec.rb
151
+ - spec/receive_matcher_spec.rb
152
+ - spec/receiver_spec.rb
153
+ - spec/result_spec.rb
154
+ - spec/runner_spec.rb
155
+ - spec/tengu_spec.rb
156
+ has_rdoc: