keytar 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- ruby_string="ree-1.8.7-2011.03"
3
+ ruby_string="ruby-1.9.2-p180"
4
4
  gemset_name="keytar"
5
5
 
6
6
  if rvm list strings | grep -q "${ruby_string}" ; then
data/README.md CHANGED
@@ -4,10 +4,10 @@ Keytar
4
4
  **1.** A keyboard that is designed to be played standing up, like a guitar.
5
5
  **2.** A crazy simple ruby-on-rails library for making re-usable keys (the kind you use in key/value stores)
6
6
 
7
- KeyBuilder
7
+ It Builds Keys
8
8
  ----------
9
9
 
10
- Keytar is an amazingly easy way to auto-magically generate keys for all of your NOSQL key needs. Are you using Redis, Memcache, MongoDB, Cassandra, or another hot key-value store? Then use **keytar**! It automatically generates keys based on class name instead of cluttering model definitions with tons of redundant key method declarations.
10
+ Keytar is an amazingly easy way generate keys for all of your NOSQL key needs. Are you using Redis, Memcache, MongoDB, Cassandra, or another hot key-value store? Then use **keytar**! It auto-magically generates keys based on class name instead of cluttering model definitions with tons of redundant key method declarations.
11
11
 
12
12
  ___quit___ littering your code with junk like this:
13
13
 
@@ -22,7 +22,7 @@ Seriously, ___quit it___!
22
22
 
23
23
  Installation
24
24
  ------------
25
- In your Ruby on Rails Gemfile add
25
+ In your Gemfile add
26
26
 
27
27
  gem 'keytar'
28
28
 
@@ -30,19 +30,19 @@ then run
30
30
 
31
31
  bundle install
32
32
 
33
- now, you're good to go. Not using RoR? No worries, just drop `include Keytar` in any Ruby model you want.
33
+ Then drop `include Keytar` in any Ruby model you want and you're good to go
34
34
 
35
35
 
36
36
  Example:
37
37
  --------
38
- keytar auto-magically generates keys using method names ending in `"_key"` or simply "key".
38
+ keytar auto-magically generates keys using method names ending in `"_key"` or simply "key"
39
39
 
40
40
  User.key #=> "user"
41
41
  User.memcache_key #=> "user:memcache"
42
42
 
43
43
  u = User.new
44
44
  u.redis_key #=> "users:redis"
45
- u.redis_key("some_arguement") #=> "users:redis:some_arguement"
45
+ u.redis_key("some_argument") #=> "users:redis:some_argument"
46
46
 
47
47
  u = User.create(:id => 2)
48
48
  u.sweet_key #=> "users:sweet:2"
@@ -51,18 +51,33 @@ keytar auto-magically generates keys using method names ending in `"_key"` or si
51
51
 
52
52
  It's that simple
53
53
 
54
- Config
55
- ------
54
+ Configuration
55
+ -------------
56
+ Keys can be pre-defined and configured on a per key basis by calling **define\_keys**:
57
+
58
+ class User
59
+ include Keytar
60
+ define_keys [:zoolander, :something_about_mary, :tropic_thunder], :delimiter => "|", :version => 2
61
+ define_keys :cassandra, :delimiter => "/", :version => 3, :key_prefix => "lol"
62
+ end
63
+
64
+ User.respond_to? :zoolander_key #=> true
65
+ User.zoolander_key #=> "user|zoolander|2"
66
+
67
+ Where the first argument is the key (or keys) to be defined, and the second argument is a hash of configurations. Using **define\_keys** is the recommended configuration method.
56
68
 
57
- These options can be configured by passing in a hash to keyfig:
58
69
 
59
- class User < ActiveRecord::Base
60
- keyfig :key_delimiter => ":", :key_order => [:unique, :suffix], :key_prefix => "before"
70
+ options can also be configured per class by passing in a hash to **key_config**:
71
+
72
+ class User
73
+ include Keytar
74
+ key_config :key_delimiter => ":", :key_order => [:unique, :suffix], :key_prefix => "before"
61
75
  end
62
76
 
63
77
  Or by calling class methods
64
78
 
65
- class User < ActiveRecord::Base
79
+ class User
80
+ include Keytar
66
81
  key_delimiter ":"
67
82
  key_order [:prefix, :base, :name, :unique, :args, :suffix]
68
83
  key_prefix nil
@@ -72,9 +87,9 @@ Config Options Breakdown
72
87
  ------------------------
73
88
  Here is a run down of what each does
74
89
 
75
- **key_delimeter** sets the separating argument in keys
90
+ **key_delimiter** sets the separating argument in keys
76
91
 
77
- User.key_delimeter "|"
92
+ User.key_delimiter "|"
78
93
  user.redis_key #=> "users|redis"
79
94
 
80
95
 
@@ -92,17 +107,18 @@ By default all instance keys have an identifying unique element included in the
92
107
  user.redis_key #=> "users:redis:9"
93
108
 
94
109
  User.key_unique("username")
110
+ user.username #=> "schneems"
95
111
  user.redis_key #=> "users:redis:schneems"
96
112
 
97
- **key_prefix** sets the a prefix to your key for that class
113
+ **key_prefix** adds some text to the beginning of your key for that class
98
114
 
99
115
  User.key_prefix "woot"
100
- user.redis_key #=> "woot:users:redis"
116
+ User.redis_key #=> "woot:users:redis"
101
117
 
102
- **key_suffix** sets the a suffix to your key for that class
118
+ **key_suffix** adds some text to the end of your key for that class
103
119
 
104
120
  User.key_suffix "slave"
105
- user.redis_key #=> "users:redis:slave"
121
+ User.redis_key #=> "users:redis:slave"
106
122
 
107
123
  **`key_pluralize_instances`** allows you to toggle pluralizing instance keys (note the 's' in 'users' is not there)
108
124
 
@@ -118,12 +134,7 @@ By default all instance keys have an identifying unique element included in the
118
134
  **key_case** allows you to specify the case of your key
119
135
 
120
136
  User.key_case :upcase
121
- user.redis_key #=> "USERS:REDIS"
122
-
123
- **`key_cache_methods`** will let you toggle whether or not keytar defines your key methods after being called. If you're calling
124
- these methods over and over, this can give you a speed boost, however there is overhead associated with defining methods. The default
125
- is on, however try it both ways on your app run some benchmarks and see what works the best.
126
-
137
+ User.redis_key #=> "USER:REDIS"
127
138
 
128
139
 
129
140
  Since this library is sooooo simple, here is a ASCII keytar for you. Thanks for checking it out.
@@ -188,4 +199,4 @@ Fork away. If you want to chat about a feature idea, or a question you can find
188
199
 
189
200
 
190
201
  Copyright (c) 2011 Schneems. See LICENSE.txt for
191
- further details.
202
+ further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.0
1
+ 1.0.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{keytar}
8
- s.version = "0.9.0"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Schneems"]
12
- s.date = %q{2011-05-08}
12
+ s.date = %q{2011-05-16}
13
13
  s.description = %q{
14
14
  Keytar is a Ruby on Rails wrapper for KeyBuilder.
15
15
  Use KeyBuilder to automatically generate keys based on class name instead of cluttering model
@@ -20,40 +20,19 @@ Gem::Specification.new do |s|
20
20
  "README.md"
21
21
  ]
22
22
  s.files = [
23
- ".DS_Store",
24
23
  ".rvmrc",
25
24
  "Gemfile",
26
- "Gemfile.lock",
27
25
  "README.md",
28
26
  "Rakefile",
29
27
  "VERSION",
30
- "db/migrate/001_create_bars.rb",
31
28
  "keytar.gemspec",
32
29
  "lib/.DS_Store",
33
30
  "lib/keytar.rb",
34
31
  "lib/keytar/key_builder.rb",
35
32
  "license.txt",
36
- "pkg/keytar-0.1.0.gem",
37
- "pkg/keytar-0.1.1.gem",
38
33
  "spec/keytar/key_builder_spec.rb",
39
34
  "spec/keytar/keytar_spec.rb",
40
- "spec/keytar/spec_helper.rb",
41
- "vendor/cache/activemodel-3.0.6.gem",
42
- "vendor/cache/activerecord-3.0.6.gem",
43
- "vendor/cache/activesupport-3.0.6.gem",
44
- "vendor/cache/arel-2.0.9.gem",
45
- "vendor/cache/builder-2.1.2.gem",
46
- "vendor/cache/diff-lcs-1.1.2.gem",
47
- "vendor/cache/git-1.2.5.gem",
48
- "vendor/cache/i18n-0.5.0.gem",
49
- "vendor/cache/jeweler-1.5.2.gem",
50
- "vendor/cache/rake-0.8.7.gem",
51
- "vendor/cache/rspec-2.5.0.gem",
52
- "vendor/cache/rspec-core-2.5.1.gem",
53
- "vendor/cache/rspec-expectations-2.5.0.gem",
54
- "vendor/cache/rspec-mocks-2.5.0.gem",
55
- "vendor/cache/sqlite3-1.3.3.gem",
56
- "vendor/cache/tzinfo-0.3.26.gem"
35
+ "spec/keytar/spec_helper.rb"
57
36
  ]
58
37
  s.homepage = %q{http://github.com/Schnems/keytar}
59
38
  s.licenses = ["MIT"]
@@ -1,9 +1,6 @@
1
- require 'rubygems'
2
- begin; require 'active_record'; rescue; end
3
1
 
4
2
  module Keytar
5
3
  autoload :KeyBuilder, 'keytar/key_builder'
6
- ActiveRecord::Base.class_eval { include KeyBuilder } if defined?(ActiveRecord::Base)
7
4
  def self.included(klass)
8
5
  klass.class_eval {include KeyBuilder}
9
6
  end
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  require 'active_support/inflector' # used for pluralize
3
2
  require 'active_support/core_ext/object/blank' # used for blank? and present?
4
3
 
@@ -6,44 +5,23 @@ module KeyBuilder
6
5
  alias :original_method_missing :method_missing
7
6
 
8
7
  DEFAULTS = {:key_delimiter => ":",
9
- :key_order => [:prefix, :base, :name, :unique, :args, :suffix],
8
+ :key_order => [:prefix, :base, :name, :unique, :args, :suffix, :version, :v],
10
9
  :key_prefix => nil,
11
10
  :key_suffix => nil,
12
11
  :key_pluralize_instances => true,
13
12
  :key_case => :downcase,
14
13
  :key_plural => nil,
15
- :key_unique => "id",
16
- :key_cache_methods => true
17
- }
14
+ :key_unique => "id"}
18
15
 
19
16
  def self.included(klass)
20
17
  # setup method missing on class
21
18
  klass.class_eval do
22
19
  extend KeyBuilder::Ext
23
- # if method_missing doesn't already exist, aliasing and calling it will create an infinite loop
24
- @@key_builder_jump_to_superclass = true
25
- if klass.respond_to?("method_missing")
26
- @@key_builder_jump_to_superclass = false
27
- alias :key_builder_alias_method_missing :method_missing
28
- end
29
-
30
20
  def self.method_missing(method_name, *args, &blk)
31
21
  if method_name.to_s =~ /.*key$/
32
- ## Performance: define method so we can skip method_missing next time
33
- if key_cache_methods
34
- (class << self;self ;end).instance_eval do
35
- define_method(method_name) do |*args|
36
- build_key(:base => self.to_s.downcase, :name => method_name, :args => args)
37
- end
38
- end
39
- end
40
22
  self.build_key(:base => self.to_s.downcase, :name => method_name, :args => args)
41
23
  else
42
- if @@key_builder_jump_to_superclass
43
- super
44
- else
45
- key_builder_alias_method_missing(method_name, *args, &blk)
46
- end
24
+ super
47
25
  end
48
26
  end
49
27
  end
@@ -62,69 +40,101 @@ module KeyBuilder
62
40
  }
63
41
  end
64
42
 
65
- def keyfig(options = {})
43
+ # sets up configuration options for individual keys
44
+ # alows us to define the keys without calling method missing
45
+ def cache_key( *args)
46
+ # coherce args into meaningful things
47
+ names = []; options = {}; args.each {|arg| arg.is_a?(Hash) ? options = arg : names << arg}
48
+ options.merge!(:name => name, :base => self.to_s.downcase)
49
+
50
+ # allow for loose naming of keys configuration symbols can use :key_prefix or just :prefix
51
+ options.keys.each do |key|
52
+ options["key_#{key}".to_sym] = options[key] if key.to_s !~ /^key_/
53
+ end
54
+
55
+ names.each do |name|
56
+ # define (cache) class method
57
+ (class << self;self ;end).instance_eval do
58
+ define_method("#{name}_key") do |*args|
59
+ options.merge!(:name => name, :base => self.to_s.downcase, :args => args)
60
+ build_key(options)
61
+ end
62
+ end
63
+
64
+ # define (cache) instance method
65
+ class_eval do
66
+ define_method("#{name}_key") do |*args|
67
+ options.merge!(:name => name, :args => args)
68
+ build_key(options)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ alias :cache_keys :cache_key
74
+ alias :define_key :cache_key
75
+ alias :define_keys :cache_key
76
+
77
+ # a way to define configurations for keytar using a hash
78
+ def key_config(options = {})
66
79
  options.keys.each do |key|
67
80
  eval("@@#{key} = options[key]") if key.to_s =~ /^key_.*/
68
81
  end
69
82
  end
83
+ alias :keyfig :key_config
70
84
 
71
85
  # Call KeyBuilder.build_key or Foo.build_key with options
72
86
  # :base => self.to_s.downcase, :name => method_name, :args => args
73
87
  def build_key(options = {})
74
88
  key_hash = build_key_hash(options)
75
89
  key_array = key_hash_to_ordered_array(key_hash)
76
- return key_from_array(key_array)
90
+ return key_from_array(key_array, options)
77
91
  end
78
92
 
79
93
  # takes input options and turns to a hash, which can be sorted based on key
80
94
  def build_key_hash(options)
81
- options[:name] = options[:name].to_s.gsub(/(key|_key)/, '')
82
- options.merge :prefix => self.key_prefix, :suffix => self.key_suffix
95
+ options[:name] = options[:name].to_s.gsub(/(^key$|_key$)/, '')
96
+ {:prefix => options[:key_prefix]||self.key_prefix,
97
+ :suffix => options[:key_suffix]||self.key_suffix}.merge(options)
83
98
  end
84
99
 
85
100
  # orders the elements based on defaults or config
86
101
  def key_hash_to_ordered_array(key_hash)
87
102
  key_array ||= []
88
- self.key_order.each do |key|
103
+ (key_hash[:key_order]||self.key_order).each do |key|
89
104
  if key != :args
90
105
  key_array << key_hash[key]
91
106
  else
92
- key_array << key_hash[key].map(&:to_s)
107
+ key_array << key_hash[key].map(&:to_s) unless key_hash[key].blank?
93
108
  end
94
109
  end
95
110
  return key_array
96
111
  end
97
112
 
98
113
  # applys a delimter and appropriate case to final key
99
- def key_from_array(key_array)
100
- key = key_array.flatten.reject {|item| item.blank? }.join(self.key_delimiter)
101
- key = key.downcase if self.key_case == :downcase
102
- key = key.upcase if self.key_case == :upcase
114
+ def key_from_array(key_array, options = {})
115
+ key = key_array.flatten.reject {|item| item.blank? }.join(options[:key_delimiter]||self.key_delimiter)
116
+ key_case = options[:key_case] || self.key_case
117
+ key = key.downcase if key_case == :downcase
118
+ key = key.upcase if key_case == :upcase
103
119
  key
104
120
  end
105
121
  end
106
122
 
107
123
  # build_key method for instances by default class is pluralized to create different key
108
- def build_key(method_name, *args)
109
- base = self.class.to_s.downcase
110
- base = self.class.key_plural||base.pluralize if self.class.key_pluralize_instances.present?
111
- unique = eval("self.#{self.class.key_unique}") unless eval("self.#{self.class.key_unique}") == object_id
112
- self.class.build_key(:base => base, :name => method_name, :args => args, :unique => unique)
124
+ def build_key(options = {})
125
+ options[:base] = options[:base]||self.class.to_s.downcase
126
+ if (options[:key_pluralize_instances] == true ) || (options[:key_pluralize_instances] != false && self.class.key_pluralize_instances.present?)
127
+ options[:base] = options[:key_plural]||self.class.key_plural||options[:base].pluralize
128
+ end
129
+ options[:unique] = eval("self.#{options[:key_unique]||self.class.key_unique}") unless eval("self.#{options[:key_unique]||self.class.key_unique}") == object_id
130
+ self.class.build_key(options)
113
131
  end
114
132
 
115
133
 
116
134
 
117
135
  def method_missing(method_name, *args, &blk)
118
136
  if method_name.to_s =~ /.*key$/
119
- ## Performance: define method so we can skip method_missing next time
120
- if self.class.key_cache_methods
121
- self.class.instance_eval do
122
- define_method(method_name) do |*args|
123
- build_key(method_name, *args)
124
- end
125
- end
126
- end
127
- build_key(method_name, *args)
137
+ build_key(:name => method_name, :args => args)
128
138
  else
129
139
  original_method_missing(method_name, *args, &blk)
130
140
  end
@@ -1,203 +1,166 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
-
4
3
  class Foo
5
- include KeyBuilder
6
- end
4
+ include Keytar
7
5
 
6
+ def ymd
7
+ Time.now.strftime("%y%m%d")
8
+ end
9
+ end
8
10
 
9
11
  describe KeyBuilder do
10
-
11
- describe 'class methods' do
12
- it 'should respond to "key" method by returning downcase of class name' do
13
- Foo.key.should == "foo"
12
+ describe 'build_key class method' do
13
+ before do
14
+ @options = {:name => "foo", :args => nil}
14
15
  end
15
16
 
16
- it 'should respond to "awesome_key" method by returning :class, :delimiter, :name' do
17
- Foo.awesome_key.should == "foo:awesome"
17
+ describe 'build_key' do
18
+ it 'calls other class methods' do
19
+ Foo.should_receive(:build_key_hash)
20
+ Foo.should_receive(:key_hash_to_ordered_array)
21
+ Foo.should_receive(:key_from_array)
22
+ Foo.build_key(@options)
23
+ end
18
24
  end
19
25
 
20
- it 'should respond to "awesome_key(number)" method by returning :class, :delimiter, :name, :delimiter, :arg' do
21
- number = rand(100)
22
- Foo.awesome_key(number).should == "foo:awesome:#{number}"
23
- end
26
+ describe 'build_key_hash' do
27
+ it 'removes key and _key from the :name option' do
28
+ Foo.build_key_hash(@options.merge(:name => "foo_key"))[:name].should == "foo"
29
+ Foo.build_key_hash(@options.merge(:name => "key"))[:name].should == ""
30
+ Foo.build_key_hash(@options.merge(:name => "fookey"))[:name].should == "fookey"
31
+ end
24
32
 
25
- it 'should dynamically define a class method capeable of producing different keys' do
26
- key1 = Foo.define_method_time_test_key(1)
27
- key2 = Foo.define_method_time_test_key(2)
28
- Foo.respond_to?(:define_method_time_test_key).should be_true
29
- key2.should_not == key1
30
- end
33
+ describe 'prefix' do
34
+ it 'takes in prefix converts key_prefix to prefix' do
35
+ prefix = "prefix"
36
+ Foo.build_key_hash(@options.merge(:key_prefix => prefix))[:prefix].should == prefix
37
+ end
38
+
39
+ it 'favors direct options over class settings' do
40
+ prefix = "prefix"
41
+ Foo.should_not_receive(:key_prefix)
42
+ Foo.build_key_hash(@options.merge(:key_prefix => prefix))[:prefix].should == prefix
43
+ end
44
+
45
+ it "defaults to class settings when no direct option is given" do
46
+ prefix = "classPrefix"
47
+ Foo.should_receive(:key_prefix).and_return(prefix)
48
+ Foo.build_key_hash(@options)[:prefix].should == prefix
49
+ end
50
+ end
31
51
 
52
+ describe "suffix" do
53
+ it 'takes in suffix and converts key_suffix to suffix' do
54
+ suffix = "sufix"
55
+ Foo.build_key_hash(@options.merge(:key_suffix => suffix))[:suffix].should == suffix
56
+ end
57
+
58
+ it 'favors direct options over class settings' do
59
+ suffix = "suffix"
60
+ Foo.should_not_receive(:key_suffix)
61
+ Foo.build_key_hash(@options.merge(:key_suffix => suffix))[:suffix].should == suffix
62
+ end
63
+
64
+ it "defaults to class settings when no direct option is given" do
65
+ suffix = "classSuffix"
66
+ Foo.should_receive(:key_suffix).and_return(suffix)
67
+ Foo.build_key_hash(@options)[:suffix].should == suffix
68
+ end
69
+ end
70
+ end
32
71
 
72
+ describe 'key_hash_to_rdered_array' do
73
+ before do
74
+ @options.merge!(:prefix => "prefix", :base => "base", :name => "name", :suffix => "suffix", :version => 1)
75
+ end
33
76
 
34
- it 'should call method_missing on a non-existant method' do
35
- begin
36
- Foo.thismethoddoesnotexist
37
- rescue => ex
77
+ it "converts a hash to an array based on default order" do
78
+ Foo.key_hash_to_ordered_array(@options).should == [@options[:prefix], @options[:base], @options[:name], @options[:unique], @options[:suffix], @options[:version], @options[:v]]
38
79
  end
39
- ex.class.should == NoMethodError
40
- end
41
- end
42
80
 
81
+ it "order output using direct option before class config" do
82
+ Foo.should_not_receive(:key_order)
83
+ key_order = [:prefix, :base, :name, :unique, :args, :suffix, :version, :v].reverse
84
+ 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
85
+ end
43
86
 
44
- describe 'instance methods' do
45
- before(:each) do
46
- @foo = Foo.new
87
+ it "convert each arg in args to a string" do
88
+ args = ["hey", 1 , "what", 2, "up", []]
89
+ Foo.key_hash_to_ordered_array(@options.merge(:args => args)).include?(args.map(&:to_s)).should be_true
90
+ end
47
91
  end
48
92
 
49
- it 'should respond to "key" method by returning pluralized downcase of class name' do
50
- @foo.key.should == "foos"
51
- end
93
+ describe 'key_from_array' do
94
+ before do
95
+ @key_array = ["foo", "Bar", "oH", "YEAH"]
96
+ end
52
97
 
53
- it 'should respond to "awesome_key" method by returning :class, :delimiter, :name' do
54
- @foo.awesome_key.should == "foos:awesome"
55
- end
98
+ it "strip out nil from the array and have no spaces" do
99
+ Foo.key_from_array([nil, nil]).match(/nil/).should be_false
100
+ Foo.key_from_array([nil, nil]).match(/\s/).should be_false
101
+ end
56
102
 
57
- it 'should respond to "awesome_key(number)" method by returning :class, :delimiter, :name, :delimiter, :arg' do
58
- number = rand(100)
59
- @foo.awesome_key(number).should == "foos:awesome:#{number}"
60
- end
103
+ it "return a string" do
104
+ Foo.key_from_array(@key_array).class.should == String
105
+ end
61
106
 
62
- it 'should dynamically define an instance method capeable of producing different keys' do
63
- key1 = @foo.define_method_time_test_key(1)
64
- key2 = @foo.define_method_time_test_key(2)
65
- @foo.respond_to?(:define_method_time_test_key).should be_true
66
- key2.should_not == key1
67
- end
107
+ it "keep the key case consistent (downcase by default)" do
108
+ Foo.key_from_array(@key_array).should == @key_array.map(&:downcase).join(":")
109
+ end
68
110
 
69
- it 'should dynamically define an instance method capeable of producing different keys' do
70
- key1 = @foo.define_method_time_test_key(1)
71
- key2 = @foo.define_method_time_test_key(2)
72
- @foo.respond_to?(:define_method_time_test_key).should be_true
73
- key2.should_not == key1
74
- end
111
+ it "allow different cases to be passed in via options" do
112
+ Foo.should_not_receive(:key_case)
113
+ Foo.key_from_array(@key_array, :key_case => :upcase).should == @key_array.map(&:upcase).join(":")
114
+ end
75
115
 
76
- it 'should call method_missing on a non-existant method' do
77
- begin
78
- @foo.thismethoddoesnotexist
79
- rescue => ex
116
+ it "flattens all inputs" do
117
+ array = @key_array << [[["1"], ["2"]],["3"]]
118
+ Foo.key_from_array(array, :key_case => :upcase).should == array.flatten.map(&:upcase).join(":")
80
119
  end
81
- ex.class.should == NoMethodError
82
120
  end
83
121
  end
84
122
 
85
- # test last
86
- describe 'class configurations' do
87
- after(:each) do
88
- # todo find a better way of resetting all these values
89
- Foo.key_delimiter KeyBuilder::DEFAULTS[:key_delimiter]
90
- Foo.key_order KeyBuilder::DEFAULTS[:key_order]
91
- Foo.key_prefix KeyBuilder::DEFAULTS[:key_prefix]
92
- Foo.key_suffix KeyBuilder::DEFAULTS[:key_suffix]
93
- Foo.key_pluralize_instances KeyBuilder::DEFAULTS[:key_pluralize_instances]
94
- Foo.key_case KeyBuilder::DEFAULTS[:key_case]
95
- Foo.key_plural KeyBuilder::DEFAULTS[:key_plural]
96
- Foo.key_unique KeyBuilder::DEFAULTS[:key_unique]
97
- Foo.key_cache_methods KeyBuilder::DEFAULTS[:key_cache_methods]
98
- end
99
-
100
- it 'should change key_delimiter' do
101
- key_delimiter = "|"
102
- Foo.key_delimiter key_delimiter
103
- Foo.key_delimiter.should == key_delimiter
104
- Foo.awesome_key.should == "foo#{key_delimiter}awesome"
123
+ describe 'build_key instance method' do
124
+ before do
125
+ @options = {:name => "foo", :args => nil}
126
+ @foo = Foo.new
105
127
  end
106
128
 
129
+ describe 'build_key' do
130
+ it 'sets_base to class name and pluralizes it' do
131
+ @foo.class.should_receive(:build_key).with(hash_including(:base => @foo.class.to_s.downcase + "s"))
132
+ @foo.build_key(@options)
133
+ end
107
134
 
108
- it 'should change key_order' do
109
- order_array = [:prefix, :name, :unique, :base, :args, :suffix]
110
- Foo.key_order order_array
111
- Foo.key_order.should == order_array
112
- Foo.awesome_key.should == "awesome:foo"
113
- end
135
+ it 'allows a manual over-ride of base' do
136
+ base = "base"
137
+ @foo.class.should_receive(:build_key).with(hash_including(:base => base + "s"))
138
+ @foo.build_key(@options.merge(:base => base))
139
+ end
114
140
 
115
- it 'should change key_prefix' do
116
- key_prefix = "memcache"
117
- Foo.key_prefix key_prefix
118
- Foo.key_prefix.should == key_prefix
119
- Foo.awesome_key.should == "#{key_prefix}:foo:awesome"
120
- end
141
+ it "don't pluralize base if key_pluralize_instances is set to false" do
142
+ @foo.class.should_not_receive(:key_pluralize_instances)
143
+ @foo.class.should_receive(:build_key).with(hash_including(:base => @foo.class.to_s.downcase))
144
+ @foo.build_key(@options.merge(:key_pluralize_instances => false))
145
+ end
121
146
 
122
- it 'should change key_suffix' do
123
- key_suffix = "slave"
124
- Foo.key_suffix key_suffix
125
- Foo.key_suffix.should == key_suffix
126
- Foo.awesome_key.should == "foo:awesome:#{key_suffix}"
127
- end
147
+ it "don't pluralize base if key_pluralize_instances is set to false" do
148
+ @foo.class.should_not_receive(:key_pluralize_instances)
149
+ @foo.class.should_receive(:build_key).with(hash_including(:base => @foo.class.to_s.downcase))
150
+ @foo.build_key(@options.merge(:key_pluralize_instances => false))
151
+ end
128
152
 
129
- it 'should change key_pluralize_instances' do
130
- key_pluralize_instances = false
131
- Foo.key_pluralize_instances key_pluralize_instances
132
- Foo.key_pluralize_instances.should == key_pluralize_instances
133
- foo = Foo.new
134
- foo.awesome_key.should == "foo:awesome"
135
- end
136
-
137
- it 'should change key_case' do
138
- key_case = :upcase
139
- Foo.key_case key_case
140
- Foo.key_case.should == key_case
141
- Foo.awesome_key.should == "FOO:AWESOME"
142
- end
143
-
144
- it 'should change key_plural' do
145
- key_plural = "fooz"
146
- Foo.key_plural key_plural
147
- Foo.key_plural.should == key_plural
148
- foo = Foo.new
149
- foo.awesome_key.should == "fooz:awesome"
150
- end
151
-
152
- it 'should change key_unique' do
153
- Foo.class_eval { def timeish; (Time.now.to_i * 0.01).floor; end}
154
- key_unique = :timeish
155
- Foo.key_unique key_unique
156
- Foo.key_unique.should == key_unique
157
- foo = Foo.new
158
- foo.awesome_key.should == "foos:awesome:#{foo.timeish}"
159
- end
160
-
161
- # todo move tests and assertsions to seperate describe and it blocks
162
- it 'should allow all configurations to be set using a hash' do
163
- # variables
164
- key_delimiter = "/"
165
- key_order = [:prefix, :base, :suffix]
166
- key_prefix = "before"
167
- key_suffix = "after"
168
- key_pluralize_instances = false
169
- key_case = :upcase
170
- key_plural = "zoosk"
171
- key_unique = "doesn-t_apply_to_instance_methods"
172
- key_cache_methods = false
173
- # config
174
- Foo.keyfig :key_delimiter => key_delimiter,
175
- :key_order => key_order,
176
- :key_prefix => key_prefix,
177
- :key_suffix => key_suffix,
178
- :key_pluralize_instances => key_pluralize_instances,
179
- :key_case => key_case,
180
- :key_plural => key_plural,
181
- :key_unique => key_unique,
182
- :key_cache_methods => key_cache_methods
183
- # assertions
184
- Foo.key_delimiter.should == key_delimiter
185
- Foo.key_order.should == key_order
186
- Foo.key_prefix.should == key_prefix
187
- Foo.key_suffix.should == key_suffix
188
- Foo.key_pluralize_instances.should == key_pluralize_instances
189
- Foo.key_case.should == key_case
190
- Foo.key_plural.should == key_plural
191
- Foo.key_unique.should == key_unique
192
- Foo.key_cache_methods == key_cache_methods
193
- end
194
-
195
- it 'should change key_cache_methods' do
196
- Foo.key_cache_methods false
197
- key1 = Foo.config_define_method_time_test_key(1)
198
- Foo.respond_to?(:config_define_method_time_test_key).should be_false
199
- end
153
+ it "allow unique method to be passed in via options" do
154
+ @foo.class.should_not_receive(:key_unique)
155
+ @foo.class.should_receive(:build_key).with(hash_including(:unique => @foo.ymd))
156
+ @foo.build_key(@options.merge(:key_unique => :ymd))
157
+ end
200
158
 
159
+ it "set unique based on configuration" do
160
+ @foo.class.should_receive(:key_unique).at_least(:once).and_return("ymd")
161
+ @foo.class.should_receive(:build_key).with(hash_including(:unique => @foo.ymd))
162
+ @foo.build_key
163
+ end
164
+ end
201
165
  end
202
-
203
166
  end
@@ -1,17 +1,23 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
2
3
  ## Gives us ActiveRecord backed model Bar that we can test instances of
3
4
  ActiveRecord::Base.establish_connection(
4
5
  :adapter => "sqlite3",
5
6
  :database => ":memory:",
6
7
  :host => 'localhost')
7
8
 
8
- ## Gives us ActiveRecord backed model Bar that we can test instances of
9
- ActiveRecord::Migrator.migrate(
10
- File.expand_path(File.dirname(__FILE__) + "../../../db/migrate") ,
11
- ENV["VERSION"] ? ENV["VERSION"].to_i : nil )
9
+ ActiveRecord::Schema.define do
10
+ create_table :bars do |t|
11
+ t.string :name, :null => false
12
+ end
13
+ end
12
14
 
13
- class Bar < ActiveRecord::Base
15
+ class Foo
16
+ include Keytar
17
+ end
14
18
 
19
+ class Bar < ActiveRecord::Base
20
+ include Keytar
15
21
  end
16
22
 
17
23
  class BarNonActiveRecord
@@ -20,13 +26,191 @@ end
20
26
 
21
27
 
22
28
  describe Keytar do
23
- describe 'requiring Keytar' do
24
- it 'should load keybuilder into ActiveRecord::Base if defined' do
25
- describe Bar.ancestors do
26
- it {should include( KeyBuilder)}
29
+
30
+ describe 'cache_key' do
31
+ it 'allows us to pre-define class methods' do
32
+ Foo.cache_key(:cached_method, :delimiter => "/", :key_prefix => "woo")
33
+ Foo.respond_to?(:cached_method_key).should be_true
34
+ puts Foo.cached_method_key(22).should == "woo/foo/cached_method/22"
35
+ end
36
+
37
+ it 'allows us to pre-define instance methods' do
38
+ Foo.cache_key(:cached_instance_method, :delimiter => "|", :version => "3")
39
+ @foo = Foo.new
40
+ @foo.respond_to?(:cached_instance_method_key).should be_true
41
+ @foo.cached_instance_method_key.should == "foos|cached_instance_method|3"
42
+ end
43
+
44
+ describe 'taking an array' do
45
+ it 'allows us to pre-define multiple class key methods' do
46
+ Foo.cache_key(:m1, :m2, :m3, :delimiter => ":", :key_prefix => "foo")
47
+ Foo.respond_to?(:m1_key).should be_true
48
+ Foo.respond_to?(:m2_key).should be_true
49
+ Foo.respond_to?(:m3_key).should be_true
50
+ @foo = Foo.new
51
+ @foo.respond_to?(:m1_key).should be_true
52
+ @foo.respond_to?(:m2_key).should be_true
53
+ @foo.respond_to?(:m3_key).should be_true
27
54
  end
28
55
  end
56
+ end
57
+
58
+ describe 'class methods' do
59
+ it 'should respond to "key" method by returning downcase of class name' do
60
+ Foo.key.should == "foo"
61
+ end
62
+
63
+ it 'should respond to "awesome_key" method by returning :class, :delimiter, :name' do
64
+ Foo.awesome_key.should == "foo:awesome"
65
+ end
66
+
67
+ it 'should respond to "awesome_key(number)" method by returning :class, :delimiter, :name, :delimiter, :arg' do
68
+ number = rand(100)
69
+ Foo.awesome_key(number).should == "foo:awesome:#{number}"
70
+ end
71
+
72
+
73
+
74
+ it 'should call method_missing on a non-existant method' do
75
+ lambda{ Foo.thismethoddoesnotexist }.should raise_error(NoMethodError)
76
+ end
77
+ end
78
+
79
+
80
+ describe 'instance methods' do
81
+ before(:each) do
82
+ @foo = Foo.new
83
+ end
84
+
85
+ it 'should respond to "key" method by returning pluralized downcase of class name' do
86
+ @foo.key.should == "foos"
87
+ end
29
88
 
89
+ it 'should respond to "awesome_key" method by returning :class, :delimiter, :name' do
90
+ @foo.awesome_key.should == "foos:awesome"
91
+ end
92
+
93
+ it 'should respond to "awesome_key(number)" method by returning :class, :delimiter, :name, :delimiter, :arg' do
94
+ number = rand(100)
95
+ @foo.awesome_key(number).should == "foos:awesome:#{number}"
96
+ end
97
+
98
+ it 'should call method_missing on a non-existant method' do
99
+ lambda{ @foo.thismethoddoesnotexist }.should raise_error(NoMethodError)
100
+ end
101
+ end
102
+
103
+ # test last
104
+ describe 'class configurations' do
105
+ after(:each) do
106
+ # todo find a better way of resetting all these values
107
+ Foo.key_delimiter KeyBuilder::DEFAULTS[:key_delimiter]
108
+ Foo.key_order KeyBuilder::DEFAULTS[:key_order]
109
+ Foo.key_prefix KeyBuilder::DEFAULTS[:key_prefix]
110
+ Foo.key_suffix KeyBuilder::DEFAULTS[:key_suffix]
111
+ Foo.key_pluralize_instances KeyBuilder::DEFAULTS[:key_pluralize_instances]
112
+ Foo.key_case KeyBuilder::DEFAULTS[:key_case]
113
+ Foo.key_plural KeyBuilder::DEFAULTS[:key_plural]
114
+ Foo.key_unique KeyBuilder::DEFAULTS[:key_unique]
115
+ end
116
+
117
+ it 'should change key_delimiter' do
118
+ key_delimiter = "|"
119
+ Foo.key_delimiter key_delimiter
120
+ Foo.key_delimiter.should == key_delimiter
121
+ Foo.awesome_key.should == "foo#{key_delimiter}awesome"
122
+ end
123
+
124
+
125
+ it 'should change key_order' do
126
+ order_array = [:prefix, :name, :unique, :base, :args, :suffix]
127
+ Foo.key_order order_array
128
+ Foo.key_order.should == order_array
129
+ Foo.awesome_key.should == "awesome:foo"
130
+ end
131
+
132
+ it 'should change key_prefix' do
133
+ key_prefix = "memcache"
134
+ Foo.key_prefix key_prefix
135
+ Foo.key_prefix.should == key_prefix
136
+ Foo.awesome_key.should == "#{key_prefix}:foo:awesome"
137
+ end
138
+
139
+ it 'should change key_suffix' do
140
+ key_suffix = "slave"
141
+ Foo.key_suffix key_suffix
142
+ Foo.key_suffix.should == key_suffix
143
+ Foo.awesome_key.should == "foo:awesome:#{key_suffix}"
144
+ end
145
+
146
+ it 'should change key_pluralize_instances' do
147
+ key_pluralize_instances = false
148
+ Foo.key_pluralize_instances key_pluralize_instances
149
+ Foo.key_pluralize_instances.should == key_pluralize_instances
150
+ foo = Foo.new
151
+ foo.awesome_key.should == "foo:awesome"
152
+ end
153
+
154
+ it 'should change key_case' do
155
+ key_case = :upcase
156
+ Foo.key_case key_case
157
+ Foo.key_case.should == key_case
158
+ Foo.awesome_key.should == "FOO:AWESOME"
159
+ end
160
+
161
+ it 'should change key_plural' do
162
+ key_plural = "fooz"
163
+ Foo.key_plural key_plural
164
+ Foo.key_plural.should == key_plural
165
+ foo = Foo.new
166
+ foo.awesome_key.should == "fooz:awesome"
167
+ end
168
+
169
+ it 'should change key_unique' do
170
+ Foo.class_eval { def timeish; (Time.now.to_i * 0.01).floor; end}
171
+ key_unique = :timeish
172
+ Foo.key_unique key_unique
173
+ Foo.key_unique.should == key_unique
174
+ foo = Foo.new
175
+ foo.awesome_key.should == "foos:awesome:#{foo.timeish}"
176
+ end
177
+
178
+ # todo move tests and assertsions to seperate describe and it blocks
179
+ it 'should allow all configurations to be set using a hash' do
180
+ # variables
181
+ key_delimiter = "/"
182
+ key_order = [:prefix, :base, :suffix]
183
+ key_prefix = "before"
184
+ key_suffix = "after"
185
+ key_pluralize_instances = false
186
+ key_case = :upcase
187
+ key_plural = "zoosk"
188
+ key_unique = "doesn-t_apply_to_instance_methods"
189
+ # config
190
+ Foo.keyfig :key_delimiter => key_delimiter,
191
+ :key_order => key_order,
192
+ :key_prefix => key_prefix,
193
+ :key_suffix => key_suffix,
194
+ :key_pluralize_instances => key_pluralize_instances,
195
+ :key_case => key_case,
196
+ :key_plural => key_plural,
197
+ :key_unique => key_unique
198
+ # assertions
199
+ Foo.key_delimiter.should == key_delimiter
200
+ Foo.key_order.should == key_order
201
+ Foo.key_prefix.should == key_prefix
202
+ Foo.key_suffix.should == key_suffix
203
+ Foo.key_pluralize_instances.should == key_pluralize_instances
204
+ Foo.key_case.should == key_case
205
+ Foo.key_plural.should == key_plural
206
+ Foo.key_unique.should == key_unique
207
+ end
208
+
209
+ end
210
+
211
+
212
+
213
+ describe 'requiring Keytar' do
30
214
  it 'should allow ActiveRecord based objects to use their unique identifiers' do
31
215
  name = "notblank"
32
216
  b = Bar.create(:name => name)
@@ -36,10 +220,6 @@ describe Keytar do
36
220
  end
37
221
 
38
222
  describe 'requiring Keytar with ActiveRecord undefined' do
39
- before do
40
- begin; Object.send(:remove_const, "ActiveRecord"); rescue NameError; end
41
- end
42
-
43
223
  it 'does not automatically add KeyBuilder to the class' do
44
224
  describe BarNonActiveRecord.ancestors do
45
225
  it {should_not include( KeyBuilder)}
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'active_record'
2
3
 
3
4
 
4
5
  $LOAD_PATH.unshift(File.dirname(__FILE__))
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: 59
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
+ - 1
7
8
  - 0
8
- - 9
9
9
  - 0
10
- version: 0.9.0
10
+ version: 1.0.0
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-05-08 00:00:00 -05:00
18
+ date: 2011-05-16 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -105,40 +105,19 @@ extensions: []
105
105
  extra_rdoc_files:
106
106
  - README.md
107
107
  files:
108
- - .DS_Store
109
108
  - .rvmrc
110
109
  - Gemfile
111
- - Gemfile.lock
112
110
  - README.md
113
111
  - Rakefile
114
112
  - VERSION
115
- - db/migrate/001_create_bars.rb
116
113
  - keytar.gemspec
117
114
  - lib/.DS_Store
118
115
  - lib/keytar.rb
119
116
  - lib/keytar/key_builder.rb
120
117
  - license.txt
121
- - pkg/keytar-0.1.0.gem
122
- - pkg/keytar-0.1.1.gem
123
118
  - spec/keytar/key_builder_spec.rb
124
119
  - spec/keytar/keytar_spec.rb
125
120
  - spec/keytar/spec_helper.rb
126
- - vendor/cache/activemodel-3.0.6.gem
127
- - vendor/cache/activerecord-3.0.6.gem
128
- - vendor/cache/activesupport-3.0.6.gem
129
- - vendor/cache/arel-2.0.9.gem
130
- - vendor/cache/builder-2.1.2.gem
131
- - vendor/cache/diff-lcs-1.1.2.gem
132
- - vendor/cache/git-1.2.5.gem
133
- - vendor/cache/i18n-0.5.0.gem
134
- - vendor/cache/jeweler-1.5.2.gem
135
- - vendor/cache/rake-0.8.7.gem
136
- - vendor/cache/rspec-2.5.0.gem
137
- - vendor/cache/rspec-core-2.5.1.gem
138
- - vendor/cache/rspec-expectations-2.5.0.gem
139
- - vendor/cache/rspec-mocks-2.5.0.gem
140
- - vendor/cache/sqlite3-1.3.3.gem
141
- - vendor/cache/tzinfo-0.3.26.gem
142
121
  has_rdoc: true
143
122
  homepage: http://github.com/Schnems/keytar
144
123
  licenses:
data/.DS_Store DELETED
Binary file
@@ -1,44 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- activemodel (3.0.6)
5
- activesupport (= 3.0.6)
6
- builder (~> 2.1.2)
7
- i18n (~> 0.5.0)
8
- activerecord (3.0.6)
9
- activemodel (= 3.0.6)
10
- activesupport (= 3.0.6)
11
- arel (~> 2.0.2)
12
- tzinfo (~> 0.3.23)
13
- activesupport (3.0.6)
14
- arel (2.0.9)
15
- builder (2.1.2)
16
- diff-lcs (1.1.2)
17
- git (1.2.5)
18
- i18n (0.5.0)
19
- jeweler (1.5.2)
20
- bundler (~> 1.0.0)
21
- git (>= 1.2.5)
22
- rake
23
- rake (0.8.7)
24
- rspec (2.5.0)
25
- rspec-core (~> 2.5.0)
26
- rspec-expectations (~> 2.5.0)
27
- rspec-mocks (~> 2.5.0)
28
- rspec-core (2.5.1)
29
- rspec-expectations (2.5.0)
30
- diff-lcs (~> 1.1.2)
31
- rspec-mocks (2.5.0)
32
- sqlite3 (1.3.3)
33
- tzinfo (0.3.26)
34
-
35
- PLATFORMS
36
- ruby
37
-
38
- DEPENDENCIES
39
- activerecord (~> 3.0.4)
40
- activesupport (~> 3.0.4)
41
- jeweler (~> 1.5.2)
42
- rake (~> 0.8.7)
43
- rspec (~> 2.5)
44
- sqlite3 (~> 1.3.3)
@@ -1,11 +0,0 @@
1
- class CreateBars < ActiveRecord::Migration
2
- def self.up
3
- create_table :bars do |t|
4
- t.column :name, :string, :null => false
5
- end
6
- end
7
-
8
- def self.down
9
- drop_table :bars
10
- end
11
- end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file