rspec-api 0.0.1 → 0.0.2

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: 302b0ee6e8cfaf3d3e65b088f190e1c36cd210af
4
- data.tar.gz: 4f27c81817901a1108c8d0fc6e28706fcb06cecd
3
+ metadata.gz: 80ddaf39a5b7ad64bec2e973e89771183f139ed2
4
+ data.tar.gz: c5b3280cd6f9b23bd127fd43db4487ded01c8a9c
5
5
  SHA512:
6
- metadata.gz: f15362494296d9866eaba1fc49100e7f2031ab78cd8a76d26336851909ea1a65f5fd273379a573e527e88f1dec62180575b4b38ee8ba9eaf9014c0e9bbe61341
7
- data.tar.gz: 6d94a2b103b77e0fd61affaac2a48c89fcea87731237fc2f5e7709772228cdfee7d5da4278c37ed494b4911cab056c9c5ac7b524fdbca760dfbfee9394c4cfa1
6
+ metadata.gz: fe877acbc40ca26a6dde50984ce03c62a485d7833fc2c175389a323a74debb9c189fd531a120cb83cf8541d8e6461afefeb36a43954a4a8d208ad9520e35f52a
7
+ data.tar.gz: d80f970b130815b361bac32f81f6d4623ae6345a514c6a0917a709596fc066bea127f6a1e2fbc112b6cf5597c33ab1e273972fadc5da1887ed8cfbe1391ed728
@@ -1,6 +1,4 @@
1
- Copyright (c) 2013 claudiob
2
-
3
- MIT License
1
+ Copyright 2013 claudiob
4
2
 
5
3
  Permission is hereby granted, free of charge, to any person obtaining
6
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,29 +1,2 @@
1
- # Rspec::Api
1
+ # RSpec API
2
2
 
3
- TODO: Write a gem description
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'rspec-api'
10
-
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
16
-
17
- $ gem install rspec-api
18
-
19
- ## Usage
20
-
21
- TODO: Write usage instructions here
22
-
23
- ## Contributing
24
-
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
@@ -0,0 +1,59 @@
1
+ def accepts(options = {}, &block)
2
+ parameters = block_given? ? options.merge(block: block) : options
3
+ (metadata[:query_parameters] ||= []).push parameters
4
+ end
5
+
6
+ RSpec::Matchers.define :be_sorted_by do |attribute|
7
+ match do |items|
8
+ values = items.map{|item| item[attribute.to_s]}
9
+ values.reverse! if example.metadata[:request_params][:sort][0] == '-'
10
+ values == values.sort
11
+ end
12
+ end
13
+
14
+ def assert_pagination_links
15
+ expect(response_headers).to have_key 'Link'
16
+ links = response_headers['Link'].split(',')
17
+ rels = links.map{|link| link[/<.+?>; rel="(.*)"$/, 1]}
18
+ expect(rels).to match_array ['last', 'next']
19
+ end
20
+
21
+ def query_parameters_requests
22
+ metadata.fetch(:query_parameters, []).map do |params|
23
+ if params.has_key? :filter
24
+ filter_parameters_requests params
25
+ elsif params.has_key? :sort
26
+ sort_parameters_requests params
27
+ elsif params.has_key? :page
28
+ page_parameters_requests params
29
+ end
30
+ end.flatten
31
+ end
32
+
33
+ def filter_parameters_requests(params)
34
+ params.except(:given, :block).tap do |req|
35
+ value = params.fetch :given, apply(:as_json, to: existing(params[:on]))
36
+ req[:description] = " filtered by #{params[:filter]}"
37
+ req[:request_params] = {params[:filter] => value}
38
+ req[:block] = params[:block]
39
+ end
40
+ end
41
+
42
+ def sort_parameters_requests(params)
43
+ [true, false].map do |ascending|
44
+ params.except(:block).tap do |req|
45
+ req[:description] = " sorted by #{params[:sort]} #{ascending ? '↑' : '↓'}"
46
+ req[:request_params] = {sort: "#{ascending ? '' : '-'}#{params[:sort]}"}
47
+ req[:block] = params[:block]
48
+ end
49
+ end
50
+ end
51
+
52
+ def page_parameters_requests(params)
53
+ {}.tap do |req|
54
+ req[:description] = " paginated by #{params[:page]}"
55
+ (req[:request_params] = {})[params[:page]] = 1
56
+ req[:min_pages] = 2
57
+ req[:block] = -> _ { assert_pagination_links }
58
+ end
59
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: UTF-8
2
+ shared_context 'accept_json', accepts: :json do
3
+ header 'Accept', 'application/json'
4
+ end
5
+
6
+ shared_context 'return_json', returns: :json do
7
+ after { expect(json_response?) }
8
+ end
9
+
10
+ def request(description, request_params = {})
11
+ default_request = {}
12
+ example_requests = [default_request]
13
+ example_requests.concat query_parameters_requests if metadata[:array]
14
+
15
+ example_requests.each do |request_metadata|
16
+ (request_metadata[:description] ||= '').prepend description
17
+ (request_metadata[:request_params] ||= {}).merge! request_params
18
+ metadata.merge! request_metadata
19
+ yield if block_given?
20
+ end
21
+ end
22
+
23
+ def request_params
24
+ example.metadata[:request_params]
25
+ end
26
+
27
+ def respond_with(expected_status, &block)
28
+ description = metadata[:description]
29
+ example description do
30
+ setup_instances
31
+ evaluate_request_params!
32
+ do_request request_params.dup
33
+ assert_response expected_status, &example.metadata.fetch(:block, block)
34
+ end
35
+ end
36
+
37
+ def assert_response(expected_status, &block)
38
+ assert_status expected_status
39
+ if block_given? || success? && returns_content?
40
+ json = JSON response_body
41
+ assert_attributes json if success?
42
+ assert_instances json
43
+ instance_exec(json, &block) if block_given?
44
+ end
45
+ end
46
+
47
+ def evaluate_request_params!
48
+ request_params.each do |name, value|
49
+ request_params[name] = instance_exec(&value) if value.is_a? Proc
50
+ end
51
+ end
52
+
53
+ def success?
54
+ status < 400
55
+ end
56
+
57
+ def returns_content?
58
+ [100, 101, 102, 204, 205, 304].exclude? status
59
+ end
60
+
61
+ def assert_status(expected_status)
62
+ expect(status).to be Rack::Utils.status_code(expected_status)
63
+ end
64
+
65
+ def json_response?
66
+ response_headers['Content-Type'] == 'application/json; charset=utf-8'
67
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'rspec_api_documentation/dsl'
3
+
4
+ def has_attribute(name, type, options = {})
5
+ (metadata[:attributes] ||= {})[name] = options.merge(type: type)
6
+ end
7
+
8
+ def assert_attributes(json)
9
+ expect(json).to be_a (example.metadata[:array] ? Array : Hash)
10
+ example.metadata[:attributes].each do |name, options|
11
+ values = Array.wrap(json).map{|item| item[name.to_s]}
12
+ assert_attribute_types(values, options[:type], options[:can_be_nil])
13
+ end
14
+ end
15
+
16
+ def random_values_for_attributes
17
+ {}.tap do |values|
18
+ example.metadata[:attributes].each do |name, options|
19
+ can_be_nil = options[:can_be_nil] && (name != example.metadata[:on])
20
+ values[name] = random_attribute_value options.merge(can_be_nil: can_be_nil)
21
+ end
22
+ end
23
+ end
24
+
25
+ def random_attribute_value(options)
26
+ if options[:can_be_nil] && [true, false].sample
27
+ nil
28
+ else
29
+ case options[:type]
30
+ when :string then [*('a'..'z'), *('A'..'Z')].sample(Random.rand 32).join
31
+ when :integer then Random.rand(2**16)
32
+ when :url then "http://example.com/#{SecureRandom.urlsafe_base64}"
33
+ end
34
+ end
35
+ end
36
+
37
+ def assert_attribute_types(values, expected_type, can_be_nil)
38
+ values.compact! if can_be_nil
39
+ expect(values).to all_match_type expected_type
40
+ end
41
+
42
+ def matches_type?(value, type)
43
+ case type
44
+ when :url then value =~ URI::regexp
45
+ else value.is_a? type.to_s.classify.constantize
46
+ end
47
+ end
48
+
49
+ RSpec::Matchers.define :all_match_type do |type|
50
+ match do |values|
51
+ values.all? {|value| matches_type? value, type}
52
+ end
53
+ end
@@ -0,0 +1,55 @@
1
+ def existing(key)
2
+ metadata[:description_attribute] = 'an existing'
3
+ -> { instances.any key }
4
+ end
5
+
6
+ def unknown(key)
7
+ metadata[:description_attribute] = 'an unknown'
8
+ -> { instances.none key }
9
+ end
10
+
11
+ def apply(method_name, options = {})
12
+ proc = options[:to]
13
+ -> { proc.call.send method_name }
14
+ end
15
+
16
+ def with(request_params = {})
17
+ request_params[:attribute] ||= metadata.delete :description_attribute
18
+ request description_for(request_params), request_params, &Proc.new
19
+ end
20
+
21
+ def no_params
22
+ {}
23
+ end
24
+
25
+ def valid(request_params)
26
+ request_params.merge attribute: 'an valid'
27
+ end
28
+
29
+ def invalid(request_params)
30
+ request_params.merge attribute: 'an invalid'
31
+ end
32
+
33
+ def description_for(request_params = {})
34
+ [description_verb, description_object(request_params)].join ' '
35
+ end
36
+
37
+ def description_verb
38
+ case metadata[:method]
39
+ when :get then 'Getting'
40
+ when :post then 'Creating'
41
+ when :put then 'Updating'
42
+ when :delete then 'Deleting'
43
+ end
44
+ end
45
+
46
+ def description_object(request_params = {})
47
+ attribute = request_params.delete :attribute
48
+ if metadata[:array]
49
+ "a list of #{metadata[:resource_name]}".tap do |objects|
50
+ objects << " by #{request_params.keys.join(', ')}" if request_params.any?
51
+ end
52
+ else
53
+ [attribute, metadata[:resource_name].singularize].join ' '
54
+ end.downcase
55
+ end
@@ -0,0 +1,8 @@
1
+ require 'rspec_api_documentation'
2
+ require 'rspec_api_documentation/dsl'
3
+
4
+ require 'rspec-api/accept_helper'
5
+ require 'rspec-api/attributes_helper'
6
+ require 'rspec-api/description_helper'
7
+ require 'rspec-api/api_helper'
8
+ require 'rspec-api/instances_helper'
@@ -0,0 +1,37 @@
1
+ def setup_instances
2
+ instances.create random_values_for_attributes
3
+ instances.create random_values_for_attributes
4
+ stub_instances_total_pages example.metadata[:min_pages]
5
+ end
6
+
7
+ def instances
8
+ example.metadata[:resource_name].singularize.constantize
9
+ end
10
+
11
+ def assert_instances(json)
12
+ expect(json).not_to be_empty
13
+ end
14
+
15
+ def existing(key)
16
+ -> { instances.pluck(key).first }
17
+ end
18
+
19
+ def unknown(key)
20
+ keys = 0.downto(-Float::INFINITY).lazy
21
+ -> { keys.reject {|value| instances.exists? key => value}.first }
22
+ end
23
+
24
+ def apply(method_name, options = {})
25
+ proc = options[:to]
26
+ -> { proc.call.send method_name }
27
+ end
28
+
29
+ def stub_instances_total_pages(total_pages)
30
+ return unless instances.respond_to?(:page) and total_pages.present?
31
+ page_method = instances.method :page
32
+ instances.stub(:page) do |page|
33
+ page_method.call(page).tap do |proxy|
34
+ proxy.stub(:total_pages).and_return total_pages
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module RspecApi
2
+ VERSION = '0.0.2'
3
+ end
metadata CHANGED
@@ -1,59 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - claudiob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-28 00:00:00.000000000 Z
11
+ date: 2013-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: '1.3'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: '1.3'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
14
+ name: rspec-api-documentation
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - '>='
32
18
  - !ruby/object:Gem::Version
33
19
  version: '0'
34
- type: :development
20
+ type: :runtime
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
24
  - - '>='
39
25
  - !ruby/object:Gem::Version
40
26
  version: '0'
41
- description: Write a gem description
27
+ description: Helpers to write specs for web APIs
42
28
  email:
43
29
  - claudiob@gmail.com
44
30
  executables: []
45
31
  extensions: []
46
32
  extra_rdoc_files: []
47
33
  files:
48
- - .gitignore
49
- - Gemfile
50
- - LICENSE.txt
34
+ - lib/rspec-api/accept_helper.rb
35
+ - lib/rspec-api/api_helper.rb
36
+ - lib/rspec-api/attributes_helper.rb
37
+ - lib/rspec-api/description_helper.rb
38
+ - lib/rspec-api/dsl.rb
39
+ - lib/rspec-api/instances_helper.rb
40
+ - lib/rspec-api/version.rb
41
+ - MIT-LICENSE
51
42
  - README.md
52
- - Rakefile
53
- - lib/rspec/api.rb
54
- - lib/rspec/api/version.rb
55
- - rspec-api.gemspec
56
- homepage: ''
43
+ homepage: https://github.com/claudiob/rspec-api
57
44
  licenses:
58
45
  - MIT
59
46
  metadata: {}
@@ -65,16 +52,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
52
  requirements:
66
53
  - - '>='
67
54
  - !ruby/object:Gem::Version
68
- version: '0'
55
+ version: 1.9.0
69
56
  required_rubygems_version: !ruby/object:Gem::Requirement
70
57
  requirements:
71
58
  - - '>='
72
59
  - !ruby/object:Gem::Version
73
- version: '0'
60
+ version: 1.3.6
74
61
  requirements: []
75
62
  rubyforge_project:
76
- rubygems_version: 2.0.3
63
+ rubygems_version: 2.1.0
77
64
  signing_key:
78
65
  specification_version: 4
79
- summary: Write a gem summary
66
+ summary: Extends rspec_api_documentation with methods to write more compact and meaningful,
67
+ auto-documented specs for web APIs.
80
68
  test_files: []
69
+ has_rdoc:
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in rspec-api.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1 +0,0 @@
1
- require "bundler/gem_tasks"
data/lib/rspec/api.rb DELETED
@@ -1,7 +0,0 @@
1
- require "rspec/api/version"
2
-
3
- module Rspec
4
- module Api
5
- # Your code goes here...
6
- end
7
- end
@@ -1,5 +0,0 @@
1
- module Rspec
2
- module Api
3
- VERSION = "0.0.1"
4
- end
5
- end
data/rspec-api.gemspec DELETED
@@ -1,23 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'rspec/api/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "rspec-api"
8
- spec.version = Rspec::Api::VERSION
9
- spec.authors = ["claudiob"]
10
- spec.email = ["claudiob@gmail.com"]
11
- spec.description = %q{Write a gem description}
12
- spec.summary = %q{Write a gem summary}
13
- spec.homepage = ""
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
23
- end