keytar 1.4.1 → 1.5.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.
- data/Gemfile +1 -1
- data/Rakefile +1 -2
- data/VERSION +1 -1
- data/keytar.gemspec +5 -9
- data/lib/keytar.rb +89 -3
- data/spec/keytar_spec.rb +151 -0
- metadata +7 -10
- data/lib/keytar/key_builder.rb +0 -125
- data/spec/keytar/key_builder_spec.rb +0 -173
- data/spec/keytar/keytar_spec.rb +0 -270
data/Gemfile
CHANGED
@@ -2,7 +2,7 @@ source 'http://rubygems.org'
|
|
2
2
|
gem 'activesupport'
|
3
3
|
|
4
4
|
group :development, :test do
|
5
|
-
gem 'activerecord', '~>3.0.4' ## not needed if you're just using
|
5
|
+
gem 'activerecord', '~>3.0.4' ## not needed if you're just using Keytar
|
6
6
|
gem 'rake', '~>0.8.7'
|
7
7
|
gem 'jeweler', '~>1.5.2'
|
8
8
|
gem "autotest-standalone"
|
data/Rakefile
CHANGED
@@ -17,8 +17,7 @@ Jeweler::Tasks.new do |gem|
|
|
17
17
|
gem.license = "MIT"
|
18
18
|
gem.summary = %Q{A crazy simple library for building keys (in _key_ value store, not house keys) for Ruby on Rails}
|
19
19
|
gem.description = %Q{
|
20
|
-
Keytar
|
21
|
-
Use KeyBuilder to automatically generate keys based on class name instead of cluttering model
|
20
|
+
Use Keytar to automatically generate keys based on class name instead of cluttering model
|
22
21
|
definitions with tons of redundant key method declarations.
|
23
22
|
}
|
24
23
|
gem.email = "richard.schneeman@gmail.com"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.5.1
|
data/keytar.gemspec
CHANGED
@@ -5,14 +5,13 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{keytar}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.5.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = [%q{Schneems}]
|
12
|
-
s.date = %q{2011-08-
|
12
|
+
s.date = %q{2011-08-12}
|
13
13
|
s.description = %q{
|
14
|
-
Keytar
|
15
|
-
Use KeyBuilder to automatically generate keys based on class name instead of cluttering model
|
14
|
+
Use Keytar to automatically generate keys based on class name instead of cluttering model
|
16
15
|
definitions with tons of redundant key method declarations.
|
17
16
|
}
|
18
17
|
s.email = %q{richard.schneeman@gmail.com}
|
@@ -31,10 +30,8 @@ Gem::Specification.new do |s|
|
|
31
30
|
"keytar.gemspec",
|
32
31
|
"lib/.DS_Store",
|
33
32
|
"lib/keytar.rb",
|
34
|
-
"lib/keytar/key_builder.rb",
|
35
33
|
"license.txt",
|
36
|
-
"spec/
|
37
|
-
"spec/keytar/keytar_spec.rb",
|
34
|
+
"spec/keytar_spec.rb",
|
38
35
|
"spec/spec_helper.rb"
|
39
36
|
]
|
40
37
|
s.homepage = %q{http://github.com/Schnems/keytar}
|
@@ -43,8 +40,7 @@ Gem::Specification.new do |s|
|
|
43
40
|
s.rubygems_version = %q{1.8.6}
|
44
41
|
s.summary = %q{A crazy simple library for building keys (in _key_ value store, not house keys) for Ruby on Rails}
|
45
42
|
s.test_files = [
|
46
|
-
"spec/
|
47
|
-
"spec/keytar/keytar_spec.rb",
|
43
|
+
"spec/keytar_spec.rb",
|
48
44
|
"spec/spec_helper.rb"
|
49
45
|
]
|
50
46
|
|
data/lib/keytar.rb
CHANGED
@@ -1,10 +1,96 @@
|
|
1
1
|
require 'active_support/all'
|
2
|
-
autoload :KeyBuilder, 'keytar/key_builder'
|
3
2
|
|
4
3
|
module Keytar
|
5
4
|
extend ActiveSupport::Concern
|
5
|
+
DEFAULTS = {:delimiter => ":",
|
6
|
+
:order => [:shard, :prefix, :base, :name, :unique, :args, :suffix, :version, :v],
|
7
|
+
:pluralize_instances => true,
|
8
|
+
:key_case => :downcase,
|
9
|
+
:unique => :id}
|
6
10
|
|
7
|
-
|
8
|
-
|
11
|
+
|
12
|
+
# cannot change :order
|
13
|
+
# can change :unique
|
14
|
+
#
|
15
|
+
class Key
|
16
|
+
attr_accessor :delimiter, :order, :key_case, :options
|
17
|
+
def initialize(options = {})
|
18
|
+
options[:name] = options.delete(:name).to_s.gsub(/(^key$|_key$)/, '')
|
19
|
+
self.delimiter = options.delete(:delimiter)
|
20
|
+
self.order = options.delete(:order)
|
21
|
+
self.key_case = options.delete(:key_case)
|
22
|
+
self.options = options
|
23
|
+
end
|
24
|
+
|
25
|
+
def key_array
|
26
|
+
order.map {|key| options[key]}.flatten.compact.map(&:to_s)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
key = key_array.join(delimiter)
|
31
|
+
key = key.send key_case if key_case.present?
|
32
|
+
key
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.build(options = {})
|
36
|
+
self.new(options).to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def self.define_key_class_method_on(base, options = {})
|
42
|
+
(class << base;self ;end).instance_eval do
|
43
|
+
define_method("#{options[:name]}_key") do |*args|
|
44
|
+
build_key(options.merge(:args => args))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.define_key_instance_method_on(base, options)
|
50
|
+
base.class_eval do
|
51
|
+
define_method("#{options[:name]}_key") do |*args|
|
52
|
+
build_key(options.merge(:args => args))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# class methods to be extended
|
58
|
+
module ClassMethods
|
59
|
+
# sets up configuration options for individual keys
|
60
|
+
# alows us to define the keys without calling method missing
|
61
|
+
def define_keys(*args)
|
62
|
+
# coherce args into meaningful things
|
63
|
+
names = []; options = {}; args.each {|arg| arg.is_a?(Hash) ? options = arg : names << arg}
|
64
|
+
names.each do |name|
|
65
|
+
name = name.to_s.gsub(/(^key$|_key$)/, '')
|
66
|
+
Keytar.define_key_class_method_on(self, options.merge(:name => name))
|
67
|
+
Keytar.define_key_instance_method_on(self, options.merge(:name => name))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
alias :define_key :define_keys
|
71
|
+
|
72
|
+
|
73
|
+
# a way to define class level configurations for keytar using a hash
|
74
|
+
def key_config(options = {})
|
75
|
+
options[:base] = self
|
76
|
+
@key_config ||= options.reverse_merge(Keytar::DEFAULTS)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Call Keytar.build_key or Foo.build_key with options
|
80
|
+
# :base => self.to_s.downcase, :name => method_name, :args => args
|
81
|
+
def build_key(options = {})
|
82
|
+
input = options.reverse_merge(key_config)
|
83
|
+
input.delete(:unique) # class methods don't have a unique key
|
84
|
+
Key.build(input)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# build_key method for instances by default class is pluralized to create different key
|
89
|
+
def build_key(options = {})
|
90
|
+
options.reverse_merge!(self.class.key_config)
|
91
|
+
unique = method(options[:unique].to_sym).call if respond_to?(options[:unique].to_sym)
|
92
|
+
options[:base] = options[:base].to_s.pluralize unless options[:pluralize_instances].blank?
|
93
|
+
options[:unique] = unique && unique == object_id ? nil : unique
|
94
|
+
Key.build(options)
|
9
95
|
end
|
10
96
|
end
|
data/spec/keytar_spec.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
## Gives us ActiveRecord backed model Bar that we can test instances of
|
4
|
+
ActiveRecord::Base.establish_connection(
|
5
|
+
:adapter => "sqlite3",
|
6
|
+
:database => ":memory:",
|
7
|
+
:host => 'localhost')
|
8
|
+
|
9
|
+
ActiveRecord::Schema.define do
|
10
|
+
create_table :bars do |t|
|
11
|
+
t.string :name, :null => false
|
12
|
+
end
|
13
|
+
create_table :bar_bazs do |t|
|
14
|
+
t.string :name, :null => false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Foo
|
19
|
+
include Keytar
|
20
|
+
define_key :awesome
|
21
|
+
end
|
22
|
+
|
23
|
+
class Bar < ActiveRecord::Base
|
24
|
+
include Keytar
|
25
|
+
define_key :awesome
|
26
|
+
end
|
27
|
+
|
28
|
+
class BarNonActiveRecord
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
class BarBaz < ActiveRecord::Base
|
33
|
+
end
|
34
|
+
|
35
|
+
describe Keytar do
|
36
|
+
describe 'class and instance interference' do
|
37
|
+
it 'should not happen' do
|
38
|
+
bar = Bar.create(:name => "whatever")
|
39
|
+
orig_key = Bar.awesome_key(bar.id)
|
40
|
+
bar.awesome_key(bar.id)
|
41
|
+
second_key = Bar.awesome_key(bar.id)
|
42
|
+
second_key.should eq(orig_key)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'define_key' do
|
47
|
+
|
48
|
+
it 'allows us to pre-define instance methods' do
|
49
|
+
Foo.define_key(:cached_instance_method, :delimiter => "|", :version => "3")
|
50
|
+
@foo = Foo.new
|
51
|
+
@foo.respond_to?(:cached_instance_method_key).should be_true
|
52
|
+
@foo.cached_instance_method_key.should == "foos|cached_instance_method|3"
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'taking an array' do
|
56
|
+
it 'allows us to pre-define multiple class key methods' do
|
57
|
+
Foo.define_key(:m1, :m2, :m3, :delimiter => ":", :key_prefix => "foo")
|
58
|
+
Foo.respond_to?(:m1_key).should be_true
|
59
|
+
Foo.respond_to?(:m2_key).should be_true
|
60
|
+
Foo.respond_to?(:m3_key).should be_true
|
61
|
+
@foo = Foo.new
|
62
|
+
@foo.respond_to?(:m1_key).should be_true
|
63
|
+
@foo.respond_to?(:m2_key).should be_true
|
64
|
+
@foo.respond_to?(:m3_key).should be_true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'class methods on Foo' do
|
70
|
+
it 'should respond to "awesome_key" method by returning :class, :delimiter, :name' do
|
71
|
+
Foo.awesome_key.should == "foo:awesome"
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should respond to "awesome_key(number)" method by returning :class, :delimiter, :name, :delimiter, :arg' do
|
75
|
+
number = rand(100)
|
76
|
+
Foo.awesome_key(number).should == "foo:awesome:#{number}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
describe 'Foo instance methods' do
|
82
|
+
before(:each) do
|
83
|
+
@foo = Foo.new
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should respond to "awesome_key" method by returning :class, :delimiter, :name' do
|
87
|
+
@foo.awesome_key.should == "foos:awesome"
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should respond to "awesome_key(number)" method by returning :class, :delimiter, :name, :delimiter, :arg' do
|
91
|
+
number = rand(100)
|
92
|
+
@foo.awesome_key(number).should == "foos:awesome:#{number}"
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should call method_missing on a non-existant method' do
|
96
|
+
lambda{ @foo.thismethoddoesnotexist }.should raise_error(NoMethodError)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
describe 'requiring Keytar' do
|
104
|
+
it 'should allow ActiveRecord based objects to use their unique identifiers' do
|
105
|
+
name = "notblank"
|
106
|
+
b = Bar.create(:name => name)
|
107
|
+
b.name.should == name
|
108
|
+
b.awesome_key.should == "bars:awesome:#{b.id}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe 'requiring Keytar with ActiveRecord undefined' do
|
113
|
+
it 'does not automatically add Keytar to the class' do
|
114
|
+
describe BarNonActiveRecord.ancestors do
|
115
|
+
it {should_not include( Keytar)}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe 'allows non ActiveRecord based classes to use keytar directly' do
|
120
|
+
it 'includes Keytar when it is included' do
|
121
|
+
BarNonActiveRecord.class_eval do
|
122
|
+
include Keytar
|
123
|
+
define_key :awesome
|
124
|
+
end
|
125
|
+
describe BarNonActiveRecord.ancestors do
|
126
|
+
it {should include( Keytar)}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should allow ActiveRecord based objects to use their unique identifiers' do
|
131
|
+
BarNonActiveRecord.awesome_key.should == "barnonactiverecord:awesome"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "keytar should not over-ride default method_missing for AR" do
|
137
|
+
before do
|
138
|
+
b = BarBaz.create(:name => "something")
|
139
|
+
@id = b.id
|
140
|
+
Object.instance_eval{ remove_const :BarBaz } ## AR caches methods on object on create, need to pull it from disk
|
141
|
+
class BarBaz < ActiveRecord::Base
|
142
|
+
include Keytar
|
143
|
+
define_key :foo_key
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'does not interfere with how ActiveRecord generates methods based on column names' do
|
148
|
+
BarBaz.last.id.should == @id
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keytar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
8
|
+
- 5
|
9
9
|
- 1
|
10
|
-
version: 1.
|
10
|
+
version: 1.5.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Schneems
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-12 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
requirement: &id001 !ruby/object:Gem::Requirement
|
@@ -121,7 +121,7 @@ dependencies:
|
|
121
121
|
name: rspec
|
122
122
|
prerelease: false
|
123
123
|
type: :development
|
124
|
-
description: "\n
|
124
|
+
description: "\n Use Keytar to automatically generate keys based on class name instead of cluttering model\n definitions with tons of redundant key method declarations.\n "
|
125
125
|
email: richard.schneeman@gmail.com
|
126
126
|
executables: []
|
127
127
|
|
@@ -141,10 +141,8 @@ files:
|
|
141
141
|
- keytar.gemspec
|
142
142
|
- lib/.DS_Store
|
143
143
|
- lib/keytar.rb
|
144
|
-
- lib/keytar/key_builder.rb
|
145
144
|
- license.txt
|
146
|
-
- spec/
|
147
|
-
- spec/keytar/keytar_spec.rb
|
145
|
+
- spec/keytar_spec.rb
|
148
146
|
- spec/spec_helper.rb
|
149
147
|
homepage: http://github.com/Schnems/keytar
|
150
148
|
licenses:
|
@@ -180,6 +178,5 @@ signing_key:
|
|
180
178
|
specification_version: 3
|
181
179
|
summary: A crazy simple library for building keys (in _key_ value store, not house keys) for Ruby on Rails
|
182
180
|
test_files:
|
183
|
-
- spec/
|
184
|
-
- spec/keytar/keytar_spec.rb
|
181
|
+
- spec/keytar_spec.rb
|
185
182
|
- spec/spec_helper.rb
|
data/lib/keytar/key_builder.rb
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
module KeyBuilder
|
2
|
-
DEFAULTS = {:key_delimiter => ":",
|
3
|
-
:key_order => [:shard, :prefix, :base, :name, :unique, :args, :suffix, :version, :v],
|
4
|
-
:key_prefix => nil,
|
5
|
-
:key_suffix => nil,
|
6
|
-
:key_pluralize_instances => true,
|
7
|
-
:key_case => :downcase,
|
8
|
-
:key_plural => nil,
|
9
|
-
:key_unique => "id"}
|
10
|
-
|
11
|
-
def self.included(klass)
|
12
|
-
# setup method missing on class
|
13
|
-
klass.class_eval do
|
14
|
-
extend KeyBuilder::Ext
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# class methods to be extended
|
19
|
-
module Ext
|
20
|
-
# creates class level getter and setter methods for the defaults for config
|
21
|
-
DEFAULTS.keys.each do |key|
|
22
|
-
# TODO: re-write without eval
|
23
|
-
eval %{
|
24
|
-
def #{key}(#{key}_input = :key_default)
|
25
|
-
@@#{key} = DEFAULTS[:#{key}] unless defined? @@#{key}
|
26
|
-
@@#{key} = #{key}_input unless #{key}_input == :key_default
|
27
|
-
return @@#{key}
|
28
|
-
end
|
29
|
-
}
|
30
|
-
end
|
31
|
-
|
32
|
-
# sets up configuration options for individual keys
|
33
|
-
# alows us to define the keys without calling method missing
|
34
|
-
def cache_key( *args)
|
35
|
-
# coherce args into meaningful things
|
36
|
-
names = []; options = {}; args.each {|arg| arg.is_a?(Hash) ? options = arg : names << arg}
|
37
|
-
options.merge!(:name => name, :base => self.to_s.downcase)
|
38
|
-
|
39
|
-
# allow for loose naming of keys configuration symbols can use :key_prefix or just :prefix
|
40
|
-
options.keys.each do |key|
|
41
|
-
options["key_#{key}".to_sym] = options[key] if key.to_s !~ /^key_/
|
42
|
-
end
|
43
|
-
names.each do |name|
|
44
|
-
# define (cache) class method
|
45
|
-
(class << self;self ;end).instance_eval do
|
46
|
-
define_method("#{name}_key") do |*args|
|
47
|
-
build_options = options.merge(:name => name, :base => self.to_s.downcase, :args => args)
|
48
|
-
build_key(build_options)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# define (cache) instance method
|
53
|
-
class_eval do
|
54
|
-
define_method("#{name}_key") do |*args|
|
55
|
-
build_options = options.merge(:name => name, :args => args)
|
56
|
-
build_key(build_options)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
alias :cache_keys :cache_key
|
62
|
-
alias :define_key :cache_key
|
63
|
-
alias :define_keys :cache_key
|
64
|
-
|
65
|
-
# a way to define configurations for keytar using a hash
|
66
|
-
def key_config(options = {})
|
67
|
-
# allow for loose naming of keys configuration symbols can use :key_prefix or just :prefix
|
68
|
-
options.keys.each do |key|
|
69
|
-
options["key_#{key}".to_sym] = options[key] if key.to_s !~ /^key_/
|
70
|
-
end
|
71
|
-
options.each do |key, value|
|
72
|
-
self.send( key , value) if self.respond_to? key
|
73
|
-
end
|
74
|
-
end
|
75
|
-
alias :keyfig :key_config
|
76
|
-
|
77
|
-
# Call KeyBuilder.build_key or Foo.build_key with options
|
78
|
-
# :base => self.to_s.downcase, :name => method_name, :args => args
|
79
|
-
def build_key(options = {})
|
80
|
-
key_hash = build_key_hash(options)
|
81
|
-
key_array = key_hash_to_ordered_array(key_hash)
|
82
|
-
return key_from_array(key_array, options)
|
83
|
-
end
|
84
|
-
|
85
|
-
# takes input options and turns to a hash, which can be sorted based on key
|
86
|
-
def build_key_hash(options)
|
87
|
-
options[:name] = options[:name].to_s.gsub(/(^key$|_key$)/, '')
|
88
|
-
{:prefix => options[:key_prefix]||self.key_prefix,
|
89
|
-
:suffix => options[:key_suffix]||self.key_suffix}.merge(options)
|
90
|
-
end
|
91
|
-
|
92
|
-
# orders the elements based on defaults or config
|
93
|
-
def key_hash_to_ordered_array(key_hash)
|
94
|
-
key_array ||= []
|
95
|
-
(key_hash[:key_order]||self.key_order).each do |key|
|
96
|
-
if key != :args
|
97
|
-
key_array << key_hash[key]
|
98
|
-
else
|
99
|
-
key_array << key_hash[key].map(&:to_s) unless key_hash[key].blank?
|
100
|
-
end
|
101
|
-
end
|
102
|
-
return key_array
|
103
|
-
end
|
104
|
-
|
105
|
-
# applys a delimter and appropriate case to final key
|
106
|
-
def key_from_array(key_array, options = {})
|
107
|
-
key = key_array.flatten.reject {|item| item.blank? }.join(options[:key_delimiter]||self.key_delimiter)
|
108
|
-
key_case = options[:key_case] || self.key_case
|
109
|
-
key = key.downcase if key_case == :downcase
|
110
|
-
key = key.upcase if key_case == :upcase
|
111
|
-
key
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# build_key method for instances by default class is pluralized to create different key
|
116
|
-
def build_key(options = {})
|
117
|
-
options[:base] = options[:base]||self.class.to_s.downcase
|
118
|
-
if (options[:key_pluralize_instances] == true ) || (options[:key_pluralize_instances] != false && self.class.key_pluralize_instances.present?)
|
119
|
-
options[:base] = options[:key_plural]||self.class.key_plural||options[:base].pluralize
|
120
|
-
end
|
121
|
-
unique = self.send "#{options[:key_unique]||self.class.key_unique}".to_sym
|
122
|
-
options[:unique] = unique unless unique == object_id
|
123
|
-
self.class.build_key(options)
|
124
|
-
end
|
125
|
-
end
|
@@ -1,173 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class Foo
|
4
|
-
include Keytar
|
5
|
-
|
6
|
-
def ymd
|
7
|
-
Time.now.strftime("%y%m%d")
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
describe KeyBuilder do
|
12
|
-
describe 'build_key class method' do
|
13
|
-
before do
|
14
|
-
@options = {:name => "foo", :args => nil}
|
15
|
-
end
|
16
|
-
|
17
|
-
describe 'manually build key' do
|
18
|
-
it 'works' do
|
19
|
-
foo = Foo.new
|
20
|
-
foo.build_key(:name => "method", :args => "args").should eq("foos:method:args")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe 'build_key' do
|
25
|
-
it 'calls other class methods' do
|
26
|
-
Foo.should_receive(:build_key_hash)
|
27
|
-
Foo.should_receive(:key_hash_to_ordered_array)
|
28
|
-
Foo.should_receive(:key_from_array)
|
29
|
-
Foo.build_key(@options)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe 'build_key_hash' do
|
34
|
-
it 'removes key and _key from the :name option' do
|
35
|
-
Foo.build_key_hash(@options.merge(:name => "foo_key"))[:name].should == "foo"
|
36
|
-
Foo.build_key_hash(@options.merge(:name => "key"))[:name].should == ""
|
37
|
-
Foo.build_key_hash(@options.merge(:name => "fookey"))[:name].should == "fookey"
|
38
|
-
end
|
39
|
-
|
40
|
-
describe 'prefix' do
|
41
|
-
it 'takes in prefix converts key_prefix to prefix' do
|
42
|
-
prefix = "prefix"
|
43
|
-
Foo.build_key_hash(@options.merge(:key_prefix => prefix))[:prefix].should == prefix
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'favors direct options over class settings' do
|
47
|
-
prefix = "prefix"
|
48
|
-
Foo.should_not_receive(:key_prefix)
|
49
|
-
Foo.build_key_hash(@options.merge(:key_prefix => prefix))[:prefix].should == prefix
|
50
|
-
end
|
51
|
-
|
52
|
-
it "defaults to class settings when no direct option is given" do
|
53
|
-
prefix = "classPrefix"
|
54
|
-
Foo.should_receive(:key_prefix).and_return(prefix)
|
55
|
-
Foo.build_key_hash(@options)[:prefix].should == prefix
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "suffix" do
|
60
|
-
it 'takes in suffix and converts key_suffix to suffix' do
|
61
|
-
suffix = "sufix"
|
62
|
-
Foo.build_key_hash(@options.merge(:key_suffix => suffix))[:suffix].should == suffix
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'favors direct options over class settings' do
|
66
|
-
suffix = "suffix"
|
67
|
-
Foo.should_not_receive(:key_suffix)
|
68
|
-
Foo.build_key_hash(@options.merge(:key_suffix => suffix))[:suffix].should == suffix
|
69
|
-
end
|
70
|
-
|
71
|
-
it "defaults to class settings when no direct option is given" do
|
72
|
-
suffix = "classSuffix"
|
73
|
-
Foo.should_receive(:key_suffix).and_return(suffix)
|
74
|
-
Foo.build_key_hash(@options)[:suffix].should == suffix
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe 'key_hash_to_rdered_array' do
|
80
|
-
before do
|
81
|
-
@options.merge!(:prefix => "prefix", :base => "base", :name => "name", :suffix => "suffix", :version => 1)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "converts a hash to an array based on default order" do
|
85
|
-
Foo.key_hash_to_ordered_array(@options).should == [@options[:shard], @options[:prefix], @options[:base], @options[:name], @options[:unique], @options[:suffix], @options[:version], @options[:v]]
|
86
|
-
end
|
87
|
-
|
88
|
-
it "order output using direct option before class config" do
|
89
|
-
Foo.should_not_receive(:key_order)
|
90
|
-
key_order = [:prefix, :base, :name, :unique, :args, :suffix, :version, :v].reverse
|
91
|
-
Foo.key_hash_to_ordered_array(@options.merge(:key_order => key_order)).should == [@options[:prefix], @options[:base], @options[:name], @options[:unique], @options[:suffix], @options[:version], @options[:v]].reverse
|
92
|
-
end
|
93
|
-
|
94
|
-
it "convert each arg in args to a string" do
|
95
|
-
args = ["hey", 1 , "what", 2, "up", []]
|
96
|
-
Foo.key_hash_to_ordered_array(@options.merge(:args => args)).include?(args.map(&:to_s)).should be_true
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
describe 'key_from_array' do
|
101
|
-
before do
|
102
|
-
@key_array = ["foo", "Bar", "oH", "YEAH"]
|
103
|
-
end
|
104
|
-
|
105
|
-
it "strip out nil from the array and have no spaces" do
|
106
|
-
Foo.key_from_array([nil, nil]).match(/nil/).should be_false
|
107
|
-
Foo.key_from_array([nil, nil]).match(/\s/).should be_false
|
108
|
-
end
|
109
|
-
|
110
|
-
it "return a string" do
|
111
|
-
Foo.key_from_array(@key_array).class.should == String
|
112
|
-
end
|
113
|
-
|
114
|
-
it "keep the key case consistent (downcase by default)" do
|
115
|
-
Foo.key_from_array(@key_array).should == @key_array.map(&:downcase).join(":")
|
116
|
-
end
|
117
|
-
|
118
|
-
it "allow different cases to be passed in via options" do
|
119
|
-
Foo.should_not_receive(:key_case)
|
120
|
-
Foo.key_from_array(@key_array, :key_case => :upcase).should == @key_array.map(&:upcase).join(":")
|
121
|
-
end
|
122
|
-
|
123
|
-
it "flattens all inputs" do
|
124
|
-
array = @key_array << [[["1"], ["2"]],["3"]]
|
125
|
-
Foo.key_from_array(array, :key_case => :upcase).should == array.flatten.map(&:upcase).join(":")
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
describe 'build_key instance method' do
|
131
|
-
before do
|
132
|
-
@options = {:name => "foo", :args => nil}
|
133
|
-
@foo = Foo.new
|
134
|
-
end
|
135
|
-
|
136
|
-
describe 'build_key' do
|
137
|
-
it 'sets_base to class name and pluralizes it' do
|
138
|
-
@foo.class.should_receive(:build_key).with(hash_including(:base => @foo.class.to_s.downcase + "s"))
|
139
|
-
@foo.build_key(@options)
|
140
|
-
end
|
141
|
-
|
142
|
-
it 'allows a manual over-ride of base' do
|
143
|
-
base = "base"
|
144
|
-
@foo.class.should_receive(:build_key).with(hash_including(:base => base + "s"))
|
145
|
-
@foo.build_key(@options.merge(:base => base))
|
146
|
-
end
|
147
|
-
|
148
|
-
it "don't pluralize base if key_pluralize_instances is set to false" do
|
149
|
-
@foo.class.should_not_receive(:key_pluralize_instances)
|
150
|
-
@foo.class.should_receive(:build_key).with(hash_including(:base => @foo.class.to_s.downcase))
|
151
|
-
@foo.build_key(@options.merge(:key_pluralize_instances => false))
|
152
|
-
end
|
153
|
-
|
154
|
-
it "don't pluralize base if key_pluralize_instances is set to false" do
|
155
|
-
@foo.class.should_not_receive(:key_pluralize_instances)
|
156
|
-
@foo.class.should_receive(:build_key).with(hash_including(:base => @foo.class.to_s.downcase))
|
157
|
-
@foo.build_key(@options.merge(:key_pluralize_instances => false))
|
158
|
-
end
|
159
|
-
|
160
|
-
it "allow unique method to be passed in via options" do
|
161
|
-
@foo.class.should_not_receive(:key_unique)
|
162
|
-
@foo.class.should_receive(:build_key).with(hash_including(:unique => @foo.ymd))
|
163
|
-
@foo.build_key(@options.merge(:key_unique => :ymd))
|
164
|
-
end
|
165
|
-
|
166
|
-
it "set unique based on configuration" do
|
167
|
-
@foo.class.should_receive(:key_unique).at_least(:once).and_return("ymd")
|
168
|
-
@foo.class.should_receive(:build_key).with(hash_including(:unique => @foo.ymd))
|
169
|
-
@foo.build_key
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
data/spec/keytar/keytar_spec.rb
DELETED
@@ -1,270 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
## Gives us ActiveRecord backed model Bar that we can test instances of
|
4
|
-
ActiveRecord::Base.establish_connection(
|
5
|
-
:adapter => "sqlite3",
|
6
|
-
:database => ":memory:",
|
7
|
-
:host => 'localhost')
|
8
|
-
|
9
|
-
ActiveRecord::Schema.define do
|
10
|
-
create_table :bars do |t|
|
11
|
-
t.string :name, :null => false
|
12
|
-
end
|
13
|
-
create_table :bar_bazs do |t|
|
14
|
-
t.string :name, :null => false
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class Foo
|
19
|
-
include Keytar
|
20
|
-
define_key :awesome
|
21
|
-
end
|
22
|
-
|
23
|
-
class Bar < ActiveRecord::Base
|
24
|
-
include Keytar
|
25
|
-
define_key :awesome
|
26
|
-
end
|
27
|
-
|
28
|
-
class BarNonActiveRecord
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
class BarBaz < ActiveRecord::Base
|
33
|
-
end
|
34
|
-
|
35
|
-
describe Keytar do
|
36
|
-
describe 'class and instance interference' do
|
37
|
-
it 'should not happen' do
|
38
|
-
bar = Bar.create(:name => "whatever")
|
39
|
-
orig_key = Bar.awesome_key(bar.id)
|
40
|
-
bar.awesome_key(bar.id)
|
41
|
-
second_key = Bar.awesome_key(bar.id)
|
42
|
-
second_key.should eq(orig_key)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe 'cache_key' do
|
47
|
-
it 'allows us to pre-define class methods' do
|
48
|
-
Foo.cache_key(:cached_method, :delimiter => "/", :key_prefix => "woo")
|
49
|
-
Foo.respond_to?(:cached_method_key).should be_true
|
50
|
-
puts Foo.cached_method_key(22).should == "woo/foo/cached_method/22"
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'allows us to pre-define instance methods' do
|
54
|
-
Foo.cache_key(:cached_instance_method, :delimiter => "|", :version => "3")
|
55
|
-
@foo = Foo.new
|
56
|
-
@foo.respond_to?(:cached_instance_method_key).should be_true
|
57
|
-
@foo.cached_instance_method_key.should == "foos|cached_instance_method|3"
|
58
|
-
end
|
59
|
-
|
60
|
-
describe 'taking an array' do
|
61
|
-
it 'allows us to pre-define multiple class key methods' do
|
62
|
-
Foo.cache_key(:m1, :m2, :m3, :delimiter => ":", :key_prefix => "foo")
|
63
|
-
Foo.respond_to?(:m1_key).should be_true
|
64
|
-
Foo.respond_to?(:m2_key).should be_true
|
65
|
-
Foo.respond_to?(:m3_key).should be_true
|
66
|
-
@foo = Foo.new
|
67
|
-
@foo.respond_to?(:m1_key).should be_true
|
68
|
-
@foo.respond_to?(:m2_key).should be_true
|
69
|
-
@foo.respond_to?(:m3_key).should be_true
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe 'class methods' do
|
75
|
-
it 'should respond to "awesome_key" method by returning :class, :delimiter, :name' do
|
76
|
-
Foo.awesome_key.should == "foo:awesome"
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'should respond to "awesome_key(number)" method by returning :class, :delimiter, :name, :delimiter, :arg' do
|
80
|
-
number = rand(100)
|
81
|
-
Foo.awesome_key(number).should == "foo:awesome:#{number}"
|
82
|
-
end
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
it 'should call method_missing on a non-existant method' do
|
87
|
-
lambda{ Foo.thismethoddoesnotexist }.should raise_error(NoMethodError)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
|
92
|
-
describe 'instance methods' do
|
93
|
-
before(:each) do
|
94
|
-
@foo = Foo.new
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'should respond to "awesome_key" method by returning :class, :delimiter, :name' do
|
98
|
-
@foo.awesome_key.should == "foos:awesome"
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'should respond to "awesome_key(number)" method by returning :class, :delimiter, :name, :delimiter, :arg' do
|
102
|
-
number = rand(100)
|
103
|
-
@foo.awesome_key(number).should == "foos:awesome:#{number}"
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'should call method_missing on a non-existant method' do
|
107
|
-
lambda{ @foo.thismethoddoesnotexist }.should raise_error(NoMethodError)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# test last
|
112
|
-
describe 'class configurations' do
|
113
|
-
after(:each) do
|
114
|
-
# todo find a better way of resetting all these values
|
115
|
-
Foo.key_delimiter KeyBuilder::DEFAULTS[:key_delimiter]
|
116
|
-
Foo.key_order KeyBuilder::DEFAULTS[:key_order]
|
117
|
-
Foo.key_prefix KeyBuilder::DEFAULTS[:key_prefix]
|
118
|
-
Foo.key_suffix KeyBuilder::DEFAULTS[:key_suffix]
|
119
|
-
Foo.key_pluralize_instances KeyBuilder::DEFAULTS[:key_pluralize_instances]
|
120
|
-
Foo.key_case KeyBuilder::DEFAULTS[:key_case]
|
121
|
-
Foo.key_plural KeyBuilder::DEFAULTS[:key_plural]
|
122
|
-
Foo.key_unique KeyBuilder::DEFAULTS[:key_unique]
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'should change key_delimiter' do
|
126
|
-
key_delimiter = "|"
|
127
|
-
Foo.key_delimiter key_delimiter
|
128
|
-
Foo.key_delimiter.should == key_delimiter
|
129
|
-
Foo.awesome_key.should == "foo#{key_delimiter}awesome"
|
130
|
-
end
|
131
|
-
|
132
|
-
|
133
|
-
it 'should change key_order' do
|
134
|
-
order_array = [:prefix, :name, :unique, :base, :args, :suffix]
|
135
|
-
Foo.key_order order_array
|
136
|
-
Foo.key_order.should == order_array
|
137
|
-
Foo.awesome_key.should == "awesome:foo"
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'should change key_prefix' do
|
141
|
-
key_prefix = "memcache"
|
142
|
-
Foo.key_prefix key_prefix
|
143
|
-
Foo.key_prefix.should == key_prefix
|
144
|
-
Foo.awesome_key.should == "#{key_prefix}:foo:awesome"
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'should change key_suffix' do
|
148
|
-
key_suffix = "slave"
|
149
|
-
Foo.key_suffix key_suffix
|
150
|
-
Foo.key_suffix.should == key_suffix
|
151
|
-
Foo.awesome_key.should == "foo:awesome:#{key_suffix}"
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'should change key_pluralize_instances' do
|
155
|
-
key_pluralize_instances = false
|
156
|
-
Foo.key_pluralize_instances key_pluralize_instances
|
157
|
-
Foo.key_pluralize_instances.should == key_pluralize_instances
|
158
|
-
foo = Foo.new
|
159
|
-
foo.awesome_key.should == "foo:awesome"
|
160
|
-
end
|
161
|
-
|
162
|
-
it 'should change key_case' do
|
163
|
-
key_case = :upcase
|
164
|
-
Foo.key_case key_case
|
165
|
-
Foo.key_case.should == key_case
|
166
|
-
Foo.awesome_key.should == "FOO:AWESOME"
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'should change key_plural' do
|
170
|
-
key_plural = "fooz"
|
171
|
-
Foo.key_plural key_plural
|
172
|
-
Foo.key_plural.should == key_plural
|
173
|
-
foo = Foo.new
|
174
|
-
foo.awesome_key.should == "fooz:awesome"
|
175
|
-
end
|
176
|
-
|
177
|
-
it 'should change key_unique' do
|
178
|
-
Foo.class_eval { def timeish; (Time.now.to_i * 0.01).floor.to_s; end}
|
179
|
-
key_unique = :timeish
|
180
|
-
Foo.key_unique key_unique
|
181
|
-
Foo.key_unique.should == key_unique
|
182
|
-
foo = Foo.new
|
183
|
-
foo.awesome_key.should include(foo.timeish)
|
184
|
-
end
|
185
|
-
|
186
|
-
# todo move tests and assertsions to seperate describe and it blocks
|
187
|
-
it 'should allow all configurations to be set using a hash' do
|
188
|
-
# variables
|
189
|
-
key_delimiter = "/"
|
190
|
-
key_order = [:prefix, :base, :suffix]
|
191
|
-
key_prefix = "before"
|
192
|
-
key_suffix = "after"
|
193
|
-
key_pluralize_instances = false
|
194
|
-
key_case = :upcase
|
195
|
-
key_plural = "zoosk"
|
196
|
-
key_unique = "doesn-t_apply_to_instance_methods"
|
197
|
-
# config
|
198
|
-
Foo.keyfig :delimiter => key_delimiter,
|
199
|
-
:order => key_order,
|
200
|
-
:prefix => key_prefix,
|
201
|
-
:suffix => key_suffix,
|
202
|
-
:pluralize_instances => key_pluralize_instances,
|
203
|
-
:case => key_case,
|
204
|
-
:plural => key_plural,
|
205
|
-
:unique => key_unique
|
206
|
-
# assertions
|
207
|
-
Foo.key_delimiter.should == key_delimiter
|
208
|
-
Foo.key_order.should == key_order
|
209
|
-
Foo.key_prefix.should == key_prefix
|
210
|
-
Foo.key_suffix.should == key_suffix
|
211
|
-
Foo.key_pluralize_instances.should == key_pluralize_instances
|
212
|
-
Foo.key_case.should == key_case
|
213
|
-
Foo.key_plural.should == key_plural
|
214
|
-
Foo.key_unique.should == key_unique
|
215
|
-
end
|
216
|
-
|
217
|
-
end
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
describe 'requiring Keytar' do
|
222
|
-
it 'should allow ActiveRecord based objects to use their unique identifiers' do
|
223
|
-
name = "notblank"
|
224
|
-
b = Bar.create(:name => name)
|
225
|
-
b.name.should == name
|
226
|
-
b.awesome_key.should == "bars:awesome:#{b.id}"
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
describe 'requiring Keytar with ActiveRecord undefined' do
|
231
|
-
it 'does not automatically add KeyBuilder to the class' do
|
232
|
-
describe BarNonActiveRecord.ancestors do
|
233
|
-
it {should_not include( KeyBuilder)}
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
describe 'allows non ActiveRecord based classes to use keytar directly' do
|
238
|
-
it 'includes keybuilder when it is included' do
|
239
|
-
BarNonActiveRecord.class_eval do
|
240
|
-
include Keytar
|
241
|
-
define_key :awesome
|
242
|
-
end
|
243
|
-
describe BarNonActiveRecord.ancestors do
|
244
|
-
it {should include( KeyBuilder)}
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'should allow ActiveRecord based objects to use their unique identifiers' do
|
249
|
-
BarNonActiveRecord.awesome_key.should == "barnonactiverecord:awesome"
|
250
|
-
end
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
describe "keytar should not over-ride default method_missing for AR" do
|
255
|
-
before do
|
256
|
-
b = BarBaz.create(:name => "something")
|
257
|
-
@id = b.id
|
258
|
-
Object.instance_eval{ remove_const :BarBaz } ## AR caches methods on object on create, need to pull it from disk
|
259
|
-
class BarBaz < ActiveRecord::Base
|
260
|
-
include Keytar
|
261
|
-
define_key :foo_key
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
it 'does not interfere with how ActiveRecord generates methods based on column names' do
|
266
|
-
BarBaz.last.id.should == @id
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
end
|