peppers-ghost 0.0.0 → 0.0.1.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c4990710319dbcc755fa8e9651b277ea26c94db
4
- data.tar.gz: a39e7dca88220240fdd6be33c1210fc2baac987b
3
+ metadata.gz: fb4767e7fefac57d01e5c9e1bbde36cf7fb59870
4
+ data.tar.gz: badd39258d23e417c1f1a133d4056287b4f383e3
5
5
  SHA512:
6
- metadata.gz: c2fda7ce252b9959861633268deb497e3b47c86efb73c93b796ee51eea3add569f0c2f17efb94e7e90c786bf7ac81697c52cc7d872f92be0291046e3ae2886db
7
- data.tar.gz: 78a728fe87cd8f04015531f33343d6d0486e26dccecb1b617ac5385584d392b6cd818a87d110e7ad95e6c3a008fbb46987f071ea4d0f2520176b717e0c83d71e
6
+ metadata.gz: ee1667f92c9415f36181d25b8a6f1cc46ce9e472a51be55699e205f38caa1f0d241db565681facf3c27baea4fe0e5370a3610fb386a4cdf75f58c1cd340db99e
7
+ data.tar.gz: 2a61937f5bb389aa2a3ddc43cd5316c673834bcd6a36bff1f11ae447ab2019995ffd91af236a3567e45c7f0534027b166834b3166301f27f9088b28ad12435e4
@@ -1,21 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- peppers-ghost (0.0.0)
4
+ peppers-ghost (0.0.1)
5
5
  rspec
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
10
  diff-lcs (1.2.4)
11
- rspec (2.14.1)
12
- rspec-core (~> 2.14.0)
13
- rspec-expectations (~> 2.14.0)
14
- rspec-mocks (~> 2.14.0)
15
- rspec-core (2.14.4)
16
- rspec-expectations (2.14.0)
11
+ rspec (2.13.0)
12
+ rspec-core (~> 2.13.0)
13
+ rspec-expectations (~> 2.13.0)
14
+ rspec-mocks (~> 2.13.0)
15
+ rspec-core (2.13.1)
16
+ rspec-expectations (2.13.0)
17
17
  diff-lcs (>= 1.1.3, < 2.0)
18
- rspec-mocks (2.14.2)
18
+ rspec-mocks (2.13.1)
19
19
 
20
20
  PLATFORMS
21
21
  ruby
@@ -1,25 +1,14 @@
1
+ require 'time'
2
+
3
+ require 'uuidtools'
1
4
  require 'rspec'
2
5
 
3
6
  module PeppersGhost
4
7
  end
5
8
 
6
- require_relative 'peppers-ghost/core'
7
-
8
- require_relative 'peppers-ghost/ghost'
9
9
  require_relative 'peppers-ghost/ghost_factory'
10
-
11
- require_relative 'peppers-ghost/shared/json_context'
12
- require_relative 'peppers-ghost/shared/list_example'
13
-
14
10
  require_relative 'peppers-ghost/matchers'
15
- require_relative 'peppers-ghost/matchers/match_structure_of'
16
- require_relative 'peppers-ghost/matchers/match_resource'
17
-
18
- module PeppersGhost
19
- extend PeppersGhost::GhostFactory
20
- end
21
11
 
22
12
  RSpec.configure do |config|
23
- config.include PeppersGhost::Core
24
- config.include PeppersGhost::Matchers
13
+ config.include PeppersGhost::Matchers, :json => true
25
14
  end
@@ -1,21 +1,125 @@
1
1
  module PeppersGhost::GhostFactory
2
- def define(&block)
2
+ def self.registry
3
+ @registry ||= Registry.new
4
+ end
5
+
6
+ class << self
7
+ delegate :find, to: :registry
8
+ end
9
+
10
+ def self.define(&block)
3
11
  instance_eval &block
4
12
  end
5
13
 
6
- def ghost_for(resource)
7
- ghosts[resource]
14
+ def self.reload
15
+ Dir[File.join(File.expand_path('spec/ghosts'), '**', '*.rb')].sort.each do |file|
16
+ load file
17
+ end
18
+ end
19
+
20
+ def self.resource(name, &block)
21
+ resource = Resource.new
22
+ resource.instance_eval(&block) if block_given?
23
+
24
+ registry.add_resource name, resource
25
+ end
26
+
27
+ class Registry
28
+ def initialize
29
+ @resources = {}
30
+ end
31
+
32
+ def add_resource(name, resource)
33
+ @resources[name] = resource
34
+ end
35
+
36
+ def find(name)
37
+ @resources[name]
38
+ end
39
+ end
40
+
41
+ class Resource
42
+ def initialize
43
+ @attributes = {}
44
+ end
45
+
46
+ def attribute_names
47
+ @attributes.keys
48
+ end
49
+
50
+ def attribute_definition_for(name)
51
+ @attributes[name]
52
+ end
53
+
54
+ def attribute(name, options={}, &block)
55
+ if block_given?
56
+ add_dynamic_attribute(name, options, &block)
57
+ else
58
+ add_implicit_attribute(name, options)
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def add_dynamic_attribute(name, options={}, &block)
65
+ @attributes[name] = DynamicAttributeDefinition.new(name, options, block)
66
+ end
67
+
68
+ def add_implicit_attribute(name, options={})
69
+ @attributes[name] = ImplicitAttributeDefinition.new(name, options)
70
+ end
71
+
72
+ def method_missing(name, *args, &block)
73
+ attribute(name, *args, &block)
74
+ end
75
+ end
76
+
77
+ class AttributeDefinition
78
+ attr_reader :name, :resource
79
+
80
+ def initialize(name, options={})
81
+ @name = name
82
+ @resource = options[:resource]
83
+ end
84
+
85
+ private
86
+
87
+ def transform(value)
88
+ case value
89
+ when UUIDTools::UUID
90
+ value.to_s
91
+ when Date, Time
92
+ value.iso8601
93
+ else
94
+ value
95
+ end
96
+ end
8
97
  end
9
98
 
10
- def ghost(name, &block)
11
- ghost = PeppersGhost::Ghost.new
12
- ghost.instance_eval &block
13
- ghosts[name] = ghost
99
+ class ImplicitAttributeDefinition < AttributeDefinition
100
+ def evaluate(object)
101
+ if object.respond_to?(name)
102
+ transform object.send(name)
103
+ elsif object.is_a?(Hash)
104
+ transform(object[name.to_s] || object[name.to_sym])
105
+ end
106
+ end
14
107
  end
15
108
 
16
- private
109
+ class DynamicAttributeDefinition < AttributeDefinition
110
+ def initialize(name, options={}, block)
111
+ super name, options
112
+ @block = block
113
+ end
17
114
 
18
- def ghosts
19
- @ghosts ||= {}
115
+ def evaluate(object)
116
+ transform object.instance_eval(&block)
117
+ end
118
+
119
+ private
120
+
121
+ attr_reader :block
20
122
  end
21
123
  end
124
+
125
+ PeppersGhost::GhostFactory.reload
@@ -1,5 +1,160 @@
1
- module PeppersGhost
2
- module Matchers
3
- extend RSpec::Matchers::DSL
1
+ module PeppersGhost::Matchers
2
+ def mirrors_ghost(json_resource, resource, type, strict = false)
3
+ mirrors_structure json_resource, type, 1
4
+ match_values json_resource, resource, type, strict
5
+ end
6
+
7
+ def mirrors_structure(json_resource, type, count = nil)
8
+ expect(json_resource).to_not eq(nil),
9
+ "Expected the #{type} to not be nil"
10
+
11
+ if json_resource.is_a?(Array)
12
+ match_array_structures json_resource, type, count
13
+ elsif !count.nil? and count != 1
14
+ expect(count).to eq(1),
15
+ "Got a singular resource, expected #{count} #{type.to_s.pluralize}"
16
+ else
17
+ match_individual_structure json_resource, type
18
+ end
19
+ end
20
+
21
+ def mirrors_many(json_resources, resources, type, strict = false)
22
+ check_resource_count json_resources, resources, type
23
+ json_resources.each_with_index do |json_resource, i|
24
+ mirrors_ghost json_resource, resources[i], type, strict
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def match_values(json_resource, resource, type, strict = false)
31
+ attributes = attributes_for_resource(type)
32
+ json_resource = json_resource.first if json_resource.is_a?(Array)
33
+ match_attributes json_resource, resource, type, attributes, strict
34
+ end
35
+
36
+ def match_individual_structure(json_resource, type)
37
+ attributes = attributes_for_resource(type)
38
+ expect(json_resource.keys).to match_array attributes.map(&:to_s)
39
+ deep_structure json_resource, type
40
+ end
41
+
42
+ def match_array_structures(json_resources, type, count)
43
+ if count
44
+ expected_resource_count json_resources, count, type
45
+ end
46
+
47
+ json_resources.each do |json_resource|
48
+ mirrors_structure json_resource, type
49
+ end
50
+ end
51
+
52
+ def match_attributes(json_resource, resource, type, attributes, strict = false)
53
+ attributes.each do |attribute|
54
+ resource_doc = resource_doc_for(type)
55
+ definition = resource_doc.attribute_definition_for(attribute)
56
+
57
+ value = definition.evaluate(resource)
58
+ json_value = json_resource[attribute.to_s]
59
+
60
+ if definition.resource
61
+ deep_match json_value, value, definition
62
+ else
63
+ match_attribute json_value, value, type, attribute, strict
64
+ end
65
+ end
66
+ end
67
+
68
+ def deep_match(json_value, value, definition)
69
+ valid = false
70
+ if array?(definition)
71
+ valid = true if json_value.count > 0
72
+ mirrors_many json_value, value, definition.resource
73
+ else
74
+ expect(json_value).to_not be_an Array
75
+ if json_value or value
76
+ valid = true
77
+ mirrors_ghost json_value, value, definition.resource
78
+ end
79
+ end
80
+ Frogger.log_resource(definition.resource, valid)
81
+ end
82
+
83
+ def check_resource_count(json_resources, resources, type)
84
+ expect(json_resources).to be_an Array
85
+ expected_resource_count json_resources, resources.count, type
86
+ end
87
+
88
+ def expected_resource_count(json_resources, count, type)
89
+ structure = type.to_s.pluralize(count)
90
+ expect(json_resources).to have(count).send(structure)
91
+ end
92
+
93
+ def deep_structure(json_resource, type)
94
+ resource_doc = resource_doc_for(type)
95
+ resource_doc.attribute_names.each do |attribute_name|
96
+ definition = resource_doc.attribute_definition_for(attribute_name)
97
+ json_value = json_resource[attribute_name.to_s]
98
+ if definition.resource && json_value
99
+ check_structure json_value, definition
100
+ end
101
+ end
102
+ end
103
+
104
+ def check_structure(json_value, definition)
105
+ check_array_for json_value, definition
106
+ mirrors_structure json_value, definition.resource
107
+ end
108
+
109
+ def check_array_for(json_value, definition)
110
+ if array?(definition)
111
+ expect(json_value).to be_an Array
112
+ else
113
+ expect(json_value).to_not be_an Array
114
+ end
115
+ end
116
+
117
+ def match_attribute(json_value, value, type, attribute, strict = false)
118
+ if strict
119
+ expect(json_value).to_not eq(nil),
120
+ "#{type}.#{attribute} is nil.\n" +
121
+ "Turn off strict mode for this test if a nil value is expected."
122
+ end
123
+
124
+ expect(json_value).to eq(value),
125
+ mismatch_message(type, attribute, json_value, value)
126
+ end
127
+
128
+ def mismatch_message(type, attribute, json_value, value)
129
+ mask = "%s.%s does not match.\n\n" +
130
+ "expected: %s\n" +
131
+ " got: %s"
132
+
133
+ mask % [
134
+ type,
135
+ attribute,
136
+ stringify_value(value),
137
+ stringify_value(json_value),
138
+ ]
139
+ end
140
+
141
+ def stringify_value(value)
142
+ "#{value.class}:#{value}"
143
+ end
144
+
145
+ def resource_doc_for(type)
146
+ type = type.to_s.singularize.to_sym
147
+ resource_doc = PeppersGhost::GhostFactory.find(type)
148
+ expect(resource_doc).to be_a(PeppersGhost::GhostFactory::Resource),
149
+ "Resource specification could not be found for #{type}."
150
+ resource_doc
151
+ end
152
+
153
+ def attributes_for_resource(type)
154
+ resource_doc_for(type).attribute_names
155
+ end
156
+
157
+ def array?(definition)
158
+ definition.resource.to_s.pluralize == definition.resource.to_s
4
159
  end
5
160
  end
@@ -1,13 +1,14 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'peppers-ghost'
3
- s.version = '0.0.0'
3
+ s.version = '0.0.1.alpha.1'
4
4
 
5
5
  s.summary = 'Adds some helpers for testing api resources'
6
- s.description = %Q{}.strip
6
+ s.description = %Q{
7
+ }.strip
7
8
 
8
9
  s.author = 'Travis Herrick'
9
10
  s.email = 'tthetoad@gmail.com'
10
- s.homepage = 'http://www.bitbucket.org/ToadJamb/peppers-ghost'
11
+ s.homepage = 'http://www.bitbucket.org/ToadJamb/gems-peppers-ghost'
11
12
 
12
13
  s.license = 'LGPLv3'
13
14
 
@@ -18,6 +19,7 @@ Gem::Specification.new do |s|
18
19
  s.test_files = Dir['spec/**/*.rb']
19
20
 
20
21
  s.add_dependency 'rspec'
22
+ s.add_dependency 'uuidtools'
21
23
 
22
24
  s.has_rdoc = false
23
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: peppers-ghost
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Travis Herrick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-01 00:00:00.000000000 Z
11
+ date: 2014-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: uuidtools
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: ''
28
42
  email: tthetoad@gmail.com
29
43
  executables: []
@@ -33,16 +47,10 @@ files:
33
47
  - Gemfile
34
48
  - Gemfile.lock
35
49
  - peppers-ghost.gemspec
36
- - lib/peppers-ghost/core.rb
37
- - lib/peppers-ghost/ghost.rb
50
+ - lib/peppers-ghost.rb
38
51
  - lib/peppers-ghost/ghost_factory.rb
39
- - lib/peppers-ghost/matchers/match_resource.rb
40
- - lib/peppers-ghost/matchers/match_structure_of.rb
41
52
  - lib/peppers-ghost/matchers.rb
42
- - lib/peppers-ghost/shared/json_context.rb
43
- - lib/peppers-ghost/shared/list_example.rb
44
- - lib/peppers-ghost.rb
45
- homepage: http://www.bitbucket.org/ToadJamb/peppers-ghost
53
+ homepage: http://www.bitbucket.org/ToadJamb/gems-peppers-ghost
46
54
  licenses:
47
55
  - LGPLv3
48
56
  metadata: {}
@@ -57,12 +65,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
65
  version: '0'
58
66
  required_rubygems_version: !ruby/object:Gem::Requirement
59
67
  requirements:
60
- - - '>='
68
+ - - '>'
61
69
  - !ruby/object:Gem::Version
62
- version: '0'
70
+ version: 1.3.1
63
71
  requirements: []
64
72
  rubyforge_project:
65
- rubygems_version: 2.0.3
73
+ rubygems_version: 2.1.11
66
74
  signing_key:
67
75
  specification_version: 4
68
76
  summary: Adds some helpers for testing api resources
@@ -1,58 +0,0 @@
1
- module PeppersGhost::Core
2
- def match_resource_type(json_resource, resource, attributes, strict = false)
3
- match_structure json_resource, attributes
4
- match_values json_resource, resource, attributes, strict
5
- end
6
-
7
- def match_structure(json_resource, attributes, count = nil, method = nil)
8
- method ||= :resource
9
- expect(json_resource).to_not be_nil
10
-
11
- if json_resource.is_a?(Array)
12
- expect(json_resource).to have(count).method_missing(method) if count
13
- match_single_structure json_resource, attributes, count
14
- else
15
- expect(json_resource.keys).to match_array attributes.map(&:to_s)
16
- end
17
- end
18
-
19
- def match_values(json_resource, resource, attributes, strict = false)
20
- if json_resource.is_a?(Array)
21
- expect(json_resource).to have(1).resource
22
- json_resource = json_resource.first
23
- end
24
- match_attributes json_resource, resource, attributes, strict
25
- end
26
-
27
- private
28
-
29
- def match_single_structure(json_resources, attributes, count)
30
- json_resources.each do |json_resource|
31
- match_structure json_resource, attributes
32
- end
33
- end
34
-
35
- def match_attributes(json_resource, resource, attributes, strict = false)
36
- attributes.each do |attribute|
37
- next unless resource.respond_to?(attribute) or
38
- (resource.is_a?(Hash) and
39
- (resource.has_key?(attribute.to_s) or resource.has_key?(attribute.to_sym)))
40
-
41
- value =
42
- if resource.respond_to?(attribute)
43
- resource.send attribute
44
- elsif resource.is_a? Hash
45
- resource[attribute.to_s] || resource[attribute.to_sym]
46
- end
47
-
48
- json_value = json_resource[attribute.to_s]
49
-
50
- match_attribute json_value, value, strict
51
- end
52
- end
53
-
54
- def match_attribute(json_value, value, strict = false)
55
- expect(value).to_not be_nil if strict
56
- expect(json_value).to eq value
57
- end
58
- end
@@ -1,9 +0,0 @@
1
- class PeppersGhost::Ghost
2
- def attributes
3
- @attributes ||= []
4
- end
5
-
6
- def method_missing(method, *args, &block)
7
- attributes << method
8
- end
9
- end
@@ -1,21 +0,0 @@
1
- module PeppersGhost::Matchers
2
- matcher :match_resource do |expected, type|
3
- chain :strictly do
4
- @strict = true
5
- end
6
-
7
- match do |actual|
8
- begin
9
- resource = PeppersGhost.ghost_for(type)
10
- match_resource_type actual, expected, resource.attributes, @strict
11
- rescue RSpec::Expectations::ExpectationNotMetError => e
12
- @error = e.message
13
- false
14
- end
15
- end
16
-
17
- failure_message_for_should do
18
- @error
19
- end
20
- end
21
- end
@@ -1,30 +0,0 @@
1
- module PeppersGhost::Matchers
2
- matcher :match_structure_of do |expected|
3
- chain :with do |count|
4
- @count = count
5
- end
6
-
7
- match do |actual|
8
- begin
9
- resource = PeppersGhost.ghost_for(expected)
10
- match_structure actual, resource.attributes, @count, @method
11
- rescue RSpec::Expectations::ExpectationNotMetError => e
12
- @error = e.message
13
- false
14
- end
15
- end
16
-
17
- failure_message_for_should do
18
- @error
19
- end
20
-
21
- def method_missing(method, *args, &block)
22
- if defined?(@method)
23
- super
24
- else
25
- @method = method
26
- end
27
- self
28
- end
29
- end
30
- end
@@ -1,5 +0,0 @@
1
- shared_context 'json' do
2
- let(:json) { JSON last_response.body }
3
- let(:root_key) { json.keys.reject { |k| k == 'meta' }.first }
4
- let(:json_root) { json[root_key] }
5
- end
@@ -1,7 +0,0 @@
1
- shared_examples_for 'a list of' do |type, count|
2
- include_context 'json'
3
-
4
- it "returns a list of #{type}" do
5
- expect(json_root).to match_structure_of(type).with(count).method_missing(type)
6
- end
7
- end