thumblemonks-protest 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 Justin Knowlden, Gabriel Gironda, Dan Hodos, Thumble Monks
1
+ Copyright (c) 2008 Justin Knowlden, Thumble Monks
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.markdown CHANGED
@@ -1,12 +1,12 @@
1
1
  # Protest
2
2
 
3
- An extremely fast, expressive, and context-driven unit-testing framework.
3
+ An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.
4
4
 
5
5
  #### Example: Basic booleans
6
6
 
7
7
  **NOTE:** For no specific reason, I'm going to use an ActiveRecord model in the following examples.
8
8
 
9
- At it's very basic, Protest simply tries to assert that an expression is true or false. Protest does this through its `asserts` and `denies` tests. An `asserts` test will pass if the result of running the test is neither `nil` or `false`. A `denies` test confirms just the opposite.
9
+ At it's very basic, Protest simply tries to assert that an expression is true or false. Protest does this through its `asserts` or `should` tests. An `asserts` test will pass if the result of running the test is neither `nil` or `false`. A `should` test does the exact same thing - they are in fact aliases. The only difference is in the way you write the assertion.
10
10
 
11
11
  For instance, given a test file named `foo_test.rb`, you might have the following code in it:
12
12
 
@@ -15,10 +15,20 @@ For instance, given a test file named `foo_test.rb`, you might have the followin
15
15
  context "a new user" do
16
16
  setup { @user = User.new }
17
17
  asserts("that it is not yet created") { @user.new_record? }
18
- denies("that it is valid") { @user.valid? }
19
18
  end
20
19
 
21
- Notice that you do not define a class anywhere. That would be the entire contents of that test file.
20
+ Notice that you do not define a class anywhere. That would be the entire contents of that test file. If you wanted to use a `should` instead, you could say this:
21
+
22
+ require 'protest'
23
+
24
+ context "a new user" do
25
+ setup { @user = User.new }
26
+ should("not be created") { @user.new_record? }
27
+ end
28
+
29
+ Sometimes it's more clear to say "this **should** be that" and sometimes it's better to say "**asserts** this is that". I promise you that Protest will get no more redundant than this, but also that besides speed, Protest will aim at being expressive with a minimal amount of syntax.
30
+
31
+ I'm going to use `asserts` for the rest of this introduction, but you should know that you can replace any instance of `asserts` with `should` and nothing would change.
22
32
 
23
33
  #### Example: Equality
24
34
 
@@ -275,7 +285,6 @@ TONS OF STUFF
275
285
  1. Refactor reporting; some abstracting is needed for recording a result (for instance)
276
286
  1. Need to know where in backtrace a test failed (line number, etc.)
277
287
  1. More assertion macros: throws, etc.
278
- 1. Handle denies macro different, so that an entire failure message can translated to the 'negative' assertion. I don't want to add deny\_this and deny\_that macros
279
288
  1. Aliases for context "with, without, when, ..."; add those words to test description
280
289
  1. Optimization and simplification (ex. flog is complaining print\_result\_stack)
281
290
  1. Better error messages (maybe need to rename asserts to should for better readability)
data/Rakefile CHANGED
@@ -10,7 +10,12 @@ task :test do
10
10
  Protest.report
11
11
  end
12
12
 
13
- desc "Run flog against library (except tests)"
13
+ desc "Run Flog against library (except tests)"
14
14
  task :flog do
15
15
  puts %x[find ./lib -name *.rb | xargs flog]
16
16
  end
17
+
18
+ desc "Run Roodi against library (except tests)"
19
+ task :roodi do
20
+ puts %x[find ./lib -name *.rb | xargs roodi]
21
+ end
@@ -1,9 +1,9 @@
1
1
  module Protest
2
2
 
3
3
  class Assertion
4
- attr_reader :raised
4
+ attr_reader :raised, :to_s
5
5
  def initialize(description, target, &block)
6
- @description = description
6
+ @description = @to_s = description
7
7
  actualize(target, &block)
8
8
  end
9
9
 
@@ -26,35 +26,12 @@ module Protest
26
26
  def error?; !failure? && raised; end
27
27
  def passed?; !failure? && !error?; end
28
28
  def result; @failure || error; end
29
- def to_s; @description; end
30
29
  private
31
30
  def actualize(target, &block)
32
31
  @actual = target.instance_eval(&block)
33
- @default_failure = base_assertion
32
+ @default_failure = failure("expected true, not #{@actual.inspect}") unless @actual
34
33
  rescue Exception => e
35
34
  @raised = e
36
35
  end
37
-
38
- def base_assertion
39
- failure("expected true, not #{@actual.inspect}") unless @actual
40
- end
41
36
  end # Assertion
42
-
43
- # Denial will evaulate to true if the assertion failed in some way. Errors pass through. A Failure
44
- # is generated if the assertion actually passed.
45
- class Denial < Assertion
46
- def actual
47
- @actual # Do not forget default failure unless a failure is thrown
48
- end
49
-
50
- alias :actual_failure :failure
51
- def failure(message)
52
- @default_failure = @failure = nil # this is a good thing
53
- end
54
- private
55
- def base_assertion
56
- actual_failure("expected assertion to fail") if @actual
57
- end
58
- end # Denial
59
-
60
37
  end # Protest
@@ -23,8 +23,8 @@ module Protest
23
23
  def to_s; @to_s ||= [@parent.to_s, @description].join(' ').strip; end
24
24
 
25
25
  def context(description, &block) Protest.context(description, @reporter, self, &block); end
26
- def asserts(description, &block) new_assertion(Assertion, description, &block); end
27
- def denies(description, &block) new_assertion(Denial, description, &block); end
26
+ def asserts(description, &block) new_assertion("asserts #{description}", &block); end
27
+ def should(description, &block) new_assertion("should #{description}", &block); end
28
28
 
29
29
  def report
30
30
  assertions.each do |assertion|
@@ -38,8 +38,8 @@ module Protest
38
38
  end
39
39
  end
40
40
  private
41
- def new_assertion(klass, description, &block)
42
- (assertions << klass.new(description, self, &block)).last
41
+ def new_assertion(description, &block)
42
+ (assertions << Assertion.new(description, self, &block)).last
43
43
  end
44
44
  end # Context
45
45
  end # Protest
@@ -2,18 +2,21 @@ module Protest
2
2
  module AssertionMacros
3
3
  # Asserts that the result of the test equals the expected value
4
4
  # asserts("test") { "foo" }.equals("foo")
5
+ # should("test") { "foo" }.equals("foo")
5
6
  def equals(expected)
6
7
  expected == actual || failure("expected #{expected.inspect}, not #{actual.inspect}")
7
8
  end
8
9
 
9
10
  # Asserts that the result of the test is nil
10
11
  # asserts("test") { nil }.nil
12
+ # should("test") { nil }.nil
11
13
  def nil
12
14
  actual.nil? || failure("expected nil, not #{actual.inspect}")
13
15
  end
14
16
 
15
17
  # Asserts that the test raises the expected Exception
16
18
  # asserts("test") { raise My::Exception }.raises(My::Exception)
19
+ # should("test") { raise My::Exception }.raises(My::Exception)
17
20
  def raises(expected)
18
21
  failure("should have raised #{expected}, but raised nothing") unless raised
19
22
  failure("should have raised #{expected}, not #{error.class}") unless expected == raised.class
@@ -22,6 +25,7 @@ module Protest
22
25
 
23
26
  # Asserts that the result of the test equals matches against the proved expression
24
27
  # asserts("test") { "12345" }.matches(/\d+/)
28
+ # should("test") { "12345" }.matches(/\d+/)
25
29
  def matches(expected)
26
30
  expected = %r[#{Regexp.escape(expected)}] if expected.kind_of?(String)
27
31
  actual =~ expected || failure("expected #{expected.inspect} to match #{actual.inspect}")
@@ -29,6 +33,7 @@ module Protest
29
33
 
30
34
  # Asserts that the result of the test is an object that is a kind of the expected type
31
35
  # asserts("test") { "foo" }.kind_of(String)
36
+ # should("test") { "foo" }.kind_of(String)
32
37
  def kind_of(expected)
33
38
  actual.kind_of?(expected) || failure("expected kind of #{expected}, not #{actual.inspect}")
34
39
  end
@@ -59,13 +59,14 @@ module Protest
59
59
  def print_result_stack
60
60
  bad_results.each_with_index do |result, idx|
61
61
  @writer.puts render_result(idx + 1, result)
62
- @writer.puts " " + result.backtrace.join("\n ") + "\n\n"
62
+ @writer.puts " " + result.backtrace.join("\n ") if result.print_stacktrace?
63
+ @writer.puts "\n\n"
63
64
  end
64
65
  end
65
66
 
66
67
  def render_result(idx, result)
67
68
  format_args = [idx, result.context.to_s, result.assertion.to_s, result.to_s]
68
- "#%d - %s asserts %s: %s" % format_args
69
+ "#%d - %s %s: %s" % format_args
69
70
  end
70
71
  end # TextReport
71
72
 
data/lib/protest.rb CHANGED
@@ -42,16 +42,20 @@ module Protest
42
42
  super(message)
43
43
  @assertion = assertion
44
44
  end
45
+
45
46
  def contextualize(ctx)
46
47
  @context = ctx
47
48
  self
48
49
  end
50
+
51
+ def print_stacktrace?; false; end
49
52
  end
50
53
  class Error < Failure
51
54
  def initialize(message, assertion, error)
52
55
  super(message, assertion)
53
56
  set_backtrace(error.backtrace)
54
57
  end
58
+ def print_stacktrace?; true; end
55
59
  end
56
60
  end # Protest
57
61
 
data/protest.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "protest"
3
- s.version = "0.0.6"
4
- s.date = "2009-07-05"
3
+ s.version = "0.0.7"
4
+ s.date = "2009-08-12"
5
5
  s.summary = "An extremely fast, expressive, and context-driven unit-testing framework"
6
6
  s.email = %w[gus@gusg.us]
7
7
  s.homepage = "http://github.com/thumblemonks/protest"
@@ -1,79 +1,66 @@
1
1
  require 'protest'
2
2
 
3
- fake_context = Object.new
3
+ fake_context = Object.new # It works ... so, why not?
4
4
 
5
5
  context "basic assertion:" do
6
- asserts("its description") do
6
+ should "have a description" do
7
7
  Protest::Assertion.new("i will pass", fake_context).to_s
8
8
  end.equals("i will pass")
9
9
 
10
- asserts("passed? if assertion returns true") do
10
+ asserts "pass? is true when assertion passed" do
11
11
  Protest::Assertion.new("i will pass", fake_context) { true }.passed?
12
12
  end
13
13
 
14
- asserts("failure? when assertion does not pass") do
14
+ asserts "failure? is true when assertion does not pass" do
15
15
  Protest::Assertion.new("i will pass", fake_context) { false }.failure?
16
16
  end
17
17
 
18
- asserts("error? when an unexpected Exception is raised") do
18
+ asserts "error? is true when an unexpected Exception is raised" do
19
19
  Protest::Assertion.new("error", fake_context) { raise Exception, "blah" }.error?
20
20
  end
21
21
  end
22
22
 
23
- context "basic denial:" do
24
- asserts("false assertion passes") do
25
- Protest::Denial.new("i will pass", fake_context) { false }.passed?
26
- end
27
-
28
- asserts("true assertion fails") do
29
- Protest::Denial.new("i will not pass", fake_context) { true }.failure?
30
- end
31
- end # basic assertion
32
-
33
23
  context "equals assertion:" do
34
- asserts("results equals expectation") do
24
+ asserts "result equals expectation" do
35
25
  Protest::Assertion.new("i will pass", fake_context) { "foo bar" }.equals("foo bar")
36
26
  end
37
27
 
38
- asserts("a Failure if results don't equal eachother") do
28
+ should "raise a Failure if results don't equal each other" do
39
29
  Protest::Assertion.new("failure", fake_context) { "bar" }.equals("foo")
40
30
  end.kind_of(Protest::Failure)
41
-
42
- asserts("a non-matching string is a good thing when in denial") do
43
- Protest::Denial.new("pass", fake_context) { "bar" }.equals("foo")
44
- end.nil
45
31
  end # equals assertion
46
32
 
47
33
  context "nil assertion:" do
48
- asserts("actual result is nil") { Protest::Assertion.new("foo", fake_context) { nil }.nil }
49
- asserts("a Failure if not nil") do
34
+ asserts("result is nil") { Protest::Assertion.new("foo", fake_context) { nil }.nil }
35
+ should "raise a Failure if not nil" do
50
36
  Protest::Assertion.new("foo", fake_context) { "a" }.nil
51
37
  end.kind_of(Protest::Failure)
52
38
  end # nil assertion
53
39
 
54
40
  context "raises assertion:" do
55
- asserts("an Exception is raised") { raise Exception }.raises(Exception)
56
- end # maching assertion
41
+ should("raise an Exception") { raise Exception }.raises(Exception)
42
+ end # raises assertion
57
43
 
58
44
  context "matching assertion:" do
59
- asserts("actual result matches expression") do
45
+ asserts "result matches expression" do
60
46
  Protest::Assertion.new("foo", fake_context) { "a" }.matches(%r[.])
61
47
  end.equals(0)
62
48
 
63
- asserts("a Failure if not nil") do
49
+ should "raise a Failure if result does not match" do
64
50
  Protest::Assertion.new("foo", fake_context) { "" }.matches(%r[.])
65
51
  end.kind_of(Protest::Failure)
66
52
 
67
- asserts("string matches string") do
53
+ should "return the result of a matching operation" do
68
54
  Protest::Assertion.new("foo", fake_context) { "a" }.matches("a")
69
55
  end.equals(0)
70
56
  end # maching assertion
71
57
 
72
58
  context "kind_of assertion:" do
73
- asserts("result is kind of String") do
59
+ asserts "specific result is a kind of String" do
74
60
  Protest::Assertion.new("foo", fake_context) { "a" }.kind_of(String)
75
61
  end
76
- asserts("a Failure if not a kind of String") do
62
+
63
+ should "raise a Failure if not a kind of String" do
77
64
  Protest::Assertion.new("foo", fake_context) { 0 }.kind_of(String)
78
65
  end.kind_of(Protest::Failure)
79
66
  end # kind_of assertion
data/test/context_test.rb CHANGED
@@ -11,41 +11,35 @@ context "any context" do
11
11
 
12
12
  context "that doesn't have passing tests" do
13
13
  setup do
14
- @context.asserts("a") { true }
15
- @context.asserts("b") { false }
16
- @context.asserts("c") { raise Exception, "blah" }
14
+ @context.should("a") { true }
15
+ @context.should("b") { false }
16
+ @context.should("c") { raise Exception, "blah" }
17
17
  end
18
18
 
19
- asserts("that passes are disctinct") { @reporter.passes }.equals(1)
20
- asserts("that failures are captured") { @reporter.failures }.equals(1)
21
- asserts("that unexpected errors are captured") { @reporter.errors }.equals(1)
19
+ asserts("passed test count") { @reporter.passes }.equals(1)
20
+ asserts("failure count") { @reporter.failures }.equals(1)
21
+ asserts("unexpected errors count") { @reporter.errors }.equals(1)
22
22
  end # that doesn't have passing tests
23
23
  end # any context
24
24
 
25
- context "when denying things" do
26
- denies("true is false") { false }
27
- denies("bar equals foo") { "bar" }.equals("foo")
28
- denies("bar matches only digits") { "bar" }.matches(/^\d+$/)
29
- end
30
-
31
25
  #
32
26
  # Test Context
33
27
 
34
28
  test_context = context("foo", Protest::NilReport.new) do
35
29
  setup { @test_counter = 0 }
36
- asserts("a block returns true") { @test_counter += 1; true }
37
- asserts("another block returns true") { @test_counter += 1; true }
30
+ asserts("truthiness") { @test_counter += 1; true }
31
+ asserts("more truthiness") { @test_counter += 1; true }
38
32
  end # A CONTEXT THAT IS DEQUEUED
39
33
 
40
34
  context "test context" do
41
35
  setup { Protest.dequeue_context(test_context) }
42
- asserts("context description") { test_context.to_s }.equals("foo")
43
- asserts("assertion count") { test_context.assertions.length }.equals(2)
36
+ should("confirm context description") { test_context.to_s }.equals("foo")
37
+ should("confirm assertion count") { test_context.assertions.length }.equals(2)
44
38
 
45
- asserts("setup runs only once") do
39
+ should("call setup once") do
46
40
  test_context.instance_variable_get(:@test_counter)
47
41
  end.equals(2)
48
- end
42
+ end # test context
49
43
 
50
44
  #
51
45
  # Nested Context
@@ -56,7 +50,7 @@ nested_context = context("foo", Protest::NilReport.new) do
56
50
  @test_counter = 0
57
51
  @foo = "bar"
58
52
  end
59
- asserts("a block returns true") { @test_counter += 1; true }
53
+ asserts("truthiness") { @test_counter += 1; true }
60
54
 
61
55
  inner_nested_context = context("baz") do
62
56
  setup { @test_counter += 10 }
@@ -72,13 +66,13 @@ context "nested context" do
72
66
  end
73
67
  end
74
68
 
75
- asserts("inner context inherits parent context setup") do
69
+ should("inherit parent context") do
76
70
  inner_nested_context.instance_variable_get(:@test_counter)
77
71
  end.equals(10)
78
72
 
79
- asserts("nested context name") { inner_nested_context.to_s }.equals("foo baz")
73
+ should("chain context names") { inner_nested_context.to_s }.equals("foo baz")
80
74
 
81
- asserts("inner context without setup is still bootstrapped") do
75
+ asserts "parent setup is called even if setup not defined for self" do
82
76
  other_nested_context.instance_variable_get(:@foo)
83
77
  end.equals("bar")
84
78
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thumblemonks-protest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Knowlden
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-05 00:00:00 -07:00
12
+ date: 2009-08-12 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -33,6 +33,7 @@ files:
33
33
  - protest.gemspec
34
34
  has_rdoc: false
35
35
  homepage: http://github.com/thumblemonks/protest
36
+ licenses:
36
37
  post_install_message:
37
38
  rdoc_options:
38
39
  - --main
@@ -54,7 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
55
  requirements: []
55
56
 
56
57
  rubyforge_project:
57
- rubygems_version: 1.2.0
58
+ rubygems_version: 1.3.5
58
59
  signing_key:
59
60
  specification_version: 2
60
61
  summary: An extremely fast, expressive, and context-driven unit-testing framework