keytar 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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