dupe 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.rdoc +390 -147
  2. data/lib/dupe/active_resource_extensions.rb +25 -0
  3. data/lib/dupe/attribute_template.rb +71 -0
  4. data/lib/dupe/cucumber_hooks.rb +15 -7
  5. data/lib/dupe/custom_mocks.rb +102 -0
  6. data/lib/dupe/database.rb +51 -0
  7. data/lib/dupe/dupe.rb +359 -372
  8. data/lib/dupe/log.rb +38 -0
  9. data/lib/dupe/mock.rb +50 -0
  10. data/lib/dupe/model.rb +55 -0
  11. data/lib/dupe/network.rb +38 -0
  12. data/lib/dupe/record.rb +35 -56
  13. data/lib/dupe/rest_validation.rb +16 -0
  14. data/lib/dupe/schema.rb +36 -0
  15. data/lib/dupe/sequence.rb +11 -10
  16. data/lib/dupe/singular_plural_detection.rb +9 -0
  17. data/lib/dupe/string.rb +6 -8
  18. data/lib/dupe/symbol.rb +3 -0
  19. data/lib/dupe.rb +13 -12
  20. data/rails_generators/dupe/templates/custom_mocks.rb +4 -34
  21. data/rails_generators/dupe/templates/dupe_setup.rb +3 -23
  22. data/spec/lib_specs/active_resource_extensions_spec.rb +29 -0
  23. data/spec/lib_specs/attribute_template_spec.rb +173 -0
  24. data/spec/lib_specs/database_spec.rb +133 -0
  25. data/spec/lib_specs/dupe_spec.rb +307 -0
  26. data/spec/lib_specs/log_spec.rb +78 -0
  27. data/spec/lib_specs/logged_request_spec.rb +22 -0
  28. data/spec/lib_specs/mock_definitions_spec.rb +32 -0
  29. data/spec/lib_specs/mock_spec.rb +67 -0
  30. data/spec/lib_specs/model_spec.rb +90 -0
  31. data/spec/lib_specs/network_spec.rb +77 -0
  32. data/spec/lib_specs/record_spec.rb +70 -0
  33. data/spec/lib_specs/rest_validation_spec.rb +17 -0
  34. data/spec/lib_specs/schema_spec.rb +90 -0
  35. data/spec/lib_specs/sequence_spec.rb +26 -0
  36. data/spec/lib_specs/string_spec.rb +31 -0
  37. data/spec/lib_specs/symbol_spec.rb +17 -0
  38. data/spec/spec_helper.rb +2 -5
  39. metadata +29 -7
  40. data/lib/dupe/active_resource.rb +0 -135
  41. data/lib/dupe/attribute.rb +0 -17
  42. data/lib/dupe/configuration.rb +0 -20
  43. data/lib/dupe/mock_service_response.rb +0 -55
  44. data/spec/lib_specs/dupe_record_spec.rb +0 -57
@@ -1,8 +1,16 @@
1
- After do |scenario| #:nodoc:
2
- if Dupe.global_configuration.config[:debug] == true
3
- ActiveResource::Connection.print_request_log
4
- ActiveResource::Connection.flush_request_log
1
+ begin
2
+ After do |scenario|
3
+ # print the requests logged during the scenario if in Dupe debug mode
4
+ if Dupe.debug
5
+ log = Dupe.network.log.pretty_print
6
+ puts "\n\n" + log.indent(4) + "\n\n" if log
7
+ end
8
+
9
+ # remove any data created during the scenario from the dupe database
10
+ Dupe.database.truncate_tables
11
+
12
+ # clear out the network log
13
+ Dupe.network.log.reset
5
14
  end
6
-
7
- Dupe.flush
8
- end
15
+ rescue
16
+ end
@@ -0,0 +1,102 @@
1
+ # Dupe knows how to handle simple find by id and find :all lookups from ActiveResource. But what about other requests we might potentially make?
2
+ #
3
+ # irb# Dupe.create :author, :name => 'Monkey', :published => true
4
+ # ==> <#Duped::Author name="Monkey" published=true id=1>
5
+ #
6
+ # irb# Dupe.create :author, :name => 'Tiger', :published => false
7
+ # ==> <#Duped::Author name="Tiger" published=false id=2>
8
+ #
9
+ # irb# class Author < ActiveResource::Base; self.site = ''; end
10
+ # ==> ""
11
+ #
12
+ # irb# Author.find :all, :from => :published
13
+ # Dupe::Network::RequestNotFoundError: No mocked service response found for '/authors/published.xml'
14
+ # from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/network.rb:32:in `match'
15
+ # from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/network.rb:17:in `request'
16
+ # from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/active_resource_extensions.rb:15:in `get'
17
+ # from /Library/Ruby/Gems/1.8/gems/activeresource-2.3.5/lib/active_resource/custom_methods.rb:57:in `get'
18
+ # from /Library/Ruby/Gems/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:632:in `find_every'
19
+ # from /Library/Ruby/Gems/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:582:in `find'
20
+ # from (irb):12
21
+ #
22
+ # Obviously, Dupe had no way of anticipating this possibility. However, you can create your own custom intercept mock for this:
23
+ #
24
+ # irb# Get %r{/authors/published.xml} do
25
+ # --# Dupe.find(:authors) {|a| a.published == true}
26
+ # --# end
27
+ # ==> #<Dupe::Network::Mock:0x1833e88 @url_pattern=/\/authors\/published.xml/, @verb=:get, @response=#<Proc:0x01833f14@(irb):13>
28
+ #
29
+ # irb# Author.find :all, :from => :published
30
+ # ==> [#<Author:0x1821d3c @attributes={"name"=>"Monkey", "published"=>true, "id"=>1}, prefix_options{}]
31
+ #
32
+ # irb# puts Dupe.network.log.pretty_print
33
+ #
34
+ # Logged Requests:
35
+ # Request: GET /authors/published.xml
36
+ # Response:
37
+ # <?xml version="1.0" encoding="UTF-8"?>
38
+ # <authors type="array">
39
+ # <author>
40
+ # <name>Monkey</name>
41
+ # <published type="boolean">true</published>
42
+ # <id type="integer">1</id>
43
+ # </author>
44
+ # </authors>
45
+ #
46
+ #
47
+ # The "Get" method requires a url pattern and a block. In most cases, your block will return a Dupe.find result. Internally, Dupe will transform that into XML. However, if your "Get" block returns a string, Dupe will use that as the response body and not attempt to do any transformations on it.
48
+ #
49
+ # Suppose instead the service expected us to pass published as a query string parameter:
50
+ #
51
+ # irb# Author.find :all, :params => {:published => true}
52
+ # Dupe::Network::RequestNotFoundError: No mocked service response found for '/authors.xml?published=true'
53
+ # from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/network.rb:32:in `match'
54
+ # from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/network.rb:17:in `request'
55
+ # from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/active_resource_extensions.rb:15:in `get'
56
+ # from /Library/Ruby/Gems/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:639:in `find_every'
57
+ # from /Library/Ruby/Gems/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:582:in `find'
58
+ # from (irb):18
59
+ #
60
+ # We can mock this with the following:
61
+ #
62
+ # irb# Get %r{/authors\.xml\?published=(true|false)$} do |published|
63
+ # --# if published == 'true'
64
+ # --# Dupe.find(:authors) {|a| a.published == true}
65
+ # --# else
66
+ # --# Dupe.find(:authors) {|a| a.published == false}
67
+ # --# end
68
+ # --# end
69
+ #
70
+ # irb# Author.find :all, :params => {:published => true}
71
+ # ==> [#<Author:0x17db094 @attributes={"name"=>"Monkey", "published"=>true, "id"=>1}, prefix_options{}]
72
+ #
73
+ # irb# Author.find :all, :params => {:published => false}
74
+ # ==> [#<Author:0x17c68c4 @attributes={"name"=>"Tiger", "published"=>false, "id"=>2}, prefix_options{}]
75
+ #
76
+ # irb# puts Dupe.network.log.pretty_print
77
+ #
78
+ # Logged Requests:
79
+ # Request: GET /authors.xml?published=true
80
+ # Response:
81
+ # <?xml version="1.0" encoding="UTF-8"?>
82
+ # <authors type="array">
83
+ # <author>
84
+ # <name>Monkey</name>
85
+ # <published type="boolean">true</published>
86
+ # <id type="integer">1</id>
87
+ # </author>
88
+ # </authors>
89
+ #
90
+ # Request: GET /authors.xml?published=false
91
+ # Response:
92
+ # <?xml version="1.0" encoding="UTF-8"?>
93
+ # <authors type="array">
94
+ # <author>
95
+ # <name>Tiger</name>
96
+ # <published type="boolean">false</published>
97
+ # <id type="integer">2</id>
98
+ # </author>
99
+ # </authors>
100
+ def Get(url_pattern, &block)
101
+ Dupe.network.define_service_mock :get, url_pattern, block
102
+ end
@@ -0,0 +1,51 @@
1
+ class Dupe
2
+ class Database #:nodoc:
3
+ attr_reader :tables
4
+
5
+ #:nodoc:
6
+ class TableDoesNotExistError < StandardError; end
7
+
8
+ #:nodoc:
9
+ class InvalidQueryError < StandardError; end
10
+
11
+ # by default, there are not tables in the database
12
+ def initialize
13
+ @tables = {}
14
+ end
15
+
16
+ # pass in a Dupe::Database::Record object, and this method will store the record
17
+ # in the appropriate table
18
+ def insert(record)
19
+ if !record.kind_of?(Dupe::Database::Record) || !record.__model__ || !record[:id]
20
+ raise ArgumentError, "You may only insert well-defined Dupe::Database::Record objects"
21
+ end
22
+ @tables[record.__model__.name] ||= []
23
+ @tables[record.__model__.name] << record
24
+ end
25
+
26
+ # pass in a model_name (e.g., :book) and optionally a proc with
27
+ # conditions (e.g., {|b| b.genre == 'Science Fiction'})
28
+ # and recieve a (possibly empty) array of results
29
+ def select(model_name, conditions=nil)
30
+ raise TableDoesNotExistError, "The table ':#{model_name}' does not exist." unless @tables[model_name]
31
+ raise(
32
+ InvalidQueryError,
33
+ "There was a problem with your select conditions. Please consult the API."
34
+ ) if conditions and (!conditions.kind_of?(Proc) || conditions.arity != 1)
35
+
36
+ return @tables[model_name] if !conditions
37
+ @tables[model_name].select {|r| conditions.call(r)}
38
+ end
39
+
40
+ def create_table(model_name)
41
+ @tables[model_name.to_sym] ||= []
42
+ end
43
+
44
+ def truncate_tables
45
+ @tables.each do |table_name, table_records|
46
+ @tables[table_name] = []
47
+ end
48
+ end
49
+
50
+ end
51
+ end