susanin 0.0.1 → 0.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: 59b6559ce5c0548853359a6ff22589bd05445937
4
- data.tar.gz: a4f94a1fe9eb848681f264855187ec0174b67e77
3
+ metadata.gz: de5f33ed26b6b589665db41aa026d814640bc551
4
+ data.tar.gz: c3e0d9dc34c3fbd77a8dabf00fb1cdbaa63175c3
5
5
  SHA512:
6
- metadata.gz: 3cca6bf0ac14d8bfdcaa7e9f80fa50f716164f79ad2082acc88f136a2601b4713b85efcb1d545c7c2b8a2155dce80cf66ceda200c20729b90599c9a49bf20c1d
7
- data.tar.gz: 8540146c20a09ef5caadb50a3047f8c90b3b1a57f5ba8df20c291f10dfbb3dbb359408703305ea9fded1375068972a84032612e19ae38b84433b1cbd524d3c50
6
+ metadata.gz: 5cf8df24f3d1229aadf4baa9232ca5979bfec499117af505a9a01f89ed9371bc5f36257b063d54aea81f735c67413b10555e4011d21fe26b9e2f9c0e4e831b09
7
+ data.tar.gz: 9b0279aee97e7635f3acfe218d83c74c13a558dba1958005b6b9281d9d1154ed2a8b9268c1f6829260d24f360a284b037073c24722da0fa15c35be2fa7b9d6f7
data/.cimon.yml ADDED
@@ -0,0 +1,39 @@
1
+ services:
2
+ ruby21:
3
+ from: ruby:2.1.8
4
+ cache:
5
+ - /bundle
6
+ build:
7
+ - gem install bundler
8
+ ruby22:
9
+ from: ruby:2.2.4
10
+ cache:
11
+ - /bundle
12
+ build:
13
+ - gem install bundler
14
+ ruby23:
15
+ from: ruby:2.3.0
16
+ cache:
17
+ - /bundle
18
+ build:
19
+ - gem install bundler
20
+
21
+ default: &default
22
+ prepare:
23
+ - bundle install --path /bundle
24
+ folder: /app
25
+ cmd: bin/rake
26
+ env:
27
+ - COVERAGE=true
28
+
29
+ test21:
30
+ <<: *default
31
+ service: ruby21
32
+
33
+ test22:
34
+ <<: *default
35
+ service: ruby22
36
+
37
+ test23:
38
+ <<: *default
39
+ service: ruby23
data/README.md CHANGED
@@ -24,12 +24,17 @@ By default gems do nothing. Include module 'susanin' to the controller.
24
24
  class ApplicationController < ActionController::Base
25
25
  include ::Susanin
26
26
 
27
- polymorphic_url_prefix do
28
- {
29
- Admin => ->(resource) { [resource.company, resource] },
30
- Photo => ->(resource) { [resource.admin.company, resource.admin, resource] },
31
- Gallery => ->(resource) { [resource.company, resource] }
32
- }
27
+ susanin do
28
+ [
29
+ [:owner, ->(r) { [:admin] }],
30
+ [[:frontend, Link], ->(r) { [:frontend, r] }],
31
+ [User, ->(r) { [:owner, r] }],
32
+ [Project, ->(r) { [:owner, r] }],
33
+ [Link, ->(r) { [:owner, r] }],
34
+ [Admin, ->(r) { [r.company, r] }],
35
+ [Photo, ->(r) { [r.admin.company, r.admin, r] }],
36
+ [Gallery, ->(r) { [r.company, r] }]
37
+ ]
33
38
  end
34
39
 
35
40
  end
@@ -47,7 +52,6 @@ You are able to write this:
47
52
  link_to user.email, [:edit, user], class: 'button'
48
53
  ```
49
54
 
50
-
51
55
  ## Contributing
52
56
 
53
57
  1. Fork it ( https://github.com/[my-github-username]/susanin/fork )
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
2
3
 
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "susanin"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
data/bin/rake ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require "pathname"
10
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require "rubygems"
14
+ require "bundler/setup"
15
+
16
+ load Gem.bin_path("rake", "rake")
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/susanin.rb CHANGED
@@ -1,45 +1,56 @@
1
+ require "active_support/core_ext/array"
2
+ require "active_support/concern"
3
+ require "active_support/dependencies/autoload"
1
4
  require "susanin/version"
2
5
 
3
6
  module Susanin
4
7
  extend ActiveSupport::Concern
5
8
 
9
+ autoload :Resource, 'susanin/resource'
10
+ autoload :Pattern, 'susanin/pattern'
11
+
6
12
  included do
7
- hide_action :polymorphic_url
8
- helper_method :polymorphic_url
13
+ hide_action :polymorphic_url, :polymorphic_path
14
+ helper_method :polymorphic_url, :polymorphic_path
9
15
  end
10
16
 
11
- class Resource
17
+ module ClassMethods
18
+ def susanin(content = nil, &block)
19
+ content_proc = block_given? ? Proc.new(&block) : Proc.new { content }
12
20
 
13
- def initialize(values={}, default = ->(resource) { resource })
14
- @resources = values.dup
15
- @resources.default = default
21
+ define_method :susanin do
22
+ @susanin ||= Resource.new(Array.wrap(instance_exec(&content_proc)))
23
+ end
16
24
  end
25
+ end
17
26
 
18
- def get(record)
19
- @resources[record.class][record]
20
- end
27
+ def polymorphic_url(record_or_hash_or_array, options={})
28
+ params = susanin_converter(record_or_hash_or_array, options)
21
29
 
30
+ if (params.first.size == 1) && params.first[0].is_a?(String)
31
+ params.first.first
32
+ else
33
+ super(*params)
34
+ end
22
35
  end
23
36
 
24
- module ClassMethods
25
- def polymorphic_url_prefix(content = nil)
26
- content_proc = if block_given?
27
- Proc.new
28
- else
29
- Proc.new { content }
30
- end
31
- define_method :polymorphic_url_prefix do
32
- @polymorphic_url_prefix ||= Resource.new(*Array.wrap(instance_exec(&content_proc)))
33
- end
37
+ def polymorphic_path(record_or_hash_or_array, options={})
38
+ params = susanin_converter(record_or_hash_or_array, options)
39
+
40
+ if (params.first.size == 1) && params.first[0].is_a?(String)
41
+ params.first.first
42
+ else
43
+ super(*params)
34
44
  end
35
45
  end
36
46
 
37
- def polymorphic_url(record_or_hash_or_array, options={})
38
- parameters = Array.wrap(record_or_hash_or_array).map {|i| polymorphic_url_prefix.get(i) }.flatten
39
- super(parameters, options)
47
+ def susanin_converter(record_or_hash_or_array, options={})
48
+ params = susanin.url_parameters(Array.wrap(record_or_hash_or_array))
49
+ params_options = params.extract_options!
50
+ [params, options.merge(params_options)]
40
51
  end
41
52
 
42
- def polymorphic_url_prefix
43
- @polymorphic_url_prefix ||= Resource.new()
53
+ def susanin
54
+ @susanin ||= Resource.new()
44
55
  end
45
56
  end
@@ -0,0 +1,37 @@
1
+ require "active_support/core_ext/array"
2
+
3
+ module Susanin
4
+
5
+ class Pattern
6
+ include Enumerable
7
+
8
+ def initialize(arr)
9
+ @arr = Array.wrap(arr)
10
+ end
11
+
12
+ def each(&block)
13
+ shifts.map do |s|
14
+ a = @arr.slice(*s)
15
+ block.call(a.size == 1 ? a[0] : a)
16
+ end
17
+ end
18
+
19
+ def arr_size
20
+ @arr.size
21
+ end
22
+
23
+ def shifts
24
+ arr_size.downto(1).flat_map do |shift|
25
+ (0).upto(arr_size-shift).map do |i|
26
+ [0+i, shift]
27
+ end
28
+ end
29
+ end
30
+
31
+ def inspect
32
+ map{|i|i}
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,209 @@
1
+ require "active_support/core_ext/array"
2
+ require "active_support/concern"
3
+
4
+ module Susanin
5
+
6
+ class Resource
7
+
8
+ def initialize(values=[])
9
+ @resources = values.dup
10
+ end
11
+
12
+ def url_parameters(record_or_hash_or_array, options={})
13
+ params = self.get(Array.wrap(record_or_hash_or_array)).flatten
14
+ merged_options(params, options={})
15
+ end
16
+
17
+ #
18
+ # get(
19
+ # [:a, :c, :d],
20
+ # [
21
+ # [[:A, :B], ->(r) {:a}]
22
+ # [[:A], ->(r) {:q}]
23
+ # [[:C], ->(r) {:w}]
24
+ # [[:E], ->(r) {:e}]
25
+ # ]
26
+ # )
27
+ #
28
+ # [:qwe, :wer, :d]
29
+ #
30
+ def get(record, resources=@resources)
31
+ new_record, new_resources = replace_with(Array.wrap(record), resources)
32
+ if record == new_record
33
+ new_record
34
+ else
35
+ get(new_record, new_resources)
36
+ end
37
+ end
38
+
39
+ #
40
+ # replace_with(
41
+ # [:a, :b, :c, :d],
42
+ # [
43
+ # [[:A, :B], ->(r) {:a}]
44
+ # [[:C], ->(r) {:w}]
45
+ # [[:E], ->(r) {:e}]
46
+ # ]
47
+ # )
48
+ #
49
+ # [
50
+ # [:a, :c, :d],
51
+ # [
52
+ # [[:C], ->(r) {:w}]
53
+ # [[:E], ->(r) {:e}]
54
+ # ]
55
+ # ]
56
+ #
57
+ def replace_with(record, resources)
58
+ record = record.dup
59
+ resources = resources.dup
60
+ pattern, converter = find_first_pattern(record, resources)
61
+
62
+ [replace_subrecord(record, pattern, converter), resources_except(resources, pattern)]
63
+ end
64
+
65
+ #
66
+ # find_first_pattern(
67
+ # [:a, :b, :c, :d],
68
+ # [
69
+ # [[:A, :B], ->(r) {:a}]
70
+ # [[:C], ->(r) {:w}]
71
+ # [[:E], ->(r) {:e}]
72
+ # ]
73
+ # )
74
+ #
75
+ # [[:A, :B], ->(r) {:a}]
76
+ #
77
+ def find_first_pattern(record, resources)
78
+ record_patterns = patterns(get_key(record))
79
+
80
+ resources.select do |r|
81
+ record_patterns.include?(r[0])
82
+ end.first || []
83
+ end
84
+
85
+ #
86
+ # resources_except(
87
+ # [
88
+ # [[:A, :B], ->(r) {:a}]
89
+ # [[:A], ->(r) {:q}]
90
+ # [[:C], ->(r) {:w}]
91
+ # [[:E], ->(r) {:e}]
92
+ # ],
93
+ # [:A, :B]
94
+ # )
95
+ #
96
+ # [
97
+ # [[:C], ->(r) {:w}]
98
+ # [[:E], ->(r) {:e}]
99
+ # ],
100
+ #
101
+ def resources_except(resources, keys)
102
+ keys = Array.wrap(keys)
103
+ new_resources = resources.dup
104
+ new_resources.reject! { |r| contains_subarray?(keys, Array.wrap(r[0])) }
105
+ new_resources
106
+ end
107
+
108
+ #
109
+ # get_key(a) => A
110
+ # get_key(A) => A
111
+ # get_key([a]) => [A]
112
+ # get_key([a, B]) => [A, B]
113
+ # get_key([A]) => [A]
114
+ # get_key([A]) => [A]
115
+ # get_key(:qwe) => :qwe
116
+ # get_key([:qwe]) => [:qwe]
117
+ # get_key('qwe') => 'qwe'
118
+ #
119
+ def get_key(record)
120
+ case record
121
+ when Class then record
122
+ when Array then record.map { |i| get_key(i) }
123
+ when Symbol then record
124
+ when String then record
125
+ else record.class
126
+ end
127
+ end
128
+
129
+ #
130
+ # merged_options([], {}) #=> []
131
+ # merged_options([a], {}) #=> [a]
132
+ # merged_options([a, {}], {}) #=> [a]
133
+ # merged_options([a, {a: 1}], {}) #=> [a, {a: 1}]
134
+ # merged_options([a, {}], {a: 1}) #=> [a, {a: 1}]
135
+ # merged_options([a, {a: 1}], {a: 2}) #=> [a, {a: 1}]
136
+ #
137
+ def merged_options(params, options={})
138
+ params = params.dup
139
+ default_options = params.extract_options!
140
+ params + ((default_options.any? || options.any?) ? [default_options.merge(options)] : [])
141
+ end
142
+
143
+ #
144
+ # contains_subarray?([1,2,3,4,5], [1,2,3]) => true
145
+ # contains_subarray?([1,2,3,4,5], [3,4]) => true
146
+ # contains_subarray?([1,2,3,4,5], [1,3,4]) => false
147
+ # contains_subarray?([1,2,3,4,5], 5) => true
148
+ #
149
+ def contains_subarray?(source, subarray)
150
+ source = Array.wrap(source)
151
+ subarray = Array.wrap(subarray)
152
+ iteration_count = source.length - subarray.length
153
+ 0.upto(iteration_count).any? do |i|
154
+ source[i..(i+subarray.length-1)] == subarray
155
+ end
156
+ end
157
+
158
+ def patterns(arr)
159
+ Pattern.new(arr)
160
+ end
161
+
162
+ #
163
+ # replace_subrecord(
164
+ # [:a, :b, :c, :a, :b, :b],
165
+ # [:a, :b],
166
+ # ->(){ '_1_' }
167
+ # )
168
+ #
169
+ # ['_1_', :c, '_1_', :b]
170
+ #
171
+ def replace_subrecord(record, pattern, resource)
172
+ record = record.dup
173
+ pattern = Array.wrap(pattern)
174
+
175
+ i = pattern.length
176
+
177
+ return record if i == 0
178
+
179
+ while i <= record.length do
180
+ set = (0+(i-pattern.length))..(i-1)
181
+ subset = record[set]
182
+
183
+ if pattern_match?(subset, pattern)
184
+ value = resource.call(*subset)
185
+ record[set] = value
186
+ i += Array.wrap(value).size
187
+ else
188
+ i += 1
189
+ end
190
+ end
191
+
192
+ record
193
+ end
194
+
195
+ #
196
+ # pattern_match?([a, b], [A, B]) => true
197
+ # pattern_match?([a, b], [a, b]) => false
198
+ #
199
+ def pattern_match?(record, pattern)
200
+ Array.wrap(get_key(record)) == Array.wrap(pattern)
201
+ end
202
+
203
+ def array_unwrap(a)
204
+ a.size == 1 ? a[0] : a
205
+ end
206
+
207
+ end
208
+
209
+ end
@@ -1,3 +1,3 @@
1
1
  module Susanin
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1"
3
3
  end
data/susanin.gemspec CHANGED
@@ -7,19 +7,22 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "susanin"
8
8
  spec.version = Susanin::VERSION
9
9
  spec.authors = ["Alexey Osipenko"]
10
- spec.email = ["alexey@osipenko.in.ua"]
10
+ spec.email = ["alexey@cimon.io"]
11
11
  spec.summary = %q{polymorphic_url extention to help with route generation}
12
12
  spec.description = %q{This gem simplify the route generation which generates via `polymorphic_url` method }
13
- spec.homepage = "https://github.com/aratak/susanin"
13
+ spec.homepage = "https://github.com/cimon-io/susanin"
14
14
  spec.license = "MIT"
15
15
 
16
- spec.files = `git ls-files -z`.split("\x0")
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "actionpack", "~> 4.1.1"
21
+ spec.add_dependency "actionpack", ">= 4.1.1", "< 5.0"
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.6"
24
- spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "bundler", "~> 1.11"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "pry"
26
+ spec.add_development_dependency "minitest", "~> 5.1"
27
+ spec.add_development_dependency "simplecov"
25
28
  end
metadata CHANGED
@@ -1,45 +1,93 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: susanin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: '0.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Osipenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-11 00:00:00.000000000 Z
11
+ date: 2016-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 4.1.1
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: 4.1.1
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: bundler
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '1.6'
39
+ version: '1.11'
34
40
  type: :development
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: '1.6'
46
+ version: '1.11'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '10.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: pry
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: minitest
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.1'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '5.1'
89
+ - !ruby/object:Gem::Dependency
90
+ name: simplecov
43
91
  requirement: !ruby/object:Gem::Requirement
44
92
  requirements:
45
93
  - - ">="
@@ -55,20 +103,29 @@ dependencies:
55
103
  description: 'This gem simplify the route generation which generates via `polymorphic_url`
56
104
  method '
57
105
  email:
58
- - alexey@osipenko.in.ua
59
- executables: []
106
+ - alexey@cimon.io
107
+ executables:
108
+ - console
109
+ - rake
110
+ - setup
60
111
  extensions: []
61
112
  extra_rdoc_files: []
62
113
  files:
114
+ - ".cimon.yml"
63
115
  - ".gitignore"
64
116
  - Gemfile
65
117
  - LICENSE.txt
66
118
  - README.md
67
119
  - Rakefile
120
+ - bin/console
121
+ - bin/rake
122
+ - bin/setup
68
123
  - lib/susanin.rb
124
+ - lib/susanin/pattern.rb
125
+ - lib/susanin/resource.rb
69
126
  - lib/susanin/version.rb
70
127
  - susanin.gemspec
71
- homepage: https://github.com/aratak/susanin
128
+ homepage: https://github.com/cimon-io/susanin
72
129
  licenses:
73
130
  - MIT
74
131
  metadata: {}
@@ -88,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
145
  version: '0'
89
146
  requirements: []
90
147
  rubyforge_project:
91
- rubygems_version: 2.2.2
148
+ rubygems_version: 2.5.1
92
149
  signing_key:
93
150
  specification_version: 4
94
151
  summary: polymorphic_url extention to help with route generation