restspec 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +21 -0
- data/.gitignore +23 -0
- data/.rspec +4 -0
- data/Gemfile +4 -0
- data/Guardfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +188 -0
- data/ROADMAP.md +11 -0
- data/Rakefile +20 -0
- data/bin/restspec +54 -0
- data/bin/templates/Gemfile +3 -0
- data/bin/templates/custom_macros.rb +3 -0
- data/bin/templates/restspec_config.rb +10 -0
- data/bin/templates/spec_helper.rb +19 -0
- data/docs/endpoints.md +200 -0
- data/docs/helpers.md +40 -0
- data/docs/macros.md +140 -0
- data/docs/matchers.md +38 -0
- data/docs/schemas.md +28 -0
- data/docs/tutorial.md +477 -0
- data/docs/types.md +134 -0
- data/examples/store-api-tests/.rspec +3 -0
- data/examples/store-api-tests/Gemfile +4 -0
- data/examples/store-api-tests/Gemfile.lock +70 -0
- data/examples/store-api-tests/spec/api/category_spec.rb +23 -0
- data/examples/store-api-tests/spec/api/product_spec.rb +55 -0
- data/examples/store-api-tests/spec/api/restspec/endpoints.rb +39 -0
- data/examples/store-api-tests/spec/api/restspec/requirements.rb +0 -0
- data/examples/store-api-tests/spec/api/restspec/restspec_config.rb +6 -0
- data/examples/store-api-tests/spec/api/restspec/schemas.rb +11 -0
- data/examples/store-api-tests/spec/spec_helper.rb +19 -0
- data/examples/store-api-tests/spec/support/custom_macros.rb +3 -0
- data/examples/store-api-tests/spec/support/custom_matchers.rb +0 -0
- data/examples/store-api/.editorconfig +24 -0
- data/examples/store-api/.rbenv-vars.example +3 -0
- data/examples/store-api/.rspec +4 -0
- data/examples/store-api/.ruby-version +1 -0
- data/examples/store-api/Gemfile +58 -0
- data/examples/store-api/Gemfile.lock +216 -0
- data/examples/store-api/Guardfile +39 -0
- data/examples/store-api/README.md +1 -0
- data/examples/store-api/Rakefile +6 -0
- data/examples/store-api/app/assets/images/.keep +0 -0
- data/examples/store-api/app/assets/javascripts/application.js +16 -0
- data/examples/store-api/app/assets/javascripts/categories.js.coffee +3 -0
- data/examples/store-api/app/assets/javascripts/products.js.coffee +3 -0
- data/examples/store-api/app/assets/stylesheets/application.css +15 -0
- data/examples/store-api/app/assets/stylesheets/categories.css.scss +3 -0
- data/examples/store-api/app/assets/stylesheets/products.css.scss +3 -0
- data/examples/store-api/app/assets/stylesheets/scaffolds.css.scss +69 -0
- data/examples/store-api/app/controllers/application_controller.rb +5 -0
- data/examples/store-api/app/controllers/categories_controller.rb +74 -0
- data/examples/store-api/app/controllers/concerns/.keep +0 -0
- data/examples/store-api/app/controllers/products_controller.rb +74 -0
- data/examples/store-api/app/helpers/application_helper.rb +2 -0
- data/examples/store-api/app/helpers/categories_helper.rb +2 -0
- data/examples/store-api/app/helpers/products_helper.rb +2 -0
- data/examples/store-api/app/mailers/.keep +0 -0
- data/examples/store-api/app/models/.keep +0 -0
- data/examples/store-api/app/models/category.rb +2 -0
- data/examples/store-api/app/models/concerns/.keep +0 -0
- data/examples/store-api/app/models/product.rb +3 -0
- data/examples/store-api/app/views/categories/_form.html.erb +21 -0
- data/examples/store-api/app/views/categories/edit.html.erb +6 -0
- data/examples/store-api/app/views/categories/index.html.erb +25 -0
- data/examples/store-api/app/views/categories/index.json.jbuilder +4 -0
- data/examples/store-api/app/views/categories/new.html.erb +5 -0
- data/examples/store-api/app/views/categories/show.html.erb +9 -0
- data/examples/store-api/app/views/categories/show.json.jbuilder +1 -0
- data/examples/store-api/app/views/layouts/application.html.erb +14 -0
- data/examples/store-api/app/views/products/_form.html.erb +29 -0
- data/examples/store-api/app/views/products/edit.html.erb +6 -0
- data/examples/store-api/app/views/products/index.html.erb +29 -0
- data/examples/store-api/app/views/products/index.json.jbuilder +4 -0
- data/examples/store-api/app/views/products/new.html.erb +5 -0
- data/examples/store-api/app/views/products/show.html.erb +19 -0
- data/examples/store-api/app/views/products/show.json.jbuilder +6 -0
- data/examples/store-api/bin/bundle +3 -0
- data/examples/store-api/bin/guard +16 -0
- data/examples/store-api/bin/rails +8 -0
- data/examples/store-api/bin/rake +8 -0
- data/examples/store-api/bin/spring +18 -0
- data/examples/store-api/config.ru +4 -0
- data/examples/store-api/config/application.rb +30 -0
- data/examples/store-api/config/boot.rb +4 -0
- data/examples/store-api/config/database.yml +25 -0
- data/examples/store-api/config/environment.rb +5 -0
- data/examples/store-api/config/environments/development.rb +37 -0
- data/examples/store-api/config/environments/production.rb +78 -0
- data/examples/store-api/config/environments/test.rb +39 -0
- data/examples/store-api/config/initializers/assets.rb +8 -0
- data/examples/store-api/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/store-api/config/initializers/cookies_serializer.rb +3 -0
- data/examples/store-api/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/store-api/config/initializers/inflections.rb +16 -0
- data/examples/store-api/config/initializers/mime_types.rb +4 -0
- data/examples/store-api/config/initializers/session_store.rb +3 -0
- data/examples/store-api/config/initializers/wrap_parameters.rb +14 -0
- data/examples/store-api/config/locales/en.yml +23 -0
- data/examples/store-api/config/routes.rb +59 -0
- data/examples/store-api/config/secrets.yml +22 -0
- data/examples/store-api/db/migrate/20141205154816_create_products.rb +11 -0
- data/examples/store-api/db/migrate/20141205171104_create_categories.rb +9 -0
- data/examples/store-api/db/migrate/20141205171140_add_category_id_to_products.rb +5 -0
- data/examples/store-api/db/schema.rb +31 -0
- data/examples/store-api/db/seeds.rb +7 -0
- data/examples/store-api/lib/assets/.keep +0 -0
- data/examples/store-api/lib/tasks/.keep +0 -0
- data/examples/store-api/log/.keep +0 -0
- data/examples/store-api/public/404.html +67 -0
- data/examples/store-api/public/422.html +67 -0
- data/examples/store-api/public/500.html +66 -0
- data/examples/store-api/public/favicon.ico +0 -0
- data/examples/store-api/public/robots.txt +5 -0
- data/examples/store-api/spec/controllers/categories_controller_spec.rb +159 -0
- data/examples/store-api/spec/controllers/products_controller_spec.rb +159 -0
- data/examples/store-api/spec/factories/categories.rb +6 -0
- data/examples/store-api/spec/factories/products.rb +8 -0
- data/examples/store-api/spec/helpers/categories_helper_spec.rb +15 -0
- data/examples/store-api/spec/helpers/products_helper_spec.rb +15 -0
- data/examples/store-api/spec/models/category_spec.rb +5 -0
- data/examples/store-api/spec/models/product_spec.rb +5 -0
- data/examples/store-api/spec/rails_helper.rb +50 -0
- data/examples/store-api/spec/requests/categories_spec.rb +10 -0
- data/examples/store-api/spec/requests/products_spec.rb +10 -0
- data/examples/store-api/spec/routing/categories_routing_spec.rb +35 -0
- data/examples/store-api/spec/routing/products_routing_spec.rb +35 -0
- data/examples/store-api/spec/spec_helper.rb +85 -0
- data/examples/store-api/spec/views/categories/edit.html.erb_spec.rb +18 -0
- data/examples/store-api/spec/views/categories/index.html.erb_spec.rb +19 -0
- data/examples/store-api/spec/views/categories/new.html.erb_spec.rb +18 -0
- data/examples/store-api/spec/views/categories/show.html.erb_spec.rb +14 -0
- data/examples/store-api/spec/views/products/edit.html.erb_spec.rb +24 -0
- data/examples/store-api/spec/views/products/index.html.erb_spec.rb +25 -0
- data/examples/store-api/spec/views/products/new.html.erb_spec.rb +24 -0
- data/examples/store-api/spec/views/products/show.html.erb_spec.rb +18 -0
- data/examples/store-api/vendor/assets/javascripts/.keep +0 -0
- data/examples/store-api/vendor/assets/stylesheets/.keep +0 -0
- data/lib/restspec.rb +38 -0
- data/lib/restspec/configuration.rb +43 -0
- data/lib/restspec/endpoints/dsl.rb +142 -0
- data/lib/restspec/endpoints/endpoint.rb +135 -0
- data/lib/restspec/endpoints/namespace.rb +89 -0
- data/lib/restspec/endpoints/network.rb +39 -0
- data/lib/restspec/endpoints/request.rb +11 -0
- data/lib/restspec/endpoints/response.rb +53 -0
- data/lib/restspec/requirements/dsl.rb +10 -0
- data/lib/restspec/requirements/requirement.rb +59 -0
- data/lib/restspec/rspec/api_helpers.rb +64 -0
- data/lib/restspec/rspec/api_macros.rb +126 -0
- data/lib/restspec/rspec/extras.rb +2 -0
- data/lib/restspec/rspec/matchers/api_matchers.rb +6 -0
- data/lib/restspec/rspec/matchers/be_like_schema.rb +18 -0
- data/lib/restspec/rspec/matchers/be_like_schema_array.rb +18 -0
- data/lib/restspec/rspec/matchers/have_header.rb +47 -0
- data/lib/restspec/rspec/matchers/have_status.rb +17 -0
- data/lib/restspec/rspec/matchers/include_where.rb +14 -0
- data/lib/restspec/rspec/shared_examples.rb +12 -0
- data/lib/restspec/schema/attribute.rb +31 -0
- data/lib/restspec/schema/attribute_example.rb +21 -0
- data/lib/restspec/schema/checker.rb +73 -0
- data/lib/restspec/schema/dsl.rb +36 -0
- data/lib/restspec/schema/schema.rb +21 -0
- data/lib/restspec/schema/schema_example.rb +28 -0
- data/lib/restspec/schema/types.rb +35 -0
- data/lib/restspec/schema/types/array_type.rb +34 -0
- data/lib/restspec/schema/types/basic_type.rb +35 -0
- data/lib/restspec/schema/types/boolean_type.rb +11 -0
- data/lib/restspec/schema/types/decimal_string_type.rb +32 -0
- data/lib/restspec/schema/types/decimal_type.rb +14 -0
- data/lib/restspec/schema/types/embedded_schema_type.rb +28 -0
- data/lib/restspec/schema/types/hash_type.rb +25 -0
- data/lib/restspec/schema/types/integer_type.rb +11 -0
- data/lib/restspec/schema/types/null_type.rb +11 -0
- data/lib/restspec/schema/types/one_of_type.rb +21 -0
- data/lib/restspec/schema/types/schema_id_type.rb +88 -0
- data/lib/restspec/schema/types/string_type.rb +11 -0
- data/lib/restspec/shortcuts.rb +8 -0
- data/lib/restspec/stores/endpoint_store.rb +25 -0
- data/lib/restspec/stores/namespace_store.rb +20 -0
- data/lib/restspec/stores/schema_store.rb +19 -0
- data/lib/restspec/values/status_code.rb +13 -0
- data/lib/restspec/values/super_hash.rb +12 -0
- data/lib/restspec/version.rb +3 -0
- data/restspec.gemspec +37 -0
- data/spec/restspec/endpoints/dsl_spec.rb +269 -0
- data/spec/restspec/endpoints/endpoint_spec.rb +146 -0
- data/spec/restspec/endpoints/namespace_spec.rb +143 -0
- data/spec/restspec/endpoints/response_spec.rb +49 -0
- data/spec/restspec/schema/attribute_example_spec.rb +35 -0
- data/spec/restspec/schema/dsl_spec.rb +78 -0
- data/spec/restspec/schema/schema_example_spec.rb +40 -0
- data/spec/restspec/schema/schema_spec.rb +11 -0
- data/spec/restspec/schema/types/array_type_spec.rb +56 -0
- data/spec/restspec/schema/types/basic_type_spec.rb +62 -0
- data/spec/restspec/schema/types/boolean_type_spec.rb +26 -0
- data/spec/restspec/schema/types/null_type_spec.rb +25 -0
- data/spec/restspec/schema/types/string_type_spec.rb +26 -0
- data/spec/restspec/values/status_code_spec.rb +13 -0
- data/spec/spec_helper.rb +23 -0
- metadata +484 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module Restspec::Schema::Types
|
2
|
+
class HashType < BasicType
|
3
|
+
def example_for(attribute)
|
4
|
+
{}
|
5
|
+
end
|
6
|
+
|
7
|
+
def valid?(attribute, value)
|
8
|
+
is_hash = value.is_a?(Hash)
|
9
|
+
keys = schema_options.fetch(:keys, [])
|
10
|
+
|
11
|
+
if keys.empty?
|
12
|
+
is_hash
|
13
|
+
else
|
14
|
+
value_type = schema_options.fetch(:value_type, nil)
|
15
|
+
|
16
|
+
is_hash && keys.all? do |key|
|
17
|
+
has_key = value.has_key?(key)
|
18
|
+
if has_key && value_type
|
19
|
+
has_key && value_type.totally_valid?(attribute, value[key])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Restspec::Schema::Types
|
2
|
+
class OneOfType < BasicType
|
3
|
+
def example_for(attribute)
|
4
|
+
elements.sample
|
5
|
+
end
|
6
|
+
|
7
|
+
def valid?(attribute, value)
|
8
|
+
elements.include?(value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"OneOfType(#{elements})"
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def elements
|
18
|
+
options.fetch(:elements)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Restspec::Schema::Types
|
2
|
+
class SchemaIdType < BasicType
|
3
|
+
attr_accessor :schema_name
|
4
|
+
|
5
|
+
def initialize(options, options_when_name_is_present = {})
|
6
|
+
if options.is_a?(Symbol)
|
7
|
+
self.schema_name = options
|
8
|
+
super(options_when_name_is_present)
|
9
|
+
else
|
10
|
+
super(options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def example_for(attribute)
|
15
|
+
return sample_item.id if sample_item.present?
|
16
|
+
|
17
|
+
if create_response.code == 201 && create_response.body.try(:id)
|
18
|
+
create_response.body.id
|
19
|
+
else
|
20
|
+
example_options.fetch(:hardcoded_fallback) {
|
21
|
+
raise "We couldn't fetch any information for this example"
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid?(attribute, value)
|
27
|
+
return true unless perform_validation?
|
28
|
+
item_ids.any? { |item| item.id == value }
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def find_endpoint(name)
|
34
|
+
Restspec::EndpointStore.get(name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def sample_item
|
38
|
+
@sample_item ||= get_sample_item
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_index_endpoint
|
42
|
+
if schema_name.present?
|
43
|
+
Restspec::EndpointStore.get_by_schema_and_name(schema_name, :index)
|
44
|
+
else
|
45
|
+
find_endpoint(example_options.fetch(:fetch_endpoint))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_sample_item
|
50
|
+
fetch_endpoint = get_index_endpoint
|
51
|
+
fetch_endpoint.execute.body.try(:sample)
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_response
|
55
|
+
create_endpoint.execute(body: create_example)
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_create_endpoint
|
59
|
+
if schema_name.present?
|
60
|
+
namespace = Restspec::Endpoints::Namespace.get_by_schema_name(schema_name)
|
61
|
+
namespace.get_endpoint(:create)
|
62
|
+
else
|
63
|
+
find_endpoint(example_options.fetch(:create_endpoint))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_endpoint
|
68
|
+
@create_endpoint ||= get_create_endpoint
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_example
|
72
|
+
Restspec.example_for(create_schema_name)
|
73
|
+
end
|
74
|
+
|
75
|
+
def create_schema_name
|
76
|
+
example_options.fetch(:create_schema, create_endpoint.schema_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
def perform_validation?
|
80
|
+
schema_options.fetch(:perform_validation, true)
|
81
|
+
end
|
82
|
+
|
83
|
+
def item_ids
|
84
|
+
fetch_endpoint = get_index_endpoint
|
85
|
+
fetch_endpoint.execute.body
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Restspec
|
4
|
+
module Stores
|
5
|
+
class EndpointStoreDelegator < SimpleDelegator
|
6
|
+
def store(endpoint)
|
7
|
+
self[endpoint.full_name] = endpoint
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(endpoint_name)
|
11
|
+
self[endpoint_name]
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_by_schema_and_name(schema_name, endpoint_name)
|
15
|
+
values.find do |endpoint|
|
16
|
+
endpoint.schema_name == schema_name && endpoint.name == endpoint_name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
EndpointStore = EndpointStoreDelegator.new(Hash.new)
|
22
|
+
end
|
23
|
+
|
24
|
+
EndpointStore = Stores::EndpointStore
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Restspec
|
4
|
+
module Stores
|
5
|
+
class NamespaceStoreDelegator < SimpleDelegator
|
6
|
+
def store(namespace)
|
7
|
+
self << namespace
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(namespace_name)
|
11
|
+
possible_names = [namespace_name.to_s, namespace_name.to_sym]
|
12
|
+
find { |ns| possible_names.include?(ns.name) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
NamespaceStore = NamespaceStoreDelegator.new(Array.new)
|
17
|
+
end
|
18
|
+
|
19
|
+
NamespaceStore = Stores::NamespaceStore
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Restspec
|
4
|
+
module Stores
|
5
|
+
class SchemaStoreDelegator < SimpleDelegator
|
6
|
+
def store(schema)
|
7
|
+
self[schema.name] = schema
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(schema_name)
|
11
|
+
self[schema_name]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
SchemaStore = SchemaStoreDelegator.new(Hash.new)
|
16
|
+
end
|
17
|
+
|
18
|
+
SchemaStore = Stores::SchemaStore
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
|
3
|
+
module Restspec
|
4
|
+
module Values
|
5
|
+
class SuperHash < Hash
|
6
|
+
include Hashie::Extensions::MethodAccess
|
7
|
+
include Hashie::Extensions::DeepMerge
|
8
|
+
include Hashie::Extensions::IndifferentAccess
|
9
|
+
include Hashie::Extensions::MergeInitializer
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/restspec.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'restspec/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "restspec"
|
8
|
+
spec.version = Restspec::VERSION
|
9
|
+
spec.authors = ["juliogarciag"]
|
10
|
+
spec.email = ["julioggonz@gmail.com"]
|
11
|
+
spec.summary = %q{RSpec macros, helpers and matchers to work with APIs}
|
12
|
+
spec.description = %q{RSpec macros, helpers and matchers to work with APIs}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = ['restspec']
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
24
|
+
spec.add_development_dependency "guard", "~> 2.8"
|
25
|
+
spec.add_development_dependency "guard-rspec", "~> 4.3"
|
26
|
+
spec.add_development_dependency "rspec-nc", "~> 0.2"
|
27
|
+
spec.add_development_dependency "simplecov", "~> 0.9.1"
|
28
|
+
spec.add_dependency "activesupport", "~> 4.0"
|
29
|
+
spec.add_dependency "faker", "~> 1.4"
|
30
|
+
spec.add_dependency "hashie", "~> 3.3"
|
31
|
+
spec.add_dependency "rack", "~> 1.0"
|
32
|
+
spec.add_dependency "rspec", "~> 3.0"
|
33
|
+
spec.add_dependency "httparty", "~> 0.13"
|
34
|
+
spec.add_dependency "rspec-its", "~> 1.0"
|
35
|
+
spec.add_dependency "rspec-collection_matchers", "~> 1.0"
|
36
|
+
spec.add_dependency "thor", "~> 0.19"
|
37
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Restspec::Endpoints::DSL do
|
4
|
+
let(:dsl) { Restspec::Endpoints::DSL.new }
|
5
|
+
|
6
|
+
before do
|
7
|
+
Restspec::NamespaceStore.clear
|
8
|
+
Restspec::EndpointStore.clear
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#namespace' do
|
12
|
+
it 'creates a namespace' do
|
13
|
+
expect do
|
14
|
+
dsl.namespace(:monkey) { }
|
15
|
+
end.to change { Restspec::NamespaceStore.size }.by(1)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'creates a namespace with the given name as a string' do
|
19
|
+
dsl.namespace(:monkey) { }
|
20
|
+
expect(Restspec::NamespaceStore.first.name).to eq('monkey')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'creates a namespace with the given base_path' do
|
24
|
+
dsl.namespace(:monkey, base_path: '/monkey') { }
|
25
|
+
expect(Restspec::NamespaceStore.first.full_base_path).to eq('/monkey')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'yields a Restspec::Endpoints::NamespaceDSL attached to the namespace to the block' do
|
29
|
+
namespace_dsl = OpenStruct.new(call: true)
|
30
|
+
|
31
|
+
allow(namespace_dsl).to receive(:call).and_return(true)
|
32
|
+
allow(Restspec::Endpoints::NamespaceDSL).to receive(:new) do |namespace|
|
33
|
+
namespace_dsl.namespace = namespace
|
34
|
+
namespace_dsl
|
35
|
+
end
|
36
|
+
|
37
|
+
dsl.namespace(:monkey) do
|
38
|
+
self.call
|
39
|
+
end
|
40
|
+
|
41
|
+
expect(namespace_dsl).to have_received(:call)
|
42
|
+
expect(namespace_dsl.namespace).to eq(Restspec::NamespaceStore.first)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#resource' do
|
47
|
+
it 'creates a namespace with the base_path equals to /:name' do
|
48
|
+
dsl.resource(:monkeys) { }
|
49
|
+
expect(Restspec::NamespaceStore.first.full_base_path).to eq('/monkeys')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'creates a namespace with the schema attached to some schema with the same name' do
|
53
|
+
dsl.resource(:monkeys) { }
|
54
|
+
expect(Restspec::NamespaceStore.first.schema_name).to eq(:monkey)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe Restspec::Endpoints::NamespaceDSL do
|
59
|
+
let(:namespace) { Restspec::Endpoints::Namespace.new(:monkeys) }
|
60
|
+
let(:ns_dsl) { Restspec::Endpoints::NamespaceDSL.new(namespace) }
|
61
|
+
|
62
|
+
describe '#endpoint' do
|
63
|
+
it 'creates an endpoint for the namespace' do
|
64
|
+
expect do
|
65
|
+
ns_dsl.endpoint(:show) { }
|
66
|
+
end.to change { Restspec::EndpointStore.size }.by(1)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'creates an endpoint with the full name of the endpoint' do
|
70
|
+
ns_dsl.endpoint(:show) { }
|
71
|
+
expect(Restspec::EndpointStore.get("monkeys/show")).to be_present
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'HTTP_METHODS calls' do
|
76
|
+
Restspec::Endpoints::HTTP_METHODS.each do |http_method|
|
77
|
+
describe "##{http_method}" do
|
78
|
+
it "creates an endpoint with the method set to #{http_method} and the correct path" do
|
79
|
+
ns_dsl.send(http_method, :show, '/hola')
|
80
|
+
endpoint = Restspec::EndpointStore.get("monkeys/show")
|
81
|
+
expect(endpoint.method).to eq(http_method)
|
82
|
+
expect(endpoint.path).to eq('/hola')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#schema' do
|
89
|
+
it 'sets the schema_name of the namespace' do
|
90
|
+
expect do
|
91
|
+
ns_dsl.schema :schema_name
|
92
|
+
end.to change { namespace.schema_name }.to(:schema_name)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#all' do
|
97
|
+
it 'calls the same block in all the endpoints inside' do
|
98
|
+
ns_dsl.all do
|
99
|
+
schema :a_schema_name
|
100
|
+
end
|
101
|
+
|
102
|
+
ns_dsl.endpoint(:a) { }
|
103
|
+
ns_dsl.endpoint(:b) { }
|
104
|
+
|
105
|
+
endpoint_a = Restspec::EndpointStore.get('monkeys/a')
|
106
|
+
endpoint_b = Restspec::EndpointStore.get('monkeys/b')
|
107
|
+
|
108
|
+
expect(endpoint_a.schema_name).to eq(:a_schema_name)
|
109
|
+
expect(endpoint_b.schema_name).to eq(:a_schema_name)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '#url_param' do
|
114
|
+
it 'sets the url_params in each endpoint' do
|
115
|
+
ns_dsl.url_param(:param) { 'value' }
|
116
|
+
|
117
|
+
ns_dsl.endpoint(:a) { }
|
118
|
+
ns_dsl.endpoint(:b) { }
|
119
|
+
|
120
|
+
Restspec::EndpointStore.each do |_, endpoint|
|
121
|
+
expect(endpoint.url_params[:param]).to eq('value')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe 'resource sub-methods' do
|
127
|
+
let(:namespace) do
|
128
|
+
dsl.resource(:monkeys) { }
|
129
|
+
Restspec::NamespaceStore.get(:monkeys)
|
130
|
+
end
|
131
|
+
|
132
|
+
shared_examples :anonymous_namespace_method do |method_name|
|
133
|
+
it 'does not adds itself to the NamespaceStore' do
|
134
|
+
expect do
|
135
|
+
ns_dsl.send(method_name) { }
|
136
|
+
end.to_not change { Restspec::EndpointStore.size }
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'creates a namespace inside the parent namespace' do
|
140
|
+
expect do
|
141
|
+
ns_dsl.send(method_name) { }
|
142
|
+
end.to change { namespace.children_namespaces.size }.by(1)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'creates an anonymous namespace' do
|
146
|
+
ns_dsl.send(method_name) { }
|
147
|
+
expect(namespace.children_namespaces.first).to be_anonymous
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe '#member' do
|
152
|
+
it 'adds a namespace that attaches the namespace parent base_path and the /:id path to the endpoints inside' do
|
153
|
+
ns_dsl.member do
|
154
|
+
endpoint(:a) { }
|
155
|
+
endpoint(:b) { path '/home' }
|
156
|
+
end
|
157
|
+
|
158
|
+
expect(Restspec::EndpointStore.get("monkeys/a").full_path).to eq('/monkeys/:id')
|
159
|
+
expect(Restspec::EndpointStore.get("monkeys/b").full_path).to eq('/monkeys/:id/home')
|
160
|
+
end
|
161
|
+
|
162
|
+
it_behaves_like :anonymous_namespace_method, :member
|
163
|
+
end
|
164
|
+
|
165
|
+
describe '#collection' do
|
166
|
+
it 'adds a namespace that attaches the previous base_path to the current path' do
|
167
|
+
ns_dsl.collection do
|
168
|
+
endpoint(:a) { }
|
169
|
+
endpoint(:b) { path '/home' }
|
170
|
+
end
|
171
|
+
|
172
|
+
expect(Restspec::EndpointStore.get("monkeys/a").full_path).to eq('/monkeys')
|
173
|
+
expect(Restspec::EndpointStore.get("monkeys/b").full_path).to eq('/monkeys/home')
|
174
|
+
end
|
175
|
+
|
176
|
+
it_behaves_like :anonymous_namespace_method, :collection
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe Restspec::Endpoints::EndpointDSL do
|
182
|
+
let(:endpoint) { Restspec::Endpoints::Endpoint.new }
|
183
|
+
let(:endpoint_dsl) { Restspec::Endpoints::EndpointDSL.new(endpoint) }
|
184
|
+
|
185
|
+
describe '#method' do
|
186
|
+
it 'sets the method of the endpoint' do
|
187
|
+
expect { endpoint_dsl.method :get }.to change { endpoint.method }.to(:get)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe '#path' do
|
192
|
+
it 'sets the path of the endpoint' do
|
193
|
+
expect {
|
194
|
+
endpoint_dsl.path '/hola'
|
195
|
+
}.to change { endpoint.full_path }.from(nil).to('/hola')
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe '#schema' do
|
200
|
+
it 'sets the schema_name' do
|
201
|
+
expect {
|
202
|
+
endpoint_dsl.schema :monkey
|
203
|
+
}.to change { endpoint.schema_name }.from(nil).to(:monkey)
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'sets the schema_name with schema_extensions' do
|
207
|
+
extensions = { a: 1, b: 2, c: 3 }
|
208
|
+
|
209
|
+
expect {
|
210
|
+
endpoint_dsl.schema :monkey, extensions
|
211
|
+
}.to change { endpoint.schema_extensions }.from(nil).to(extensions)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe '#headers' do
|
216
|
+
it 'changes the headers of the endpoint' do
|
217
|
+
expect do
|
218
|
+
endpoint_dsl.headers['hola'] = 'mundo'
|
219
|
+
end.to change { endpoint.headers['hola'] }.from(nil).to('mundo')
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe '#url_param' do
|
224
|
+
context 'with a block returning a raw value' do
|
225
|
+
it 'adds the raw param to the endpoint' do
|
226
|
+
endpoint_dsl.url_param(:param) { 'param' }
|
227
|
+
expect(endpoint.url_params).to have_key(:param)
|
228
|
+
expect(endpoint.url_params[:param]).to eq('param')
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'with a block returning a schema type' do
|
233
|
+
let(:type) { Restspec::Schema::Types::StringType.new }
|
234
|
+
|
235
|
+
before do
|
236
|
+
allow(type).to receive(:example_for).and_return('')
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'executes example_for in the type' do
|
240
|
+
type = self.type
|
241
|
+
|
242
|
+
endpoint_dsl.url_param(:param) { type }
|
243
|
+
found_param = endpoint.url_params[:param]
|
244
|
+
|
245
|
+
expect(type).to have_received(:example_for)
|
246
|
+
expect(found_param).to eq('')
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'when the endpoint has a schema' do
|
250
|
+
let(:schema) { double(attributes: { param: 1 }) }
|
251
|
+
|
252
|
+
before do
|
253
|
+
allow(endpoint).to receive(:schema).and_return(schema)
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'calls the example_for with the attribute from the schema' do
|
257
|
+
type = self.type
|
258
|
+
|
259
|
+
endpoint_dsl.url_param(:param) { type }
|
260
|
+
found_param = endpoint.url_params[:param]
|
261
|
+
|
262
|
+
expect(type).to have_received(:example_for).with(1)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|