active_triples-local_name 0.1.0

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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MTcyOTBhODdmODAzNWQ5OWJiYjFlOWY3YTA4ZDRmZTBlNDIwYzI3MA==
5
+ data.tar.gz: !binary |-
6
+ MTRjNzcwNWQ3NjhkMjQzOWRlZTcyMDVkNTE3ZDFmZDA0NjUzNjM1Nw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZTRmYzc4NmEyMjgyYzg2MDE5MWNkMWVlZWJjZjExMzFmMWY4YzBkYTEyZWQ0
10
+ NTg4MTYyZGNlYmMzZGQyYzJmYjI1MDQ5YWNiZjMzMThiNTU5MmRiMGFmMGIx
11
+ NTI5YTVhNWQ5NDgwMzgyY2ViZGU2YmVjMWExOGVlOTIwOGVmNTA=
12
+ data.tar.gz: !binary |-
13
+ NjBkNDc3NTM4MjMwODlmYTk1M2RlNDJkMmVkMTVkNmJkNjllY2M2YzYzY2Jk
14
+ ZTUxMWIwMTc2MzkwNmIyYTdhMTVmMTIxODJjMDhlM2I3ZDEwMmViOGVlMGJm
15
+ MjhiNWI2NjBmYjYwZjU2MGEwZjc1OTM5NWUxMDk2ZTFmNGNjMzQ=
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ Gemfile.lock
5
+ tmp/*
6
+ .sass-cache
7
+ .idea
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ anguage: ruby
2
+ bundler_args: --without debug
3
+ script: "bundle exec rspec spec"
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - 2.1.1
9
+ - jruby-19mode
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: jruby-19mode
data/AUTHORS ADDED
@@ -0,0 +1,2 @@
1
+ * Tom Johnson (thomas.johnson@oregonstate.edu)
2
+ * Trey Terrell
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ # GETTING FROM GEMFILE UNTIL ActiveTriples master CODE IS RELEASED (>0.4.0), THEN MOVE THIS BACK TO *.gemspec FILE
6
+ # Use active-triple for handling of triple persistence
7
+ gem 'active-triples', :git => 'git@github.com:no-reply/ActiveTriples.git', :branch => 'master'
8
+
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/LICENSE ADDED
@@ -0,0 +1,12 @@
1
+ ##########################################################################
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
data/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # ActiveTriples::LocalName
2
+
3
+
4
+ Provides utilities for working with local names under the [ActiveTriples](https://github.com/ActiveTriples/ActiveTriples)
5
+ framework. Includes a default implementation of a local name minter.
6
+
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'active_triples-local_name'
13
+
14
+ And then execute:
15
+
16
+ $ bundle install
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install active_triples-local_name
21
+
22
+
23
+ ## Usage
24
+
25
+ **Utilities**
26
+
27
+ * Local Name Minter
28
+ * Others may be added in the future.
29
+
30
+
31
+ ### Local Name Minter
32
+
33
+ Common prep code for all examples:
34
+ ```ruby
35
+ require 'active_triples'
36
+ require 'active_triples/local_name'
37
+
38
+ # create an in-memory repository for ad-hoc testing
39
+ ActiveTriples::Repositories.add_repository :default, RDF::Repository.new
40
+
41
+ # create a DummyResource for ad-hoc testing
42
+ # NOTE: local name minter requires resource class to have base_uri configured
43
+ class DummyResourceWithBaseURI < ActiveTriples::Resource
44
+ configure :base_uri => "http://example.org",
45
+ :type => RDF::URI("http://example.org/SomeClass"),
46
+ :repository => :default
47
+ end
48
+ ```
49
+
50
+ #### Example: Using default minter
51
+ ```ruby
52
+ # create a new resource with a minted local name using default minter
53
+ localname = ActiveTriples::LocalName::Minter.generate_local_name(
54
+ DummyResourceWithBaseURI, 10, {:prefix=>'d'})
55
+ # => something like -- "http://example.org/d59beebc5-5238-4aad-bf92-f63fbbd8faaa"
56
+ ```
57
+
58
+ Parameter NOTES:
59
+ * for_class = DummyResourceWithBaseURI - resource class must have base_uri configured
60
+ * max_tries = 10 - If using default minter, it should easily find an available local name in 10 tries.
61
+ If your minter algorithm gets lots of clashes with existing URIs and max_tries is set high, you may
62
+ run into performance issues.
63
+ * minter_args (optional) = {:prefix=>'d'} - The default minter takes a single hash argument. You can
64
+ define minters that take no arguments, multiple arguments, or a multiple item hash argument.
65
+ * minter_block = nil - When minter_block is not passed in, the default minter algorithm, which produces
66
+ a UUID, will be used. Best practice is to start local names with an alpha character. UUIDs generate
67
+ with either an alpha or numeric as the first character. Passing in a prefix of 'd' forces the local
68
+ name to start with the character 'd'.
69
+
70
+
71
+ #### Example: Passing in a block as minter
72
+
73
+ ```ruby
74
+ # create a new resource with a minted local name using passed in block
75
+ localname = ActiveTriples::LocalName::Minter.generate_local_name(
76
+ DummyResourceWithBaseURI,10,'d') do |prefix|
77
+ prefix ||= ""
78
+ local_name = SecureRandom.uuid
79
+ local_name = prefix + "_blockproc_" + local_name if prefix && prefix.is_a?(String)
80
+ local_name
81
+ end
82
+ # => something like -- "http://example.org/d_blockproc_59beebc5-5238-4aad-bf92-f63fbbd8faaa"
83
+ ```
84
+
85
+
86
+ #### Example: Passing in a method as minter
87
+ ```ruby
88
+ # minter method
89
+ def uuid_minter( *options )
90
+ prefix = options[0][:prefix] if ! options.empty? && options[0].is_a?(Hash) && options[0].key?(:prefix)
91
+ local_name = SecureRandom.uuid
92
+ local_name = prefix + "_method_" + local_name if prefix && prefix.is_a?(String)
93
+ local_name
94
+ end
95
+
96
+ # create a new resource with a minted local name using a minter method
97
+ localname = ActiveTriples::LocalName::Minter.generate_local_name(
98
+ DummyResourceWithBaseURI,10,{:prefix=>"d"}) {|args| uuid_minter(args)}
99
+ # => something like -- "http://example.org/d_method_59beebc5-5238-4aad-bf92-f63fbbd8faaa"
100
+ ```
101
+
102
+ #### Example: Override default minter.
103
+ ```ruby
104
+ # minter method
105
+ module ActiveTriples
106
+ module LocalName
107
+ class Minter
108
+ def self.default_minter( *options )
109
+ prefix = options[0][:prefix] if ! options.empty? && options[0].is_a?(Hash) && options[0].key?(:prefix)
110
+ local_name = SecureRandom.uuid
111
+ local_name = prefix + "_default_" + local_name if prefix && prefix.is_a?(String)
112
+ local_name
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ # create a new resource with a minted local name using override of default minter
119
+ localname = ActiveTriples::LocalName::Minter.generate_local_name(
120
+ DummyResourceWithBaseURI,10,{:prefix=>"d"})
121
+ # => something like -- "http://example.org/d_default_59beebc5-5238-4aad-bf92-f63fbbd8faaa"
122
+ ```
123
+
124
+ See more examples in spec/active_triples/local_name/minter_spec.rb.
125
+
126
+
127
+ ## Contributing
128
+
129
+ Please observe the following guidelines:
130
+
131
+ - Do your work in a feature branch based on ```master``` and rebase before submitting a pull request.
132
+ - Write tests for your contributions.
133
+ - Document every method you add using YARD annotations. (_Note: Annotations are sparse in the existing codebase, help us fix that!_)
134
+ - Organize your commits into logical units.
135
+ - Don't leave trailing whitespace (i.e. run ```git diff --check``` before committing).
136
+ - Use [well formed](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) commit messages.
137
+
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "active_triples/local_name/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "active_triples-local_name"
7
+ s.version = ActiveTriples::LocalName::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["E. Lynette Rayle"]
10
+ s.homepage = 'https://github.com/no-reply/active_triples-local_name'
11
+ s.email = 'elr37@cornell.edu'
12
+ s.summary = %q{Local name minter for ActiveTriples based resources.}
13
+ s.description = %q{active_triples-local_name provides a standard interface and default implementation for a minter of the local name portion of a URI.}
14
+ s.license = "APACHE2"
15
+ s.required_ruby_version = '>= 1.9.3'
16
+
17
+ # GETTING FROM GEMFILE UNTIL persistent check CODE IS RELEASED
18
+ # s.add_dependency('active-triples', '~> 0.4')
19
+
20
+ s.add_dependency('deprecation', '~> 0.1')
21
+ s.add_dependency('activesupport', '>= 3.0.0')
22
+
23
+ s.add_development_dependency('rdoc')
24
+ s.add_development_dependency('rspec')
25
+ s.add_development_dependency('guard-rspec')
26
+
27
+ s.files = `git ls-files`.split("\n")
28
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
29
+
30
+ s.extra_rdoc_files = [
31
+ "LICENSE",
32
+ "README.md"
33
+ ]
34
+ end
@@ -0,0 +1,28 @@
1
+ # require 'rdf'
2
+ require 'active_triples/local_name/version'
3
+ require 'active_support'
4
+
5
+ module ActiveTriples
6
+ module LocalName
7
+ extend ActiveSupport::Autoload
8
+ eager_autoload do
9
+ autoload :Minter
10
+ end
11
+
12
+ def self.class_from_string(class_name, container_class=Kernel)
13
+ container_class = container_class.name if container_class.is_a? Module
14
+ container_parts = container_class.split('::')
15
+ (container_parts + class_name.split('::')).flatten.inject(Kernel) do |mod, class_name|
16
+ if mod == Kernel
17
+ Object.const_get(class_name)
18
+ elsif mod.const_defined? class_name.to_sym
19
+ mod.const_get(class_name)
20
+ else
21
+ container_parts.pop
22
+ class_from_string(class_name, container_parts.join('::'))
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,75 @@
1
+ module ActiveTriples
2
+ module LocalName
3
+
4
+ ##
5
+ # Provide a standard interface for minting new IDs and validating
6
+ # the ID is not in use in any known (i.e., registered) repository.
7
+ class Minter
8
+
9
+ ##
10
+ # Generate a random localname that combined with a class' base_uri does not already exist in
11
+ # registered triplestores.
12
+ #
13
+ # @param [Class] the class inheriting from <tt>ActiveTriples::Reource</tt> whose configuration
14
+ # is used to generate the full URI for testing for uniqueness of the generated local name
15
+ # @param [Integer] the maximum number of attempts to make a unique local name
16
+ # @yieldparam the arguments to pass to the minter block (optional)
17
+ # @yield the function to use to mint the local name. If not specified, the
18
+ # +default_minter+ function will be used to generate an UUID.
19
+ # @yieldreturn [String] the generated local name to be tested for uniqueness
20
+ #
21
+ # @return [String] the generated local name
22
+ #
23
+ # @raise [ArgumentError] if maximum allowed tries is less than 0
24
+ # @raise [ArgumentError] if for_class does not inherit from ActiveTriples::Resources
25
+ # @raise [ArgumentError] if minter_block is not a block (does not respond to call)
26
+ # @raise [Exception] if for_class does not have base_uri configured
27
+ # @raise [Exception] if an available local name is not found in the maximum allowed tries.
28
+ #
29
+ # @TODO This is inefficient if max_tries is large. Could try
30
+ # multi-threading. When using the default_minter included
31
+ # in this class, it is unlikely to be a problem and should
32
+ # find an ID within the first few attempts.
33
+ def self.generate_local_name(for_class, max_tries=10, *minter_args, &minter_block)
34
+ raise ArgumentError, 'Argument max_tries must be >= 1 if passed in' if max_tries <= 0
35
+
36
+ raise ArgumentError, 'Argument for_class must inherit from ActiveTriples::Resource' unless for_class < ActiveTriples::Resource
37
+ raise 'Requires base_uri to be defined in for_class.' unless for_class.base_uri
38
+
39
+ raise ArgumentError, 'Invalid minter_block.' if minter_block && !minter_block.respond_to?(:call)
40
+ minter_block = proc { |args| default_minter(args) } unless minter_block
41
+
42
+ found = true
43
+ test_id = nil
44
+ (1).upto(max_tries) do
45
+ test_id = minter_block.call( *minter_args )
46
+ found = for_class.id_persisted?(test_id)
47
+ break unless found
48
+ end
49
+ raise 'Available ID not found. Exceeded maximum tries.' if found
50
+ test_id
51
+ end
52
+
53
+ ##
54
+ # Default minter used by generate_id.
55
+ #
56
+ # @param [Hash] options the options to use while generating the local name
57
+ # @option options [String] :prefix the prefix to put before the generated local name (optional)
58
+ #
59
+ # @note Because <tt>:prefix</tt> is optional, errors in type for <tt>:prefix</tt> are ignored. Any additional
60
+ # parameters beyond <tt>:prefix</tt> are also ignored.
61
+ #
62
+ # @note Best practice is to begin localnames with an alpha character. UUIDs can generate with an alpha or
63
+ # numeric as the first character. Pass in an alpha character as <tt>:prefix</tt> to enforce this best
64
+ # practice.
65
+ #
66
+ # @return [String] a uuid
67
+ def self.default_minter( *options )
68
+ prefix = options[0][:prefix] if ! options.empty? && options[0].is_a?(Hash) && options[0].key?(:prefix)
69
+ local_name = SecureRandom.uuid
70
+ local_name = prefix + local_name if prefix && prefix.is_a?(String)
71
+ local_name
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveTriples
2
+ module LocalName
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,336 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveTriples::LocalName::Minter do
4
+
5
+ describe "#generate_local_name" do
6
+ before (:all) do
7
+ @timeHashMinter_lambda = lambda do |digit_count|
8
+ rnd_id = 0
9
+ rnd_id = Time.now.hash until rnd_id != 0
10
+ rnd_id *= -1 if rnd_id < 0
11
+ rnd_id /= 10 until rnd_id < (10**digit_count)
12
+ "lambda_#{rnd_id}"
13
+ end
14
+
15
+ @timeHashMinter_proc = proc do |digit_count|
16
+ rnd_id = 0
17
+ rnd_id = Time.now.hash until rnd_id != 0
18
+ rnd_id *= -1 if rnd_id < 0
19
+ rnd_id /= 10 until rnd_id < (10**digit_count)
20
+ "proc_#{rnd_id}"
21
+ end
22
+
23
+ @timeHashMinter2_proc = proc do |digit_count,prefix|
24
+ rnd_id = 0
25
+ rnd_id = Time.now.hash until rnd_id != 0
26
+ rnd_id *= -1 if rnd_id < 0
27
+ rnd_id /= 10 until rnd_id < (10**digit_count)
28
+ "#{prefix}_#{rnd_id}"
29
+ end
30
+
31
+ # See also timeHashMinter_method defined in DummyResourceWithBaseURI class below.
32
+ end
33
+
34
+ subject {DummyResourceWithBaseURI.new('1')}
35
+
36
+ before do
37
+ class DummyResource < ActiveTriples::Resource
38
+ configure :type => RDF::URI('http://example.org/SomeClass')
39
+ property :title, :predicate => RDF::DC.title
40
+ end
41
+ class DummyResourceWithBaseURI < ActiveTriples::Resource
42
+ configure :base_uri => "http://example.org",
43
+ :type => RDF::URI("http://example.org/SomeClass"),
44
+ :repository => :default
45
+
46
+ def self.timeHashMinter_method( *args )
47
+ digit_count = args.size > 0 ? args[0] : 10
48
+ rnd_id = 0
49
+ rnd_id = Time.now.hash until rnd_id != 0
50
+ rnd_id *= -1 if rnd_id < 0
51
+ rnd_id /= 10 until rnd_id < (10**digit_count)
52
+ "method_#{rnd_id}"
53
+ end
54
+
55
+ def self.timeHashMinter2_method( *args )
56
+ digit_count = args && args.size > 0 ? args[0] : 10
57
+ prefix = args && args.size > 1 ? args[1] : ""
58
+ rnd_id = 0
59
+ rnd_id = Time.now.hash until rnd_id != 0
60
+ rnd_id *= -1 if rnd_id < 0
61
+ rnd_id /= 10 until rnd_id < (10**digit_count)
62
+ "#{prefix}_#{rnd_id}"
63
+ end
64
+
65
+ def self.timeHashMinter3_method( *args )
66
+ digit_count = (args && args.size > 0 && args[0]) ? args[0][:digit_count] : 10
67
+ prefix = args && args.size > 0 && args[0] ? args[0][:prefix] : ""
68
+ rnd_id = 0
69
+ rnd_id = Time.now.hash until rnd_id != 0
70
+ rnd_id *= -1 if rnd_id < 0
71
+ rnd_id /= 10 until rnd_id < (10**digit_count)
72
+ localname = "#{prefix}_#{rnd_id}"
73
+ localname
74
+ end
75
+ end
76
+ ActiveTriples::Repositories.add_repository :default, RDF::Repository.new
77
+ end
78
+ after do
79
+ Object.send(:remove_const, "DummyResourceWithBaseURI") if Object
80
+ Object.send(:remove_const, "DummyResource") if Object
81
+ ActiveTriples::Repositories.clear_repositories!
82
+ end
83
+
84
+ context "when class doesn't have base_uri defined" do
85
+ it "should raise an Exception" do
86
+ expect{ ActiveTriples::LocalName::Minter.generate_local_name(DummyResource) }.to raise_error(RuntimeError, 'Requires base_uri to be defined in for_class.')
87
+ end
88
+ end
89
+
90
+ context "when all IDs available" do
91
+ context "and no minter function is passed in" do
92
+ it "should generate an ID using default minter function" do
93
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI)
94
+ expect(id).to be_kind_of String
95
+ expect(id.length).to be 36
96
+ id.should match /[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/
97
+ end
98
+ end
99
+
100
+ context "and minter function is passed as ad-hoc proc" do
101
+ it "should generate an ID with passed in minter function block" do
102
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,1) do |digit_count|
103
+ rnd_id = 0
104
+ rnd_id = Time.now.hash until rnd_id != 0
105
+ rnd_id *= -1 if rnd_id < 0
106
+ rnd_id /= 10 until rnd_id < (10**digit_count)
107
+ rnd_id
108
+ end
109
+ expect(id).to be_between(1,9)
110
+ end
111
+ end
112
+
113
+ context "and minter function is pre-defined proc that takes 1 parameter" do
114
+ context "and minter function is passed as proc in block with hardcoded parameter" do
115
+ it "should generate an ID with passed in proc in block" do
116
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI) {
117
+ @timeHashMinter_proc.call(1) }
118
+ expect(id[0..4]).to eq "proc_"
119
+ expect(id[5..id.length].to_i).to be_between(1,9)
120
+ end
121
+ end
122
+
123
+ context "and minter function is passed as proc in block with parameter passed in minterargs" do
124
+ it "should generate an ID with passed in proc in block" do
125
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,1) {
126
+ |digit_count| @timeHashMinter_proc.call(digit_count) }
127
+ expect(id[0..4]).to eq "proc_"
128
+ expect(id[5..id.length].to_i).to be_between(1,9)
129
+ end
130
+ end
131
+
132
+ context "and minter function is passed address to proc with parameter passed in minterargs" do
133
+ it "should generate an ID with passed in proc" do
134
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,1,
135
+ &@timeHashMinter_proc)
136
+ expect(id[0..4]).to eq "proc_"
137
+ expect(id[5..id.length].to_i).to be_between(1,9)
138
+ end
139
+ end
140
+ end
141
+
142
+ context "and minter function is pre-defined proc that takes 2 parameter" do
143
+ context "and minter function is passed as proc in block with hardcoded parameter" do
144
+ it "should generate an ID with passed in proc in block" do
145
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI) {
146
+ @timeHashMinter2_proc.call(1,'foo') }
147
+ expect(id[0..3]).to eq "foo_"
148
+ expect(id[4..id.length].to_i).to be_between(1,9)
149
+ end
150
+ end
151
+
152
+ context "and minter function is passed as proc in block with parameter passed in minterargs" do
153
+ it "should generate an ID with passed in proc in block" do
154
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,1,'foo') {
155
+ |digit_count,prefix| @timeHashMinter2_proc.call(digit_count,prefix) }
156
+ expect(id[0..3]).to eq "foo_"
157
+ expect(id[4..id.length].to_i).to be_between(1,9)
158
+ end
159
+ end
160
+
161
+ context "and minter function is passed address to proc with parameters passed in minterargs" do
162
+ it "should generate an ID with passed in proc" do
163
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,1,"foo",
164
+ &@timeHashMinter2_proc)
165
+ expect(id[0..3]).to eq "foo_"
166
+ expect(id[4..id.length].to_i).to be_between(1,9)
167
+ end
168
+ end
169
+ end
170
+
171
+
172
+ context "and minter function is method that takes 1 parameter" do
173
+ context "and parameter is hardcoded in block" do
174
+ it "should generate an ID with passed in method" do
175
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI) {
176
+ DummyResourceWithBaseURI.timeHashMinter_method (1) }
177
+ expect(id[0..6]).to eq "method_"
178
+ expect(id[7..id.length].to_i).to be_between(1,9)
179
+ end
180
+ end
181
+
182
+ context "and parameter is passed as minterargs" do
183
+ it "should generate an ID with passed in method" do
184
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,1) {
185
+ |digit_count| DummyResourceWithBaseURI.timeHashMinter_method(digit_count) }
186
+ expect(id[0..6]).to eq "method_"
187
+ expect(id[7..id.length].to_i).to be_between(1,9)
188
+ end
189
+ end
190
+ end
191
+
192
+
193
+ context "and minter function is method that takes 2 parameters" do
194
+ context "and parameters are hardcoded in block" do
195
+ it "should generate an ID with passed in method" do
196
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI) {
197
+ DummyResourceWithBaseURI.timeHashMinter2_method(1,"foo") }
198
+ expect(id[0..3]).to eq "foo_"
199
+ expect(id[4..id.length].to_i).to be_between(1,9)
200
+ end
201
+ end
202
+
203
+ context "and parameters are passed as minterargs" do
204
+ it "should generate an ID with passed in method" do
205
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,1,"foo") {
206
+ |digit_count,prefix| DummyResourceWithBaseURI.timeHashMinter2_method(digit_count,prefix) }
207
+ expect(id[0..3]).to eq "foo_"
208
+ expect(id[4..id.length].to_i).to be_between(1,9)
209
+ end
210
+ end
211
+ end
212
+
213
+
214
+ context "and minter function is method that takes 1 hash parameter" do
215
+ context "and parameter is hardcoded in block" do
216
+ it "should generate an ID with passed in method" do
217
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI) {
218
+ DummyResourceWithBaseURI.timeHashMinter3_method({:digit_count=>1,:prefix=>"foo"}) }
219
+ expect(id[0..3]).to eq "foo_"
220
+ expect(id[4..id.length].to_i).to be_between(1,9)
221
+ end
222
+ end
223
+ end
224
+
225
+ context "and parameter is passed as minterargs" do
226
+ it "should generate an ID with passed in method" do
227
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,{:digit_count=>1,:prefix=>"foo"}) {
228
+ |hash_args| DummyResourceWithBaseURI.timeHashMinter3_method(hash_args) }
229
+ expect(id[0..3]).to eq "foo_"
230
+ expect(id[4..id.length].to_i).to be_between(1,9)
231
+ end
232
+ end
233
+
234
+ context "and no parameters are passed in" do
235
+ it "should generate an ID with passed in method using defaults when no params passed" do
236
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10) {
237
+ |hash_args| DummyResourceWithBaseURI.timeHashMinter3_method(hash_args) }
238
+ expect(id[0]).to eq "_"
239
+ expect(id[1..id.length].to_i).to be_between(1000000000,9999999999)
240
+ end
241
+ end
242
+
243
+ context "but block defines method with no parameters" do
244
+ it "should generate an ID with passed in method using defaults when no params passed" do
245
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10) {
246
+ DummyResourceWithBaseURI.timeHashMinter3_method }
247
+ expect(id[0]).to eq "_"
248
+ expect(id[1..id.length].to_i).to be_between(1000000000,9999999999)
249
+ end
250
+ end
251
+ end
252
+ context "when some IDs available" do
253
+ before do
254
+ DummyResourceWithBaseURI.new('proc_3').persist!
255
+ DummyResourceWithBaseURI.new('proc_4').persist!
256
+ DummyResourceWithBaseURI.new('proc_8').persist!
257
+ end
258
+ after do
259
+ DummyResourceWithBaseURI.new('proc_3').destroy!
260
+ DummyResourceWithBaseURI.new('proc_4').destroy!
261
+ DummyResourceWithBaseURI.new('proc_8').destroy!
262
+ end
263
+
264
+ it "should generate an ID not already in use" do
265
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI) { @timeHashMinter_proc.call(1) }
266
+ expect(id[0..4]).to eq "proc_"
267
+ expect(id[5..id.length].to_i).to be_between(1,9)
268
+ expect(id).not_to eq 'proc_3'
269
+ expect(id).not_to eq 'proc_4'
270
+ expect(id).not_to eq 'proc_8'
271
+ end
272
+ end
273
+
274
+ context "when no IDs available" do
275
+ before do
276
+ 1.upto(9) { |id| DummyResourceWithBaseURI.new("proc_#{id}").persist! }
277
+ end
278
+ after do
279
+ 1.upto(9) { |id| DummyResourceWithBaseURI.new("proc_#{id}").destroy! }
280
+ end
281
+
282
+ it "should raise an Exception" do
283
+ expect{ ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI) { @timeHashMinter_proc.call(1) } }.
284
+ to raise_error(RuntimeError, "Available ID not found. Exceeded maximum tries.")
285
+ end
286
+ end
287
+
288
+ context "when passing prefix to default minter function" do
289
+ context "and prefix is string" do
290
+ it "should generate a prefixed ID" do
291
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,{:prefix=>"s"})
292
+ expect(id).to be_kind_of String
293
+ expect(id.length).to be 37
294
+ id.should match /s[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/
295
+ end
296
+ end
297
+
298
+ context "and prefix is integer" do
299
+ it "should generate ID ignoring prefix" do
300
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,1)
301
+ expect(id).to be_kind_of String
302
+ expect(id.length).to be 36
303
+ id.should match /[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/
304
+ end
305
+ end
306
+
307
+ context "and prefix is float" do
308
+ it "should generate ID ignoring prefix" do
309
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,{:prefix=>1.5})
310
+ expect(id).to be_kind_of String
311
+ expect(id.length).to be 36
312
+ id.should match /[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/
313
+ end
314
+ end
315
+
316
+ context "and prefix is hash" do
317
+ it "should generate ID ignoring prefix" do
318
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,{:prefix=>{"a"=>"b"}})
319
+ expect(id).to be_kind_of String
320
+ expect(id.length).to be 36
321
+ id.should match /[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/
322
+ end
323
+ end
324
+
325
+ context "and prefix is array" do
326
+ it "should generate ID ignoring prefix" do
327
+ id = ActiveTriples::LocalName::Minter.generate_local_name(DummyResourceWithBaseURI,10,{:prefix=>[1,2,3]})
328
+ expect(id).to be_kind_of String
329
+ expect(id.length).to be 36
330
+ id.should match /[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/
331
+ end
332
+ end
333
+ end
334
+
335
+ end
336
+ end
@@ -0,0 +1,19 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'active_triples/local_name'
5
+ require 'active_triples'
6
+
7
+
8
+ Dir['./spec/support/**/*.rb'].each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ config.color = true
12
+ config.tty = true
13
+
14
+ # Uncomment the following line to get errors and backtrace for deprecation warnings
15
+ # config.raise_errors_for_deprecations!
16
+
17
+ # Use the specified formatter
18
+ config.formatter = :progress
19
+ end
@@ -0,0 +1,81 @@
1
+ shared_examples_for "an ActiveModel" do
2
+ subject { described_class.new }
3
+
4
+ describe '#to_key' do
5
+ it 'should respond' do
6
+ expect(subject).to respond_to :to_key
7
+ end
8
+
9
+ it 'should return nil when #persisted? is false ' do
10
+ def subject.persisted?() false end
11
+ expect(subject.to_key).to eq nil
12
+ end
13
+ end
14
+
15
+ describe '#to_param' do
16
+ it 'should respond' do
17
+ expect(subject).to respond_to :to_param
18
+ end
19
+
20
+ it 'should return nil when #persisted? is false ' do
21
+ def subject.persisted?() false end
22
+ expect(subject.to_param).to eq nil
23
+ end
24
+ end
25
+
26
+ describe '#model_name' do
27
+ let(:model_name) { subject.class.model_name }
28
+
29
+ it 'should have a model name' do
30
+ expect(model_name).to respond_to :to_str
31
+ end
32
+
33
+ it 'should have a human name' do
34
+ expect(model_name.human).to respond_to :to_str
35
+ end
36
+
37
+ it 'should have a singular name' do
38
+ expect(model_name.singular).to respond_to :to_str
39
+ end
40
+
41
+ it 'should have a plural name' do
42
+ expect(model_name.plural).to respond_to :to_str
43
+ end
44
+ end
45
+
46
+ describe '#to_partial_path' do
47
+ it 'should return a string' do
48
+ expect(subject.to_partial_path).to be_a String
49
+ end
50
+ end
51
+
52
+ describe '#persisted?' do
53
+ it 'should return a boolean' do
54
+ expect(match_boolean(subject.persisted?)).to be true
55
+ end
56
+ end
57
+
58
+ describe '#valid?' do
59
+ it 'should return a boolean' do
60
+ expect(match_boolean(subject.valid?)).to be true
61
+ end
62
+ end
63
+
64
+ describe '#new_record' do
65
+ it 'should return a boolean' do
66
+ expect(match_boolean(subject.new_record?)).to be true
67
+ end
68
+ end
69
+
70
+ describe '#destroyed?' do
71
+ it 'should return a boolean' do
72
+ expect(match_boolean(subject.destroyed?)).to be true
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def match_boolean(result)
79
+ result == true || result == false
80
+ end
81
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_triples-local_name
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - E. Lynette Rayle
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: deprecation
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rdoc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: active_triples-local_name provides a standard interface and default implementation
84
+ for a minter of the local name portion of a URI.
85
+ email: elr37@cornell.edu
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files:
89
+ - LICENSE
90
+ - README.md
91
+ files:
92
+ - .gitignore
93
+ - .travis.yml
94
+ - AUTHORS
95
+ - Gemfile
96
+ - Guardfile
97
+ - LICENSE
98
+ - README.md
99
+ - active_triples-local_name.gemspec
100
+ - lib/active_triples/local_name.rb
101
+ - lib/active_triples/local_name/minter.rb
102
+ - lib/active_triples/local_name/version.rb
103
+ - spec/active_triples/local_name/minter_spec.rb
104
+ - spec/spec_helper.rb
105
+ - spec/support/active_model_lint.rb
106
+ homepage: https://github.com/no-reply/active_triples-local_name
107
+ licenses:
108
+ - APACHE2
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: 1.9.3
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.2.2
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Local name minter for ActiveTriples based resources.
130
+ test_files: []