bogus 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.travis.yml +1 -0
  2. data/Gemfile.lock +6 -1
  3. data/README.md +3 -0
  4. data/features/changelog.md +30 -22
  5. data/features/configuration/fake_ar_attributes.feature +3 -1
  6. data/features/configuration/search_modules.feature +5 -0
  7. data/features/contract_tests/contract_tests_mocks.feature +12 -1
  8. data/features/contract_tests/contract_tests_spies.feature +14 -2
  9. data/features/contract_tests/contract_tests_stubs.feature +13 -2
  10. data/features/contract_tests/return_value_contracts.feature +15 -4
  11. data/features/fakes/anonymous_doubles.feature +15 -1
  12. data/features/fakes/duck_types.feature +12 -2
  13. data/features/fakes/fake_objects.feature +11 -1
  14. data/features/fakes/global_fake_configuration.feature +4 -1
  15. data/features/readme.md +2 -2
  16. data/features/safe_stubbing/argument_matchers.feature +32 -2
  17. data/features/safe_stubbing/safe_mocking.feature +9 -2
  18. data/features/safe_stubbing/safe_stubbing.feature +11 -2
  19. data/features/safe_stubbing/spies.feature +52 -1
  20. data/features/step_definitions/rspec_steps.rb +1 -2
  21. data/features/support/env.rb +19 -0
  22. data/lib/bogus/active_record_accessors.rb +4 -4
  23. data/lib/bogus/adds_recording.rb +1 -0
  24. data/lib/bogus/any_args.rb +32 -3
  25. data/lib/bogus/class_methods.rb +7 -1
  26. data/lib/bogus/copies_classes.rb +5 -2
  27. data/lib/bogus/fake.rb +0 -2
  28. data/lib/bogus/have_received_matcher.rb +5 -0
  29. data/lib/bogus/interaction.rb +66 -35
  30. data/lib/bogus/interactions_repository.rb +1 -1
  31. data/lib/bogus/makes_substitute_methods.rb +3 -2
  32. data/lib/bogus/mocking_dsl.rb +8 -0
  33. data/lib/bogus/public_methods.rb +1 -1
  34. data/lib/bogus/rspec_extensions.rb +8 -1
  35. data/lib/bogus/same_class.rb +14 -0
  36. data/lib/bogus/shadow.rb +8 -12
  37. data/lib/bogus/verifies_stub_definition.rb +1 -5
  38. data/lib/bogus/version.rb +1 -1
  39. data/spec/bogus/adds_recording_spec.rb +8 -0
  40. data/spec/bogus/class_methods_spec.rb +8 -2
  41. data/spec/bogus/clean_ruby_spec.rb +15 -0
  42. data/spec/bogus/have_received_matcher_spec.rb +45 -27
  43. data/spec/bogus/instance_methods_spec.rb +1 -1
  44. data/spec/bogus/interaction_spec.rb +87 -83
  45. data/spec/bogus/interactions_repository_spec.rb +8 -11
  46. data/spec/bogus/shadow_spec.rb +4 -1
  47. metadata +81 -39
  48. checksums.yaml +0 -7
@@ -21,7 +21,7 @@ Feature: Faking duck types
21
21
  end
22
22
 
23
23
  Background:
24
- Given a file named "foo.rb" with:
24
+ Given a file named "loggers.rb" with:
25
25
  """ruby
26
26
  class DatabaseLogger
27
27
  def error(message); end
@@ -56,6 +56,8 @@ Feature: Faking duck types
56
56
  Scenario: Copying instance methods
57
57
  Then spec file with following content should pass:
58
58
  """ruby
59
+ require_relative 'loggers'
60
+
59
61
  describe "make_duck" do
60
62
  let(:duck) { make_duck(DatabaseLogger, NetworkLogger,
61
63
  DevNullLogger) }
@@ -94,6 +96,8 @@ Feature: Faking duck types
94
96
  Scenario: Faking duck types
95
97
  Then spec file with following content should pass:
96
98
  """ruby
99
+ require_relative 'loggers'
100
+
97
101
  describe "fake with multiple classes" do
98
102
  fake(:logger) { [DatabaseLogger,
99
103
  NetworkLogger,
@@ -110,7 +114,7 @@ Feature: Faking duck types
110
114
  """
111
115
 
112
116
  Scenario: Globally configured duck types
113
- Then spec file with following content should pass:
117
+ Given a file named "fakes.rb" with:
114
118
  """ruby
115
119
  Bogus.fakes do
116
120
  logger_implementations = proc{ [DatabaseLogger,
@@ -119,6 +123,12 @@ Feature: Faking duck types
119
123
 
120
124
  fake :logger, class: logger_implementations
121
125
  end
126
+ """
127
+
128
+ Then spec file with following content should pass:
129
+ """ruby
130
+ require_relative 'fakes'
131
+ require_relative 'loggers'
122
132
 
123
133
  describe "fake with multiple classes" do
124
134
  fake(:logger)
@@ -26,7 +26,7 @@ Feature: Faking existing classes
26
26
  let(:foo) { fake(:foo, bar: "value") }
27
27
 
28
28
  Background:
29
- Given a file named "foo.rb" with:
29
+ Given a file named "library.rb" with:
30
30
  """ruby
31
31
  class Library
32
32
  def checkout(book)
@@ -38,7 +38,10 @@ Feature: Faking existing classes
38
38
  def self.look_up(book)
39
39
  end
40
40
  end
41
+ """
41
42
 
43
+ Given a file named "student.rb" with:
44
+ """ruby
42
45
  class Student
43
46
  def self.learn(library = Library.new)
44
47
  library.checkout("hello world")
@@ -50,6 +53,9 @@ Feature: Faking existing classes
50
53
  Scenario: Calling methods that exist on real object
51
54
  Then spec file with following content should pass:
52
55
  """ruby
56
+ require_relative 'student'
57
+ require_relative 'library'
58
+
53
59
  describe Student do
54
60
  fake(:library)
55
61
 
@@ -79,6 +85,8 @@ Feature: Faking existing classes
79
85
  Scenario: Fakes which are classes
80
86
  Then spec file with following content should pass:
81
87
  """ruby
88
+ require_relative 'library'
89
+
82
90
  describe "library class fake" do
83
91
  fake(:library, as: :class)
84
92
 
@@ -99,6 +107,8 @@ Feature: Faking existing classes
99
107
  Scenario: Fakes with inline return values
100
108
  Then spec file with following content should pass:
101
109
  """ruby
110
+ require_relative 'library'
111
+
102
112
  describe "library class fake" do
103
113
  let(:library) { fake(:library, checkout: "checked out",
104
114
  return_book: "returned") }
@@ -18,7 +18,7 @@ Feature: Global fake configuration
18
18
  in your spec helper, or a file required from it.
19
19
 
20
20
  Background:
21
- Given a file named "foo.rb" with:
21
+ Given a file named "public_library.rb" with:
22
22
  """ruby
23
23
  class PublicLibrary
24
24
  def self.books_by_author(name)
@@ -39,6 +39,7 @@ Feature: Global fake configuration
39
39
  Then spec file with following content should pass:
40
40
  """ruby
41
41
  require_relative "fakes"
42
+ require_relative "public_library"
42
43
 
43
44
  describe "The library fake" do
44
45
  fake(:library)
@@ -64,6 +65,7 @@ Feature: Global fake configuration
64
65
  Then spec file with following content should pass:
65
66
  """ruby
66
67
  require_relative "fakes"
68
+ require_relative "public_library"
67
69
 
68
70
  describe "The library fake" do
69
71
  fake(:library, books_by_author: ["Some Book"])
@@ -78,6 +80,7 @@ Feature: Global fake configuration
78
80
  Then spec file with following content should pass:
79
81
  """ruby
80
82
  require_relative "fakes"
83
+ require_relative "public_library"
81
84
 
82
85
  describe "The library fake" do
83
86
  it "can be overridden in the helper" do
@@ -37,8 +37,8 @@ Bogus makes your test doubles more assertive. They will no longer be too shy to
37
37
  Let's reexamine our previous example, this time Bogus-style:
38
38
 
39
39
  it "returns the average score" do
40
- students = fake(:students, get: [5, 9])
41
- scores = fake(:scores, all: ["John", "Mary"])
40
+ scores = fake(:scores, get: [5, 9])
41
+ students = fake(:students, all: ["John", "Mary"])
42
42
 
43
43
  report_card = ReportCard.new(scores, students)
44
44
 
@@ -3,7 +3,7 @@ Feature: Argument matchers
3
3
  Bogus supports some argument matchers for use, when you don't really care about exact equality of arguments passed in or spied on.
4
4
 
5
5
  Background:
6
- Given a file named "foo.rb" with:
6
+ Given a file named "catalog.rb" with:
7
7
  """ruby
8
8
  class Catalog
9
9
  def self.books_by_author_and_title(author, title)
@@ -14,17 +14,47 @@ Feature: Argument matchers
14
14
  Scenario: Stubbing methods with any arguments
15
15
  Then the following test should pass:
16
16
  """ruby
17
+ require_relative 'catalog'
18
+
17
19
  stub(Catalog).books_by_author_and_title(any_args) { :some_book }
18
20
 
19
- Catalog.books_by_author_and_title("Mark Twain", "Tom Sawyer").should == :some_book
21
+ Catalog.books_by_author_and_title("Arthur Conan Doyle", "Sherlock Holmes").should == :some_book
20
22
  """
21
23
 
22
24
  Scenario: Stubbing methods with some wildcard arguments
23
25
  Then the following test should pass:
24
26
  """ruby
27
+ require_relative 'catalog'
28
+
29
+ stub(Catalog).books_by_author_and_title(any_args) { :some_book }
25
30
  stub(Catalog).books_by_author_and_title("Mark Twain", anything) { :twains_book }
26
31
 
27
32
  Catalog.books_by_author_and_title("Mark Twain", "Tom Sawyer").should == :twains_book
28
33
  Catalog.books_by_author_and_title("Mark Twain", "Huckleberry Finn").should == :twains_book
34
+ Catalog.books_by_author_and_title("Arthur Conan Doyle", "Sherlock Holmes").should == :some_book
35
+ """
36
+
37
+ Scenario: Stubbing methods with proc argument matcher
38
+ Then the following test should pass:
39
+ """ruby
40
+ require_relative 'catalog'
41
+
42
+ stub(Catalog).books_by_author_and_title(any_args) { :some_book }
43
+ stub(Catalog).books_by_author_and_title(with{|author| author =~ /Twain/ }) { :twains_book }
44
+
45
+ Catalog.books_by_author_and_title("Mark Twain", "Tom Sawyer").should == :twains_book
46
+ Catalog.books_by_author_and_title("M. Twain", "Huckleberry Finn").should == :twains_book
47
+ Catalog.books_by_author_and_title("Arthur Conan Doyle", "Sherlock Holmes").should == :some_book
29
48
  """
30
49
 
50
+ Scenario: Stubbing methods with argument type matcher
51
+ Then the following test should pass:
52
+ """ruby
53
+ require_relative 'catalog'
54
+
55
+ stub(Catalog).books_by_author_and_title(any_args) { :some_book }
56
+ stub(Catalog).books_by_author_and_title(any(String), any(String)) { :twains_book }
57
+
58
+ Catalog.books_by_author_and_title("Mark Twain", "Tom Sawyer").should == :twains_book
59
+ Catalog.books_by_author_and_title("M. Twain", :other_book).should == :some_book
60
+ """
@@ -15,7 +15,7 @@ Feature: Safe mocking
15
15
  You can only mock methods that actually exist on an object. It will also work with methods that the object `responds_to?`, but (obviously) without being able to check the method signature.
16
16
 
17
17
  Background:
18
- Given a file named "foo.rb" with:
18
+ Given a file named "library.rb" with:
19
19
  """ruby
20
20
  class Library
21
21
  def checkout(book)
@@ -26,8 +26,9 @@ Feature: Safe mocking
26
26
  Scenario: Mocking methods that exist on real object
27
27
  Then spec file with following content should pass:
28
28
  """ruby
29
- describe Library do
29
+ require_relative 'library'
30
30
 
31
+ describe Library do
31
32
  it "does something" do
32
33
  library = Library.new
33
34
  mock(library).checkout("some book") { :checked_out }
@@ -40,6 +41,8 @@ Feature: Safe mocking
40
41
  Scenario: Mocking methods that do not exist on real object
41
42
  Then spec file with following content should fail:
42
43
  """ruby
44
+ require_relative 'library'
45
+
43
46
  describe Library do
44
47
  it "does something" do
45
48
  library = Library.new
@@ -52,6 +55,8 @@ Feature: Safe mocking
52
55
  Scenario: Mocking methods with wrong number of arguments
53
56
  Then spec file with following content should fail:
54
57
  """ruby
58
+ require_relative 'library'
59
+
55
60
  describe Library do
56
61
  it "does something" do
57
62
  library = Library.new
@@ -64,6 +69,8 @@ Feature: Safe mocking
64
69
  Scenario: Mocks require the methods to be called
65
70
  Then spec file with following content should fail:
66
71
  """ruby
72
+ require_relative 'library'
73
+
67
74
  describe Library do
68
75
  it "does something" do
69
76
  library = Library.new
@@ -7,7 +7,7 @@ Feature: Safe stubbing
7
7
  stub(object).method_name(arg1, arg2, ...) { return_value }
8
8
 
9
9
  Background:
10
- Given a file named "foo.rb" with:
10
+ Given a file named "library.rb" with:
11
11
  """ruby
12
12
  class Library
13
13
  def checkout(book)
@@ -18,8 +18,9 @@ Feature: Safe stubbing
18
18
  Scenario: Stubbing methods that exist on real object
19
19
  Then spec file with following content should pass:
20
20
  """ruby
21
- describe Library do
21
+ require_relative 'library'
22
22
 
23
+ describe Library do
23
24
  it "does something" do
24
25
  library = Library.new
25
26
  stub(library).checkout("some book") { :checked_out }
@@ -32,6 +33,8 @@ Feature: Safe stubbing
32
33
  Scenario: Stubbing methods that do not exist on real object
33
34
  Then spec file with following content should fail:
34
35
  """ruby
36
+ require_relative 'library'
37
+
35
38
  describe Library do
36
39
  it "does something" do
37
40
  library = Library.new
@@ -43,6 +46,8 @@ Feature: Safe stubbing
43
46
  Scenario: Stubbing methods with wrong number of arguments
44
47
  Then spec file with following content should fail:
45
48
  """ruby
49
+ require_relative 'library'
50
+
46
51
  describe Library do
47
52
  it "does something" do
48
53
  library = Library.new
@@ -54,6 +59,8 @@ Feature: Safe stubbing
54
59
  Scenario: Stubs allow the methods to be called
55
60
  Then spec file with following content should pass:
56
61
  """ruby
62
+ require_relative 'library'
63
+
57
64
  describe Library do
58
65
  it "does something" do
59
66
  library = Library.new
@@ -65,6 +72,8 @@ Feature: Safe stubbing
65
72
  Scenario: Stubbing methods multiple times
66
73
  Then spec file with following content should fail:
67
74
  """ruby
75
+ require_relative 'library'
76
+
68
77
  describe Library do
69
78
  it "stubbing with too many arguments" do
70
79
  library = Library.new
@@ -5,14 +5,17 @@ Feature: Spies
5
5
  Typically, stubbing libraries force you to first stub a method, so that you can later make sure it was called. However, if you use fakes, Bogus lets you verify that a method was called (or not) without stubbing it first.
6
6
 
7
7
  Background:
8
- Given a file named "foo.rb" with:
8
+ Given a file named "library.rb" with:
9
9
  """ruby
10
10
  class Library
11
11
  def checkout(book)
12
12
  # marks book as checked out
13
13
  end
14
14
  end
15
+ """
15
16
 
17
+ Given a file named "student.rb" with:
18
+ """ruby
16
19
  class Student
17
20
  def initialize(library)
18
21
  @library = library
@@ -29,6 +32,9 @@ Feature: Spies
29
32
  Scenario: Ensuring methods were called
30
33
  Then spec file with following content should pass:
31
34
  """ruby
35
+ require_relative 'student'
36
+ require_relative 'library'
37
+
32
38
  describe Student do
33
39
  fake(:library)
34
40
 
@@ -46,6 +52,9 @@ Feature: Spies
46
52
  Scenario: Spying on methods that do not exist
47
53
  Then spec file with following content should fail:
48
54
  """ruby
55
+ require_relative 'student'
56
+ require_relative 'library'
57
+
49
58
  describe Student do
50
59
  fake(:library)
51
60
 
@@ -62,6 +71,9 @@ Feature: Spies
62
71
  Scenario: Spying on methods with wrong number of arguments
63
72
  Then spec file with following content should fail:
64
73
  """ruby
74
+ require_relative 'student'
75
+ require_relative 'library'
76
+
65
77
  describe Student do
66
78
  fake(:library)
67
79
 
@@ -79,6 +91,9 @@ Feature: Spies
79
91
  Scenario: Spying on previously stubbed methods
80
92
  Then spec file with following content should pass:
81
93
  """ruby
94
+ require_relative 'student'
95
+ require_relative 'library'
96
+
82
97
  describe Student do
83
98
  fake(:library)
84
99
 
@@ -91,3 +106,39 @@ Feature: Spies
91
106
  end
92
107
  end
93
108
  """
109
+
110
+ Scenario: Spying on attribute writers
111
+ Given a file named "canvas.rb" with:
112
+ """ruby
113
+ class Canvas
114
+ def background_color=(color)
115
+ # do something complicated
116
+ end
117
+ end
118
+ """
119
+
120
+ Given a file named "popup.rb" with:
121
+ """ruby
122
+ class Popup
123
+ def self.alert(message, canvas)
124
+ canvas.background_color = "red"
125
+ # display message
126
+ end
127
+ end
128
+ """
129
+
130
+ Then spec file with following content should pass:
131
+ """ruby
132
+ require_relative 'canvas'
133
+ require_relative 'popup'
134
+
135
+ describe Popup do
136
+ fake(:canvas)
137
+
138
+ it "sets the background to red" do
139
+ Popup.alert("No such file!", canvas)
140
+
141
+ canvas.should have_received(:background_color=, "red")
142
+ end
143
+ end
144
+ """
@@ -6,7 +6,6 @@ Given /^a spec file named "([^"]*)" with:$/ do |file_name, string|
6
6
  Given a file named "#{file_name}" with:
7
7
  """ruby
8
8
  require 'bogus/rspec'
9
- require_relative 'foo'
10
9
 
11
10
  #{string}
12
11
  """
@@ -26,7 +25,7 @@ Then /^all the specs should pass$/ do
26
25
  end
27
26
 
28
27
  When /^I run spec with the following content:$/ do |string|
29
- file_name = 'foo_spec.rb'
28
+ file_name = "foo_#{rand(1000000)}_spec.rb"
30
29
 
31
30
  steps %Q{
32
31
  Given a spec file named "#{file_name}" with:
@@ -1,5 +1,24 @@
1
1
  require 'aruba/cucumber'
2
+ require 'aruba/jruby'
2
3
 
3
4
  Before('@known_bug') do
4
5
  pending("This scenario fails because of a known bug")
5
6
  end
7
+
8
+ Before do |scenario|
9
+ dir_name = "scenario-#{rand(1_000_000)}"
10
+ create_dir(dir_name)
11
+ cd(dir_name)
12
+ end
13
+
14
+ Before do
15
+ @aruba_timeout_seconds = 60
16
+ end
17
+
18
+ if RUBY_PLATFORM == 'java' && ENV['TRAVIS']
19
+ Aruba.configure do |config|
20
+ config.before_cmd do
21
+ set_env('JAVA_OPTS', "#{ENV['JAVA_OPTS']} -d64")
22
+ end
23
+ end
24
+ end
@@ -7,7 +7,7 @@ module Bogus
7
7
 
8
8
  takes :klass, :instance_methods
9
9
 
10
- def_delegators :instance_methods, :remove, :define
10
+ def_delegators :model_methods, :remove, :define
11
11
 
12
12
  def all
13
13
  return [] unless klass < ActiveRecord::Base
@@ -20,8 +20,8 @@ module Bogus
20
20
 
21
21
  private
22
22
 
23
- def instance_methods
24
- @instance_methods.call(klass)
23
+ def model_methods
24
+ instance_methods.call(klass)
25
25
  end
26
26
 
27
27
  def all_attributes
@@ -29,7 +29,7 @@ module Bogus
29
29
  end
30
30
 
31
31
  def missing_attributes
32
- all_attributes - instance_methods.all
32
+ all_attributes - model_methods.all
33
33
  end
34
34
 
35
35
  class Attribute < Struct.new(:name)