url_keyed_object 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -19,3 +19,4 @@ rdoc
19
19
  pkg
20
20
 
21
21
  ## PROJECT::SPECIFIC
22
+ url_keyed_object.gemspec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -0,0 +1,44 @@
1
+ Feature: Using for things which are URL key-like
2
+ In order to generate and validate URL key-like data in a plain Ruby object
3
+ A Ruby developer
4
+ Wants to use UrlKeyedObject
5
+
6
+ # If you want to generate URL key values without validating them it's really easy
7
+ Scenario: Generating a URL key value
8
+ When I make a call to generate a URL key:
9
+ """
10
+ @value = UrlKeyedObject.generate_unchecked_url_key
11
+ """
12
+ Then @value should match /^[a-z0-9]{5}$/
13
+
14
+ Scenario: Generating and validating a URL key value
15
+ Given this class:
16
+ """
17
+ class HasOpaqueId
18
+ class << self
19
+ def instances
20
+ @instances ||= []
21
+ end
22
+ end
23
+
24
+ attr_reader :id
25
+
26
+ def initialize
27
+ @id = UrlKeyedObject.generate_checked_url_key do |id_value|
28
+ is_this_a_valid_id?(id_value)
29
+ end
30
+ self.class.instances << self
31
+ end
32
+
33
+ private
34
+
35
+ def is_this_a_valid_id?(id_value)
36
+ self.class.instances.select { |obj| obj.id == id_value }.empty?
37
+ end
38
+ end
39
+ """
40
+ When I make a new instance:
41
+ """
42
+ @object_with_id = HasOpaqueId.new
43
+ """
44
+ Then @object_with_id.id should match /^[a-z0-9]{5}$/
@@ -10,6 +10,10 @@ Then /^(@[a-zA-Z_0-9]+)\.([a-zA-Z_0-9?!]+) should match \/(.+)\/$/ do |ivar, met
10
10
  instance_variable_get(ivar).send(method).should match(regex)
11
11
  end
12
12
 
13
+ Then /^(@[a-zA-Z_0-9]+) should match \/(.+)\/$/ do |ivar, regex|
14
+ instance_variable_get(ivar).should match(regex)
15
+ end
16
+
13
17
  Then /^(@[a-zA-Z_0-9]+)\.([a-zA-Z_0-9?!]+) should be (.+)$/ do |ivar, method, value|
14
18
  instance_variable_get(ivar).send(method).should send("be_#{value}")
15
19
  end
@@ -1,4 +1,4 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
- require 'url_keyed_object'
2
+ require 'url_keyed_object/active_record'
3
3
 
4
4
  require 'spec/expectations'
@@ -37,7 +37,7 @@ Feature: Using with ActiveRecord
37
37
  @instance = Thing.new
38
38
  @instance.save!
39
39
  """
40
- Then @instance.url_key should match /[a-z0-9]{5}/
40
+ Then @instance.url_key should match /^[a-z0-9]{5}$/
41
41
 
42
42
  Scenario: Attempting to mass-assign url_key ought to fail
43
43
  When I make an instance using mass-assignment:
@@ -1,3 +1,5 @@
1
+ require 'url_keyed_object'
2
+
1
3
  module UrlKeyedObject
2
4
  module ActiveRecord
3
5
  # --
@@ -27,10 +29,7 @@ module UrlKeyedObject
27
29
  protected
28
30
 
29
31
  def generate_valid_url_key
30
- new_url_key = UrlKeyedObject.generate_unchecked_url_key
31
- while !self.valid_url_key?(new_url_key) do
32
- new_url_key = UrlKeyedObject.generate_unchecked_url_key
33
- end
32
+ new_url_key = UrlKeyedObject.generate_checked_url_key { |value| self.valid_url_key?(value) }
34
33
  write_attribute(:url_key, new_url_key)
35
34
  end
36
35
 
@@ -6,9 +6,10 @@ module UrlKeyedObject
6
6
  # holds an array so a base-31 column (units / tens / hundreds) equiv can be
7
7
  # encoded as an ASCII character
8
8
  def key_encoding
9
- @key_encoding ||= ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
10
- "a", "b", "c", "d", "e", "f", "g", "h", "j", "k", "m",
11
- "n", "p", "q", "r", "s", "v", "w", "x", "y", "z"]
9
+ @key_encoding ||= ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
10
+ "a", "b", "c", "d", "e", "f", "g", "h", "j", "k",
11
+ "m", "n", "p", "q", "r", "s", "v", "w", "x", "y",
12
+ "z"]
12
13
  end
13
14
 
14
15
  # generates a url key from a random 5-digit base 31 number, without checking its uniqueness
@@ -18,6 +19,15 @@ module UrlKeyedObject
18
19
  end.join('')
19
20
  end
20
21
 
22
+ # Keeps generating new URL keys until the passed-in block returns true
23
+ def generate_checked_url_key
24
+ key = generate_unchecked_url_key
25
+ while !yield(key)
26
+ key = generate_unchecked_url_key
27
+ end
28
+ key
29
+ end
30
+
21
31
  # Validate the well-formedness of a URL key
22
32
  def well_formed_url_key?(url_key)
23
33
  !url_key.match(/^[0-9abcdefghjkmnpqrsvwxyz]{5}$/).nil?
@@ -29,5 +39,3 @@ module UrlKeyedObject
29
39
  end
30
40
  end
31
41
  end
32
-
33
- require 'url_keyed_object/active_record'
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  $:.unshift(File.dirname(__FILE__))
2
2
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'url_keyed_object'
4
+ require 'url_keyed_object/active_record'
4
5
  require 'spec'
5
6
  require 'spec/autorun'
6
7
  require 'rubygems'
@@ -83,12 +83,9 @@ describe UrlKeyedObject::ActiveRecord do
83
83
 
84
84
  it "should be able to keep attempting to create a URL key until one is valid" do
85
85
  url_keyed_object = @url_keyed_class.new
86
- valid_url_sequence = sequence('valid url sequence')
87
86
 
88
- UrlKeyedObject.expects(:generate_unchecked_url_key).in_sequence(valid_url_sequence).returns('a1url')
89
- url_keyed_object.expects(:valid_url_key?).in_sequence(valid_url_sequence).returns(false)
90
- UrlKeyedObject.expects(:generate_unchecked_url_key).in_sequence(valid_url_sequence).returns('a2url')
91
- url_keyed_object.expects(:valid_url_key?).in_sequence(valid_url_sequence).returns(true)
87
+ UrlKeyedObject.expects(:generate_checked_url_key).yields('a2url').returns('a2url')
88
+ url_keyed_object.expects(:valid_url_key?).with('a2url').returns(true)
92
89
 
93
90
  @url_keyed_class.publicize_methods do
94
91
  url_keyed_object.generate_valid_url_key
@@ -38,4 +38,16 @@ describe UrlKeyedObject do
38
38
  end
39
39
  end
40
40
  end
41
+
42
+ describe "validity of URL keys" do
43
+ it "should be able to evaluate a block to check key validity, repeating until it generates one" do
44
+ valid_key_sequence = sequence('valid key sequence')
45
+ UrlKeyedObject.expects(:generate_unchecked_url_key).in_sequence(valid_key_sequence).returns('a1url')
46
+ UrlKeyedObject.expects(:generate_unchecked_url_key).in_sequence(valid_key_sequence).returns('a2url')
47
+
48
+ key = UrlKeyedObject.generate_checked_url_key { |value| value != 'a1url' }
49
+
50
+ key.should == 'a2url'
51
+ end
52
+ end
41
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: url_keyed_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Patterson
@@ -60,6 +60,7 @@ files:
60
60
  - VERSION
61
61
  - cucumber.yml
62
62
  - features/fixtures/.gitignore
63
+ - features/for_url_key-like_uses.feature
63
64
  - features/step_definitions/database_steps.rb
64
65
  - features/step_definitions/eval_steps.rb
65
66
  - features/step_definitions/feedback_steps.rb