url_keyed_object 0.1.0 → 0.1.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/.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