thumblemonks-protest 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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