versioned_blocks 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +85 -0
- data/Rakefile +2 -0
- data/lib/versioned_blocks.rb +87 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/versioned_blocks_spec.rb +137 -0
- data/versioned_blocks.gemspec +23 -0
- metadata +83 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MjRmZWFmZDUyZjRkMTc2NmJkYmU5ZDkyYjgzYmViZTZlMDUxZThiMA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YWFjNTdiNjllYzNiMzRjYTI3OTQ3NjY0ZDUyY2QxY2Y1ZTg1MDBhZg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZmNlODVjNGI0OGMzZjBmNTkwZTk3ZTYzNDAzYTZjMDFhODI2NjI2NWFhMGNl
|
10
|
+
NGNlYTM1ZjkxNmZlMTg4N2Q1NWJmMzhiMWU2OTQ1OGFmYTNjZjI5ZjhjMmE1
|
11
|
+
ODJjMmM3MTlhNTNmOTEzMzM1MjFhMDg4M2M5MTNhYzA1NTRmYzA=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NmUyYmRlZjA0NTNiMWZjNTg1NWI5YzM1ZjgxYzhlNDllOTU0YTYzZjQyZjYy
|
14
|
+
OTQxNjRjYWI2MzRmZTNjYmVhZTcwMGFhZTc5ZTVlZmU0NzcxNDMzMTE3MTgz
|
15
|
+
NjU0ODQ3YTUzOGJmZjhhODY3NjU3YTFjMTc4ZjczM2ZiOWQzNWM=
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
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
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 ddayal-fiksu
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# versioned_blocks
|
2
|
+
|
3
|
+
Are you working with versioned APIs? Loop through them easily like this:
|
4
|
+
|
5
|
+
VersionedBlocks.base_uri = 'http://www.api.com/'
|
6
|
+
|
7
|
+
versioned_block(from: 2, to: 4) do |v, uri|
|
8
|
+
puts "For version #{v}, the URI is #{uri}"
|
9
|
+
end
|
10
|
+
|
11
|
+
The block is passed the version number and a URI string formed from the base URI and the respective version number.
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
### Specifying ranges
|
16
|
+
|
17
|
+
You can specify version ranges in many ways:
|
18
|
+
- {from: 2, to: 4} would pass 2,3,4 to the block, resulting in "http://www.api.com/v2", "http://www.api.com/v3", "http://www.api.com/v4"
|
19
|
+
- {to: 3} would pass 1,2,3 to the block
|
20
|
+
- {only: 6} would pass just 6 to the block
|
21
|
+
- {these: [2,4,5]} would pass 2,4,5 to the block
|
22
|
+
|
23
|
+
You can config all blocks to run over a certain range by default, like this...
|
24
|
+
|
25
|
+
VersionedBlocks.versions = {from: 2, to: 4}
|
26
|
+
|
27
|
+
versioned_block {|v, uri| puts "URI: #{uri}"}
|
28
|
+
|
29
|
+
...and override a default range in a specific case like this:
|
30
|
+
|
31
|
+
versioned_block(only: 5, override: true) do |v, uri|
|
32
|
+
puts "For version #{v}, the URI is #{uri}"
|
33
|
+
end
|
34
|
+
|
35
|
+
### Error messages
|
36
|
+
|
37
|
+
If you're using a versioned_block inside a test, for example, you might want any error messages to include some information about the version number that the test broke on. Just configure VersionedBlocks like this:
|
38
|
+
|
39
|
+
VersionedBlocks.prepend_errors = true
|
40
|
+
|
41
|
+
### Configuring defaults
|
42
|
+
|
43
|
+
You can set your preferences like this...
|
44
|
+
|
45
|
+
VersionedBlocks.versions = {to: 5}
|
46
|
+
VersionedBlocks.base_uri = 'http://www.api.com/'
|
47
|
+
VersionedBlocks.prepend_errors = true
|
48
|
+
|
49
|
+
...and reset them all like this:
|
50
|
+
|
51
|
+
VersionedBlocks.reset
|
52
|
+
|
53
|
+
All configurations can be overridden in a specific case using `override: true`:
|
54
|
+
|
55
|
+
versioned_block(from: 1, to: 10, base_uri: 'http://new-api.com/', prepend_errors: false, override: true) do |v, uri|
|
56
|
+
puts "For version #{v}, the URI is now #{uri}"
|
57
|
+
end
|
58
|
+
|
59
|
+
You can also just override one of them - the others will use their default value:
|
60
|
+
|
61
|
+
versioned_block(from: 1, to: 10, override: true) do |v, uri|
|
62
|
+
puts "For version #{v}, the URI is still #{uri}"
|
63
|
+
end
|
64
|
+
|
65
|
+
## Installation
|
66
|
+
|
67
|
+
Add this line to your application's Gemfile:
|
68
|
+
|
69
|
+
gem 'versioned_blocks'
|
70
|
+
|
71
|
+
And then execute:
|
72
|
+
|
73
|
+
$ bundle
|
74
|
+
|
75
|
+
Or install it yourself as:
|
76
|
+
|
77
|
+
$ gem install versioned_blocks
|
78
|
+
|
79
|
+
## Contributing
|
80
|
+
|
81
|
+
1. Fork it ( https://github.com/[my-github-username]/versioned_blocks/fork )
|
82
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
83
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
84
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
85
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
class VersionedBlocks
|
2
|
+
VERSION = "1.0.1"
|
3
|
+
|
4
|
+
class << self
|
5
|
+
attr_accessor :versions, :base_uri, :prepend_errors
|
6
|
+
|
7
|
+
def reset
|
8
|
+
# set defaults
|
9
|
+
self.versions = {}
|
10
|
+
self.base_uri = ''
|
11
|
+
self.prepend_errors = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def base_uri_from_opts(opts)
|
15
|
+
# specify a base uri:
|
16
|
+
# base:'http://www.example.com/'
|
17
|
+
# or set a default base like:
|
18
|
+
# VersionedRetry.base = 'http://www.example.com/'
|
19
|
+
b = opts.has_key?(:base_uri) && (opts[:override]==true || self.base_uri=='') ? opts[:base_uri] : self.base_uri
|
20
|
+
raise('Empty base URI! Set VersionedBlock.base_uri or pass a :base_uri as an option') if b.nil? || b==''
|
21
|
+
b += '/' unless b[-1]=='/' # add a slash if it's missing
|
22
|
+
b = b[0..-2] if b[-2..-1]=='//' # get rid of trailing double slashes
|
23
|
+
b
|
24
|
+
end
|
25
|
+
|
26
|
+
def opts_specify_a_version?(opts)
|
27
|
+
opts.has_key?(:to) || (opts.has_key?(:to) && opts.has_key?(:from)) || opts.has_key?(:only) || opts.has_key?(:these)
|
28
|
+
end
|
29
|
+
|
30
|
+
def versions_from_opts(opts)
|
31
|
+
# specifying versioning:
|
32
|
+
# pass {only:1} to test only v1
|
33
|
+
# pass {to:3} to test v1,v2,v3
|
34
|
+
# pass {from:2, to:3} to test v2,v3
|
35
|
+
# pass {these:[1,2,4]} to test v1,v2,v4 but NOT v3
|
36
|
+
# you can set default versioning with:
|
37
|
+
# VersionedRetry.config = {}
|
38
|
+
# you can then override that default for a specifig case by passing:
|
39
|
+
# override:true
|
40
|
+
# or reset the default versioning with:
|
41
|
+
# VersionedRetry.reset
|
42
|
+
opts = opts_specify_a_version?(opts) || (opts[:override]==true && opts_specify_a_version?(opts)) ? opts : self.versions
|
43
|
+
#opts = self.versions unless (opts[:override]==true || self.versions == {})
|
44
|
+
if opts[:from].is_a?(Integer) && opts[:to].is_a?(Integer) # from vX to vY
|
45
|
+
raise "Expected :from (#{opts[:from]}) to be less than :to (#{opts[:to]})" if opts[:from] > opts[:to]
|
46
|
+
versions_to_test = (opts[:from]..opts[:to])
|
47
|
+
else
|
48
|
+
if opts[:to].is_a?(Integer) # up to vX
|
49
|
+
versions_to_test = (1..opts[:to])
|
50
|
+
elsif opts[:only].is_a?(Integer) # only vX
|
51
|
+
versions_to_test = [opts[:only]]
|
52
|
+
elsif opts[:these].is_a?(Array) # vX, vY, etc. for each of :these
|
53
|
+
if opts[:these].all?{|n| n.is_a?(Integer)}
|
54
|
+
versions_to_test = opts[:these]
|
55
|
+
else
|
56
|
+
raise "Each element in :these must be an integer"
|
57
|
+
end
|
58
|
+
else
|
59
|
+
raise "Couldn't determine which versions to test!\nUse :only, :these, :to, or :from and :to"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
versions_to_test
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
VersionedBlocks.reset
|
68
|
+
|
69
|
+
module Kernel
|
70
|
+
def versioned_block(opts = {}, &block)
|
71
|
+
versions_to_test = VersionedBlocks.versions_from_opts(opts)
|
72
|
+
if block.arity == 2 # if block is asking for the uri and the version
|
73
|
+
base_uri = VersionedBlocks.base_uri_from_opts(opts)
|
74
|
+
versions = versions_to_test.map{|num| [num, "#{base_uri}v#{num}"]}
|
75
|
+
else # just return the version
|
76
|
+
versions = versions_to_test.to_a
|
77
|
+
end
|
78
|
+
versions.each do |v, uri|
|
79
|
+
begin
|
80
|
+
block.call(v, uri)
|
81
|
+
rescue Exception=> e
|
82
|
+
e.message.prepend("When version = #{v}: ") if VersionedBlocks.prepend_errors || (opts[:override]==true && opts[:prepend_errors]==true)
|
83
|
+
raise e
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require_relative './spec_helper'
|
2
|
+
|
3
|
+
describe 'Versioned Blocks' do
|
4
|
+
context 'before any config' do
|
5
|
+
it 'has empty config, base_uri' do
|
6
|
+
expect(VersionedBlocks.versions).to eq({})
|
7
|
+
expect(VersionedBlocks.base_uri).to eq ''
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'prepend_errors' do
|
11
|
+
it 'is false' do
|
12
|
+
expect(VersionedBlocks.prepend_errors).to be false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context ':to' do
|
17
|
+
it 'counts up to x' do
|
18
|
+
count = 0
|
19
|
+
versioned_block(to:3) do |v|
|
20
|
+
count += 1
|
21
|
+
expect(v).to eq count
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context ':to, :from' do
|
27
|
+
before :all do
|
28
|
+
@x = 5
|
29
|
+
@y = 8
|
30
|
+
@count = @x - 1
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'counts from x to y' do
|
34
|
+
versioned_block(from:@x, to:@y) do |v|
|
35
|
+
@count += 1
|
36
|
+
expect(v).to eq @count
|
37
|
+
end
|
38
|
+
expect(@count).to eq @y
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'raises an error if :from > :to' do
|
42
|
+
begin
|
43
|
+
versioned_block(from:@y, to:@x) {}
|
44
|
+
expect(false).to be true
|
45
|
+
rescue Exception=>e
|
46
|
+
expect(e.class.to_s).to eq 'RuntimeError'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context ':these' do
|
52
|
+
before :all do
|
53
|
+
@nums = [1,2,5]
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'counts only the specified versions' do
|
57
|
+
versioned_block(these:@nums) do |v|
|
58
|
+
expect(@nums).to include v
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context ':only' do
|
64
|
+
before :all do
|
65
|
+
@num = 3
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'counts only the specified version' do
|
69
|
+
versioned_block(only:@num) do |v|
|
70
|
+
expect(@num).to eq v
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'after config' do
|
77
|
+
before :all do
|
78
|
+
@versions = {to:5}
|
79
|
+
@base_uri = 'http://www.google.com/'
|
80
|
+
@prepend_errors = true
|
81
|
+
VersionedBlocks.versions = @versions
|
82
|
+
VersionedBlocks.base_uri = @base_uri
|
83
|
+
VersionedBlocks.prepend_errors = @prepend_errors
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'has a specified version' do
|
87
|
+
expect(VersionedBlocks.versions).to eq @versions
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'has a specified uri' do
|
91
|
+
expect(VersionedBlocks.base_uri).to eq @base_uri
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'can override a default uri without specifying version' do
|
95
|
+
versioned_block(base_uri: 'test2.com', override: true) do |v, uri|
|
96
|
+
expect(uri).to include 'test2'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'can override a default uri and version' do
|
101
|
+
versioned_block(base_uri: 'test2.com', only:8, override: true) do |v, uri|
|
102
|
+
expect(uri).to include 'test2'
|
103
|
+
expect(v).to eq 8
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'prepends errors' do
|
108
|
+
expect(VersionedBlocks.prepend_errors).to eq @prepend_errors
|
109
|
+
begin
|
110
|
+
versioned_block do |v|
|
111
|
+
v + "can't do this!"
|
112
|
+
end
|
113
|
+
rescue Exception=>e
|
114
|
+
expect(e.message).to include "version"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'can return a version and a url' do
|
119
|
+
versioned_block do |v, uri|
|
120
|
+
expect(v).to be_a Integer
|
121
|
+
expect(uri).to be_a String
|
122
|
+
expect(uri).to include @base_uri
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'returns the default specified versions' do
|
127
|
+
versioned_block do |v|
|
128
|
+
count = 0
|
129
|
+
versioned_block do |v|
|
130
|
+
count += 1
|
131
|
+
expect(v).to eq count
|
132
|
+
end
|
133
|
+
expect(count).to eq @versions[:to]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'versioned_blocks'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "versioned_blocks"
|
8
|
+
spec.version = VersionedBlocks::VERSION
|
9
|
+
spec.authors = ["devend711@gmail.com"]
|
10
|
+
spec.email = ["devend711@gmail.com"]
|
11
|
+
spec.summary = "Easily loop through versioned API URIs"
|
12
|
+
#spec.description = %q{TODO: Write a longer description. Optional.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
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.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: versioned_blocks
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- devend711@gmail.com
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
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.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- devend711@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- lib/versioned_blocks.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
- spec/versioned_blocks_spec.rb
|
56
|
+
- versioned_blocks.gemspec
|
57
|
+
homepage: ''
|
58
|
+
licenses:
|
59
|
+
- MIT
|
60
|
+
metadata: {}
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
requirements: []
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 2.2.2
|
78
|
+
signing_key:
|
79
|
+
specification_version: 4
|
80
|
+
summary: Easily loop through versioned API URIs
|
81
|
+
test_files:
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
- spec/versioned_blocks_spec.rb
|