keytar 1.4.1 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile 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 KeyBuilder
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 is a Ruby on Rails wrapper for KeyBuilder.
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.4.1
1
+ 1.5.1
@@ -5,14 +5,13 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{keytar}
8
- s.version = "1.4.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-08}
12
+ s.date = %q{2011-08-12}
13
13
  s.description = %q{
14
- Keytar is a Ruby on Rails wrapper for KeyBuilder.
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/keytar/key_builder_spec.rb",
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/keytar/key_builder_spec.rb",
47
- "spec/keytar/keytar_spec.rb",
43
+ "spec/keytar_spec.rb",
48
44
  "spec/spec_helper.rb"
49
45
  ]
50
46
 
@@ -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
- included do
8
- include KeyBuilder
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
@@ -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: 5
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 4
8
+ - 5
9
9
  - 1
10
- version: 1.4.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-08 00:00:00 Z
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 Keytar is a Ruby on Rails wrapper for KeyBuilder.\n Use KeyBuilder to automatically generate keys based on class name instead of cluttering model\n definitions with tons of redundant key method declarations.\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/keytar/key_builder_spec.rb
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/keytar/key_builder_spec.rb
184
- - spec/keytar/keytar_spec.rb
181
+ - spec/keytar_spec.rb
185
182
  - spec/spec_helper.rb
@@ -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
@@ -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