keytar 1.4.1 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|