readable_ident 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 937571a591a4d48958a844d0add1048fa40dfc9b
4
+ data.tar.gz: fc4549f0079cdf7df6d0ef262a5ed742b257d613
5
+ SHA512:
6
+ metadata.gz: 729d0f75604ea3f682a381e9ab00a1bd6aac3f35319beb51fca11934dedf5a1459d5dcd1861a6e8200398669432b951a735863040fa12887e877f24455966035
7
+ data.tar.gz: c891e9e3c184c8d7864df4daa3f59f4b3198cae83ef25010f109f233551e720d2be75d7343dd0b58c179333a762d8b63f141de4bfe0437b8f2fa9602e43a191f
data/.gitignore ADDED
@@ -0,0 +1,18 @@
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
+ db/test.db
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.0.1
2
+
3
+ * initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in readable_ident.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Mark Schewe
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,55 @@
1
+ # Readable Ident
2
+
3
+ [![Build Status](https://travis-ci.org/mschewe/readable_ident.png?branch=master)](https://travis-ci.org/mschewe/readable_ident) [![Code Climate](https://codeclimate.com/github/mschewe/readable_ident.png)](https://codeclimate.com/github/mschewe/readable_ident)
4
+
5
+ UUIDs are great, but not really easy to remember and compare by humans.
6
+ At many points you might need a human readable ident, that is not the database id field.
7
+ To use the database id might be appealing, but if you need to backup and probably restore data this is no good.
8
+
9
+ This gem aims to help you generate unique short idents for ActiveRecord models.
10
+
11
+ It makes it possible to autogenerate a quiet readable unique ident, that consists of an (optional) prefix and a variable amount of [a-zA-Z0-9]{n}.
12
+
13
+ e.g. device-9fX compared to 170a3d59-db5d-48d4-b064-1fd127fde049
14
+
15
+ For example if you decide to use the signs, there are (26*2 + 10)^3 = 238.328 possible combinations, that should be enough for most cases.
16
+
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ gem 'readable_ident'
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install readable_ident
31
+
32
+ ## Usage
33
+
34
+ First create a migration to add a field to the model
35
+
36
+ ```rails g migration add_r_ident_to_device r_ident:string```
37
+
38
+ Then add the following to your model:
39
+
40
+ ```
41
+ class SomeModel < ActiveRecord::Base
42
+ readable_ident prefix: s, seperator: '~', length: 5
43
+ end
44
+ ```
45
+
46
+ This will automatically generate an unique ident for the field r_ident with the prefix 's', the seperator '~' and the length of 5 e.g. s~iq12xk
47
+
48
+
49
+ ## Contributing
50
+
51
+ 1. Fork it
52
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
53
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
54
+ 4. Push to the branch (`git push origin my-new-feature`)
55
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
data/db/.gitkeep ADDED
File without changes
@@ -0,0 +1,39 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'active_record'
3
+ require 'active_support/concern'
4
+
5
+ module ReadableIdent
6
+
7
+ module ModelAddition
8
+ extend ActiveSupport::Concern
9
+ include ActiveModel::Validations
10
+
11
+ @options
12
+
13
+ included do
14
+ validates :r_ident, presence: true, length: { minimum: 0 }
15
+ after_validation :generate_readable_ident
16
+ end
17
+
18
+ module ClassMethods
19
+ def readable_ident(options={})
20
+ attr_reader :options
21
+ class_attribute :options
22
+ self.options = options
23
+ end
24
+ end
25
+
26
+ private
27
+ def generate_readable_ident
28
+ r_ident = ''
29
+ while true do
30
+ r_ident = ReadableIdent::generate_readable_ident(self.options)
31
+ break if self.class.where(r_ident: r_ident).first.nil?
32
+ end
33
+ write_attribute(:r_ident, r_ident)
34
+ end
35
+
36
+ end
37
+ end
38
+
39
+ ActiveRecord::Base.send(:include, ReadableIdent::ModelAddition)
@@ -0,0 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module ReadableIdent
3
+ VERSION = "0.0.1"
4
+ end
@@ -0,0 +1,47 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require "readable_ident/model_addition"
3
+
4
+ module ReadableIdent
5
+
6
+ @@regex_prefix = /[a-zA-Z0-9]+|^$/
7
+ @@regex_seperator = /[~-]+|^$/
8
+
9
+ def self.generate_readable_ident(options={})
10
+ options[:length] ||= 4
11
+ options[:prefix] ||= ''
12
+
13
+ if options[:prefix].empty?
14
+ options[:seperator] ||= ''
15
+ else
16
+ options[:seperator] ||= '-'
17
+ end
18
+
19
+ self.validate_options(options)
20
+
21
+ options[:prefix].to_s + options[:seperator].to_s + random_alphanumeric(options[:length].to_i).to_s
22
+ end
23
+
24
+ private
25
+
26
+ def self.random_alphanumeric(length)
27
+ ident = ""
28
+ length.times { ident << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }
29
+ return ident
30
+ end
31
+
32
+ def self.validate_options(options)
33
+ raise ArgumentError, 'length must be numeric' \
34
+ unless options[:length].is_a? Numeric
35
+
36
+ raise ArgumentError, 'seperator length must be 1' \
37
+ unless options[:seperator].length < 2
38
+
39
+ raise ArgumentError, 'prefix is not in specified regex' \
40
+ if options[:prefix].match(@@regex_prefix).nil?
41
+
42
+ raise ArgumentError, 'seperator is not in specified regex' \
43
+ if options[:seperator].match(@@regex_seperator).nil?
44
+ end
45
+
46
+ end
47
+
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'readable_ident/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "readable_ident"
8
+ gem.version = ReadableIdent::VERSION
9
+ gem.authors = ["Mark Schewe"]
10
+ gem.email = ["schewe.mark@gmail.com"]
11
+ gem.description = %q{Generates a readable ident for a given model}
12
+ gem.summary = gem.description
13
+ gem.homepage = "https://github.com/mschewe/readable_ident"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "activerecord"
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "rspec"
23
+ gem.add_development_dependency "factory_girl"
24
+ gem.add_development_dependency "debugger"
25
+ gem.add_development_dependency "sqlite3"
26
+
27
+ end
@@ -0,0 +1,8 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ FactoryGirl.define do
5
+ factory :test_class do
6
+ r_ident 'abcd'
7
+ end
8
+ end
@@ -0,0 +1,75 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ root = File.expand_path(File.join(File.dirname(__FILE__), '../..'))
5
+ ActiveRecord::Base.establish_connection(
6
+ :adapter => "sqlite3",
7
+ :database => "#{root}/db/test.db"
8
+ )
9
+
10
+ ActiveRecord::Schema.define do
11
+ self.verbose = false
12
+ create_table :test_classes, :force => true do |t|
13
+ t.string :r_ident
14
+ end
15
+ end
16
+
17
+ class TestClass < ActiveRecord::Base
18
+ readable_ident length: 10
19
+ end
20
+
21
+
22
+ describe ReadableIdent do
23
+
24
+ let(:test_class) { TestClass.create() }
25
+
26
+ it 'calls generates a readable_ident before validation' do
27
+ test_class.r_ident.should_not be_nil
28
+ test_class.r_ident.should_not be_empty
29
+ test_class.r_ident.length.should be 10
30
+ end
31
+
32
+ context 'creation with options' do
33
+
34
+ it 'accepts a length option' do
35
+ TestClass.options.merge!({length: 11})
36
+ test_class.r_ident.length.should be 11
37
+ end
38
+
39
+ it 'accepts a prefix option' do
40
+ TestClass.options.merge!({prefix: 'x', length: 12, seperator: '~'})
41
+ test_class.r_ident.length.should be 14
42
+ test_class.r_ident.should start_with('x~')
43
+ end
44
+
45
+ it 'acceps a seperator option' do
46
+ TestClass.options.merge!({prefix: 'y', length: 13, seperator: ''})
47
+ test_class.r_ident.length.should be 14
48
+ test_class.r_ident.should start_with('y')
49
+ end
50
+ end
51
+
52
+ context 'model validations' do
53
+ it 'generates unique idents' do
54
+ test_class_1 = FactoryGirl.build(:test_class)
55
+ test_class_2 = FactoryGirl.build(:test_class, r_ident: test_class_1.r_ident)
56
+
57
+ test_class_1.should be_valid
58
+ test_class_2.should be_valid
59
+
60
+ test_class_1.r_ident.should_not be test_class_2.r_ident
61
+
62
+ end
63
+
64
+ it 'p_ident should not be nil' do
65
+ test_class.r_ident = nil
66
+ test_class.should_not be_valid
67
+ end
68
+
69
+ it 'check if p_ident is empty' do
70
+ test_class.r_ident = ''
71
+ test_class.should_not be_valid
72
+ end
73
+ end
74
+
75
+ end
@@ -0,0 +1,72 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe "generate_readable_ident" do
5
+
6
+ context 'prefix' do
7
+
8
+ it 'should be empty if not supplied' do
9
+ ident = ReadableIdent.generate_readable_ident(length: 10);
10
+ ident.length.should eq 10
11
+ ident.should_not start_with('-')
12
+ end
13
+
14
+ it 'must be in specified regex' do
15
+ expect { ReadableIdent.generate_readable_ident(prefix: 'ß') }.to \
16
+ raise_error(ArgumentError, 'prefix is not in specified regex')
17
+ end
18
+
19
+ it 'should start with the given prefix' do
20
+ ident = ReadableIdent.generate_readable_ident(prefix: 'custom_prefix')
21
+ ident.should start_with('custom_prefix')
22
+ end
23
+ end
24
+
25
+ context 'seperator' do
26
+
27
+ it 'should have a dash as seperator if prefix is specified' do
28
+ ident = ReadableIdent.generate_readable_ident(prefix: 'hello')
29
+ ident.should start_with('hello-')
30
+ end
31
+
32
+ it 'should have an empty seperator if specified and has prefix' do
33
+ ident = ReadableIdent.generate_readable_ident(prefix: 'hello', seperator: '', length: 10)
34
+ ident.should =~ /hello[a-zA-Z0-9]{10}/
35
+ end
36
+
37
+ it 'must have the length of 1' do
38
+ expect { ReadableIdent.generate_readable_ident(seperator: '123') }.to \
39
+ raise_error(ArgumentError, 'seperator length must be 1')
40
+ end
41
+
42
+ it 'must be in specified regex' do
43
+ expect { ReadableIdent.generate_readable_ident(seperator: "µ") }.to \
44
+ raise_error(ArgumentError, 'seperator is not in specified regex')
45
+ end
46
+
47
+ it 'should have use the supplied seperator' do
48
+ ident = ReadableIdent.generate_readable_ident(seperator: '~')
49
+ ident.should start_with('~')
50
+ end
51
+
52
+ end
53
+
54
+ context 'length' do
55
+
56
+ it 'should generate ident with given length' do
57
+ ident = ReadableIdent.generate_readable_ident(length: 22)
58
+ ident.length.should eq 22
59
+ end
60
+
61
+ it 'must be numeric or raise AgrumentError' do
62
+ expect { ReadableIdent.generate_readable_ident(length: 'a') }.to \
63
+ raise_error(ArgumentError, 'length must be numeric')
64
+ end
65
+
66
+ it 'should have a length of 4 if no length given' do
67
+ ident = ReadableIdent.generate_readable_ident
68
+ ident.length.should eq 4
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,5 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'readable_ident'
3
+ require 'factory_girl'
4
+
5
+ FactoryGirl.find_definitions
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: readable_ident
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mark Schewe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
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
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
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: factory_girl
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: debugger
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
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Generates a readable ident for a given model
98
+ email:
99
+ - schewe.mark@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .rspec
106
+ - .travis.yml
107
+ - CHANGELOG.md
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - db/.gitkeep
113
+ - lib/readable_ident.rb
114
+ - lib/readable_ident/model_addition.rb
115
+ - lib/readable_ident/version.rb
116
+ - readable_ident.gemspec
117
+ - spec/factories/test_class_factory.rb
118
+ - spec/readable_ident/model_addition_spec.rb
119
+ - spec/readable_ident/readable_ident_spec.rb
120
+ - spec/spec_helper.rb
121
+ homepage: https://github.com/mschewe/readable_ident
122
+ licenses: []
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 2.0.5
141
+ signing_key:
142
+ specification_version: 4
143
+ summary: Generates a readable ident for a given model
144
+ test_files:
145
+ - spec/factories/test_class_factory.rb
146
+ - spec/readable_ident/model_addition_spec.rb
147
+ - spec/readable_ident/readable_ident_spec.rb
148
+ - spec/spec_helper.rb