url_keyed_object 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,59 +1 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- require 'spec/rake/spectask'
5
- Spec::Rake::SpecTask.new(:spec) do |spec|
6
- spec.libs << 'lib' << 'spec'
7
- spec.spec_files = FileList['spec/**/*_spec.rb']
8
- end
9
-
10
- Spec::Rake::SpecTask.new(:rcov) do |spec|
11
- spec.libs << 'lib' << 'spec'
12
- spec.pattern = 'spec/**/*_spec.rb'
13
- spec.rcov = true
14
- end
15
-
16
- task :spec => :check_dependencies
17
-
18
- begin
19
- require 'cucumber/rake/task'
20
- namespace :cucumber do
21
- Cucumber::Rake::Task.new(:ok, 'Run features that should pass') do |t|
22
- t.fork = true # You may get faster startup if you set this to false
23
- t.profile = 'default'
24
- end
25
-
26
- Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
27
- t.fork = true # You may get faster startup if you set this to false
28
- t.profile = 'wip'
29
- end
30
-
31
- desc 'Run all features'
32
- task :all => [:ok, :wip]
33
- end
34
- desc 'Alias for cucumber:ok'
35
- task :cucumber => 'cucumber:ok'
36
-
37
- task :default => :cucumber
38
-
39
- task :features => :cucumber do
40
- STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
41
- end
42
- rescue LoadError
43
- desc 'cucumber rake task not available (cucumber not installed)'
44
- task :cucumber do
45
- abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
46
- end
47
- end
48
-
49
- task :default => :spec
50
-
51
- require 'rake/rdoctask'
52
- Rake::RDocTask.new do |rdoc|
53
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
54
-
55
- rdoc.rdoc_dir = 'rdoc'
56
- rdoc.title = "url_keyed_object #{version}"
57
- rdoc.rdoc_files.include('README*')
58
- rdoc.rdoc_files.include('lib/**/*.rb')
59
- end
1
+ require 'bundler/gem_tasks'
@@ -1,4 +1,5 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
2
  require 'url_keyed_object/active_record'
3
+ require 'active_record'
3
4
 
4
- require 'spec/expectations'
5
+ require 'rspec/expectations'
@@ -1,15 +1,19 @@
1
1
  require 'fileutils'
2
2
 
3
3
  Before("@db") do |scenario|
4
- require 'activerecord'
4
+ require 'active_record'
5
+ require 'url_keyed_object/active_record'
6
+
5
7
  @db_dir = ::Dir.mktmpdir
6
8
  begin
7
- # Create the SQLite database
9
+ # Create the SQLite database, pretend the Railtie has run...
10
+ @recording_logger = RecordingLogger.new($stderr)
11
+
12
+ ActiveRecord::Base.extend UrlKeyedObject::ActiveRecord
8
13
  ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3',
9
14
  'database' => "#{@db_dir}/feature.sqlite3", 'pool' => 5, 'timeout' => 5000
10
15
  })
11
16
  ActiveRecord::Base.connection
12
- @recording_logger = RecordingLogger.new($stderr)
13
17
  ActiveRecord::Base.logger = @recording_logger
14
18
  rescue
15
19
  $stderr.puts $!, *($!.backtrace)
@@ -21,4 +25,4 @@ After("@db") do |scenario|
21
25
  ActiveRecord::Base.connection.disconnect!
22
26
  FileUtils.remove_entry_secure @db_dir
23
27
  @recording_logger.reset_recorder!
24
- end
28
+ end
@@ -4,25 +4,25 @@ class RecordingLogger < Logger
4
4
  def recorded_messages
5
5
  @recorded_messages ||= {}
6
6
  end
7
-
7
+
8
8
  alias_method :add_original, :add
9
9
  def add(severity, message = nil, progname = nil, &block)
10
10
  record_it(severity, message)
11
11
  super
12
12
  end
13
-
14
-
13
+
14
+
15
15
  def reset_recorder!
16
16
  @recorded_messages = {}
17
17
  end
18
-
18
+
19
19
  def has_message_for_severity?(severity)
20
20
  (!recorded_messages[severity].nil? && !recorded_messages[severity].empty?)
21
21
  end
22
-
22
+
23
23
  private
24
-
24
+
25
25
  def record_it(severity, message)
26
26
  (recorded_messages[severity] ||= []) << message
27
27
  end
28
- end
28
+ end
@@ -1,36 +1,36 @@
1
1
  @db
2
2
  Feature: Using with ActiveRecord
3
- In order to generate and validate URL keys in an ActiveRecord::Base object
3
+ In order to generate and validate URL keys in an ActiveRecord::Base model in a Rails project
4
4
  A Rails developer
5
5
  Wants to include and use UrlKeyedObject
6
-
6
+
7
7
  # The most basic use case is for a 5-character ID, stored in the url_key column.
8
- #
9
- # Simply including the UrlKeyedObject::ActiveRecord module is enough.
8
+ #
9
+ # Simply extended the UrlKeyedObject::ActiveRecord module and calling has_url_key is enough.
10
10
  # This makes the url_key attribute protected from mass assignment and read-only.
11
11
  Background:
12
12
  Given a database, with this table defined:
13
13
  """
14
14
  create_table :things do |t|
15
15
  t.string :url_key, :null => false
16
-
16
+
17
17
  t.timestamps
18
18
  end
19
19
  """
20
20
  And this class:
21
21
  """
22
22
  class Thing < ActiveRecord::Base
23
- acts_as_url_keyed
23
+ has_url_key
24
24
  end
25
25
  """
26
-
26
+
27
27
  Scenario: An unsaved model object with UrlKeyedObject included
28
28
  When I make a bare instance:
29
29
  """
30
30
  @instance = Thing.new
31
31
  """
32
32
  Then @instance.url_key should be nil
33
-
33
+
34
34
  Scenario: A saved model object with UrlKeyedObject included
35
35
  When I make and save an instance:
36
36
  """
@@ -38,15 +38,14 @@ Feature: Using with ActiveRecord
38
38
  @instance.save!
39
39
  """
40
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:
44
44
  """
45
45
  @instance = Thing.new(:url_key => 'abcde')
46
46
  """
47
47
  Then @instance.url_key should be nil
48
- And a warning should have been logged
49
-
48
+
50
49
  Scenario: Attempting to set url_key ought to fail
51
50
  When I make an instance and set the value of url_key manually:
52
51
  """
@@ -1,36 +1,36 @@
1
1
  @db
2
2
  Feature: More advanced usage with ActiveRecord
3
- In order to generate and validate non-standard URL keys in an ActiveRecord::Base object
3
+ In order to generate and validate non-standard URL keys in an ActiveRecord::Base model in a Rails project
4
4
  A Rails developer
5
5
  Wants to include and use UrlKeyedObject
6
-
6
+
7
7
  # The default case is for a 5-character ID, stored in the url_key column.
8
8
  # Here we have an existing column we want to re-use, and we want a longer URL key
9
- #
9
+ #
10
10
  # calling acts_as_url_keyed and setting a couple of options is all that's needed.
11
11
  Background:
12
12
  Given a database, with this table defined:
13
13
  """
14
14
  create_table :advanced_things do |t|
15
15
  t.string :opaque_id, :null => false
16
-
16
+
17
17
  t.timestamps
18
18
  end
19
19
  """
20
20
  And this class:
21
21
  """
22
22
  class AdvancedThing < ActiveRecord::Base
23
- acts_as_url_keyed :url_key_column => :opaque_id, :url_key_length => 8
23
+ has_url_key :column => :opaque_id, :length => 8
24
24
  end
25
25
  """
26
-
26
+
27
27
  Scenario: An unsaved model object with UrlKeyedObject included
28
28
  When I make a bare instance:
29
29
  """
30
30
  @instance = AdvancedThing.new
31
31
  """
32
32
  Then @instance.opaque_id should be nil
33
-
33
+
34
34
  Scenario: A saved model object with an 8-character URL key on #opaque_id
35
35
  When I make and save an instance:
36
36
  """
@@ -38,15 +38,14 @@ Feature: More advanced usage with ActiveRecord
38
38
  @instance.save!
39
39
  """
40
40
  Then @instance.opaque_id should match /^[a-z0-9]{8}$/
41
-
41
+
42
42
  Scenario: Attempting to mass-assign opaque_id ought to fail
43
43
  When I make an instance using mass-assignment:
44
44
  """
45
45
  @instance = AdvancedThing.new(:opaque_id => 'abcde')
46
46
  """
47
47
  Then @instance.opaque_id should be nil
48
- And a warning should have been logged
49
-
48
+
50
49
  Scenario: Attempting to set opaque_id ought to fail
51
50
  When I make an instance and set the value of opaque_id manually:
52
51
  """
@@ -1,63 +1,58 @@
1
1
  require 'url_keyed_object'
2
- require 'active_record'
2
+ require 'active_support/concern'
3
3
 
4
4
  module UrlKeyedObject
5
- module ActiveRecordHook
6
- def acts_as_url_keyed(opts = {})
7
- attr_writer :url_key_length
8
-
9
- @url_key_column = opts[:url_key_column] if opts.has_key?(:url_key_column)
10
- @url_key_length = opts[:url_key_length] if opts.has_key?(:url_key_length)
11
-
12
- send :include, UrlKeyedObject::ActiveRecord
13
-
5
+ module ActiveRecord
6
+ def has_url_key(opts = {})
7
+ url_key_column = opts.has_key?(:column) ? opts[:column] : :url_key
8
+ url_key_length = opts.has_key?(:length) ? opts[:length] : 5
9
+
10
+ include UrlKeyedObject::ActiveRecord::Extensions
11
+
12
+ attr_protected url_key_column
14
13
  before_create :generate_valid_url_key
15
-
16
- define_method("#{url_key_column}=") { |value| logger.warn("Attempt to set ##{url_key_column}!"); nil }
14
+
15
+ @url_key_helper = UrlKeyedObject::ActiveRecord::Helper.new(self, url_key_column, url_key_length)
16
+
17
+ define_method("#{url_key_column}=") { |value| logger.warn("Attempt to set ##{url_key_column}!") if self.respond_to?(:logger); nil }
17
18
  end
18
- end
19
-
20
- module ActiveRecord
21
- # def url_key=(value)
22
- # logger.warn('Attempt to set #url_key!')
23
- # nil
24
- # end
25
-
26
- module ClassMethods
27
- def url_key_column
28
- @url_key_column ||= :url_key
19
+
20
+ class Helper
21
+ attr_reader :klass, :column, :length
22
+
23
+ def initialize(klass, column, length)
24
+ @klass = klass
25
+ @column = column
26
+ @length = length
29
27
  end
30
-
31
- def url_key_length
32
- @url_key_length ||= 5
28
+
29
+ def generate_valid_url_key(instance)
30
+ new_url_key = UrlKeyedObject.generate_checked_url_key(length) { |value| valid_url_key?(value) }
31
+ instance.send(:write_attribute, column, new_url_key)
32
+ end
33
+
34
+ def valid_url_key?(url_key)
35
+ klass.send("find_by_#{column}", url_key).nil?
33
36
  end
34
37
  end
35
-
36
- def self.included(model_class)
37
- model_class.extend ClassMethods
38
- end
39
-
40
- def to_param
41
- send url_key_column
42
- end
43
-
38
+
39
+ module Extensions
40
+ extend ActiveSupport::Concern
41
+
42
+ def to_param
43
+ send self.class.url_key_helper.column
44
+ end
45
+
46
+ module ClassMethods
47
+ def url_key_helper
48
+ @url_key_helper
49
+ end
50
+ end
51
+
44
52
  protected
45
-
46
- def generate_valid_url_key
47
- new_url_key = UrlKeyedObject.generate_checked_url_key(url_key_length) { |value| self.valid_url_key?(value) }
48
- write_attribute(url_key_column, new_url_key)
49
- end
50
-
51
- def valid_url_key?(url_key)
52
- self.class.send("find_by_#{url_key_column}", url_key).nil?
53
- end
54
-
55
- def url_key_column
56
- self.class.url_key_column
57
- end
58
-
59
- def url_key_length
60
- self.class.url_key_length
53
+ def generate_valid_url_key
54
+ self.class.url_key_helper.generate_valid_url_key(self)
55
+ end
61
56
  end
62
57
  end
63
- end
58
+ end
@@ -4,7 +4,7 @@ require 'url_keyed_object/active_record'
4
4
  module UrlKeyedObject
5
5
  class Railtie < Rails::Railtie
6
6
  initializer 'url_keyed_object.active_record_hook', :after => :preload_frameworks do
7
- ::ActiveRecord::Base.extend UrlKeyedObject::ActiveRecordHook
7
+ ::ActiveRecord::Base.extend UrlKeyedObject::ActiveRecord
8
8
  end
9
9
  end
10
- end
10
+ end
@@ -11,14 +11,14 @@ module UrlKeyedObject
11
11
  "m", "n", "p", "q", "r", "s", "v", "w", "x", "y",
12
12
  "z"]
13
13
  end
14
-
14
+
15
15
  # generates a url key from a random 5-digit base 31 number, without checking its uniqueness
16
16
  def generate_unchecked_url_key(length = 5)
17
17
  (1..length).collect do
18
18
  key_encoding[rand(31)]
19
19
  end.join('')
20
20
  end
21
-
21
+
22
22
  # Keeps generating new URL keys until the passed-in block returns true
23
23
  def generate_checked_url_key(length = 5)
24
24
  key = generate_unchecked_url_key(length)
@@ -27,16 +27,22 @@ module UrlKeyedObject
27
27
  end
28
28
  key
29
29
  end
30
-
30
+
31
31
  # Validate the well-formedness of a URL key
32
32
  def well_formed_url_key?(url_key, length = 5)
33
33
  !url_key.match(Regexp.new("^[0-9abcdefghjkmnpqrsvwxyz]{#{length.to_i}}$")).nil?
34
34
  end
35
-
35
+
36
36
  # decode a moderately dirty URL key
37
37
  def decode_url_key(url_key)
38
38
  url_key.downcase.tr('o', '0').tr('il', '1')
39
39
  end
40
+
41
+ # decode and validate a key, returning the decoded key only if it's well-formed
42
+ def decode_well_formed_url_key(url_key, length = 5)
43
+ decoded_url_key = decode_url_key(url_key)
44
+ well_formed_url_key?(decoded_url_key, length) ? decoded_url_key : nil
45
+ end
40
46
  end
41
47
  end
42
48
 
data/spec/spec_helper.rb CHANGED
@@ -1,17 +1,13 @@
1
- $:.unshift(File.dirname(__FILE__))
2
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
- require 'rubygems'
4
- gem 'activerecord'
1
+ lib_path = File.expand_path('../../lib', __FILE__)
2
+ $:.unshift(lib_path) unless $:.include?(lib_path)
3
+
5
4
  require 'url_keyed_object'
6
- require 'url_keyed_object/active_record'
7
- require 'spec'
8
- require 'spec/autorun'
9
5
 
10
- Spec::Runner.configure do |config|
6
+ RSpec.configure do |config|
11
7
  config.mock_with :mocha
12
8
  end
13
9
 
14
- Spec::Matchers.define :use_method do |method|
10
+ RSpec::Matchers.define :use_method do |method|
15
11
  chain :for_callback do |callback|
16
12
  @callback = callback
17
13
  end
@@ -29,9 +25,9 @@ class Class
29
25
  public *saved_private_instance_methods
30
26
  public *saved_protected_instance_methods
31
27
  end
32
-
28
+
33
29
  yield
34
-
30
+
35
31
  self.class_eval do
36
32
  private *saved_private_instance_methods
37
33
  protected *saved_protected_instance_methods
@@ -1,101 +1,94 @@
1
1
  require 'spec_helper'
2
- require 'active_record'
3
- require 'tmpdir'
4
- require 'fileutils'
5
- require 'logger'
6
-
7
- class SpecMigration < ActiveRecord::Migration
8
- def self.up
9
- create_table :things do |t|
10
- t.string :url_key, :null => false
11
-
12
- t.timestamps
2
+ require 'active_model/callbacks'
3
+ require 'active_model/mass_assignment_security'
4
+
5
+ require 'url_keyed_object/active_record'
6
+
7
+
8
+ class UrlKeyedModel
9
+ extend ActiveModel::Callbacks
10
+ include ActiveModel::MassAssignmentSecurity
11
+
12
+ define_model_callbacks :create
13
+
14
+ def initialize(attrs = {})
15
+ @attributes = sanitize_for_mass_assignment(attrs)
16
+ end
17
+
18
+ def url_key
19
+ @attributes[:url_key]
20
+ end
21
+
22
+ def read_attribute(key)
23
+ @attributes[key]
24
+ end
25
+
26
+ def write_attribute(key, value)
27
+ @attributes[key] = value
28
+ end
29
+
30
+ extend UrlKeyedObject::ActiveRecord
31
+
32
+ has_url_key
33
+
34
+ def save
35
+ run_callbacks :create do
36
+ #logic
13
37
  end
14
38
  end
15
39
  end
16
40
 
17
41
  describe UrlKeyedObject::ActiveRecord do
18
- before(:all) do
19
- @db_dir = ::Dir.mktmpdir
20
- begin
21
- # Create the SQLite database
22
- ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3',
23
- 'database' => "#{@db_dir}/spec.sqlite3", 'pool' => 5, 'timeout' => 5000
24
- })
25
- ActiveRecord::Base.connection
26
- rescue
27
- $stderr.puts $!, *($!.backtrace)
28
- $stderr.puts "Couldn't create database for #{"#{@db_dir}/feature.sqlite3".inspect}"
29
- end
30
-
31
- SpecMigration.migrate(:up)
32
-
33
- @url_keyed_class = Class.new(ActiveRecord::Base)
34
- @url_keyed_class.class_eval do
35
- set_table_name 'things'
36
- def self.name
37
- 'UrlKeyedObjectMock'
38
- end
39
-
40
- acts_as_url_keyed
41
- end
42
-
43
- ActiveRecord::Base.logger = Logger.new(STDERR)
44
- end
45
-
46
- after(:all) do
47
- ActiveRecord::Base.connection.disconnect!
48
- FileUtils.remove_entry_secure @db_dir
49
- end
50
-
51
- it "should protect URL keys from mass-assignment" do
52
- url_keyed_object = @url_keyed_class.new(:url_key => 'woo')
53
-
42
+ let(:url_keyed_object) { UrlKeyedModel.new }
43
+
44
+ it "protects URL keys from mass-assignment" do
45
+ url_keyed_object = UrlKeyedModel.new(:url_key => 'woo')
46
+
54
47
  url_keyed_object.url_key.should be_nil
55
48
  end
56
-
57
- it "should not allow URL keys to be set" do
58
- url_keyed_object = @url_keyed_class.new
59
-
49
+
50
+ it "does not allow URL keys to be set" do
60
51
  url_keyed_object.url_key = 'dfghj'
61
-
52
+
62
53
  url_keyed_object.url_key.should be_nil
63
54
  end
64
-
65
- describe "ensuring unique URL keys get created " do
66
- it "should be able to verify that a URL key is valid" do
67
- @url_keyed_class.expects(:find_by_url_key).with('a_url').returns(nil)
68
- url_keyed_object = @url_keyed_class.new
69
-
70
- @url_keyed_class.publicize_methods do
71
- url_keyed_object.valid_url_key?('a_url').should be_true
72
- end
55
+
56
+ it "returns the contents of the url_key column for to_param" do
57
+ url_keyed_object.stubs(:url_key).returns('hello')
58
+
59
+ url_keyed_object.to_param.should == 'hello'
60
+ end
61
+
62
+ describe "ensuring unique URL keys get created" do
63
+ let(:ar_helper) { UrlKeyedObject::ActiveRecord::Helper.new(UrlKeyedModel, :url_key, 5) }
64
+
65
+ it "can verify that a URL key is valid" do
66
+ UrlKeyedModel.expects(:find_by_url_key).with('a_url').returns(nil)
67
+
68
+ ar_helper.valid_url_key?('a_url').should be_true
73
69
  end
74
-
75
- it "should be able to verify that a URL key is not valid" do
76
- @url_keyed_class.expects(:find_by_url_key).with('a_url').returns(@url_keyed_class.new)
77
- url_keyed_object = @url_keyed_class.new
78
-
79
- @url_keyed_class.publicize_methods do
80
- url_keyed_object.valid_url_key?('a_url').should be_false
81
- end
70
+
71
+ it "can verify that a URL key is not valid" do
72
+ UrlKeyedModel.expects(:find_by_url_key).with('a_url').returns(UrlKeyedModel.new)
73
+
74
+ ar_helper.valid_url_key?('a_url').should be_false
82
75
  end
83
-
84
- it "should be able to keep attempting to create a URL key until one is valid" do
85
- url_keyed_object = @url_keyed_class.new
86
-
76
+
77
+ it "keeps attempting to create a URL key until one is valid" do
78
+ url_keyed_object = UrlKeyedModel.new
79
+
87
80
  UrlKeyedObject.expects(:generate_checked_url_key).yields('a2url').returns('a2url')
88
- url_keyed_object.expects(:valid_url_key?).with('a2url').returns(true)
89
-
90
- @url_keyed_class.publicize_methods do
91
- url_keyed_object.generate_valid_url_key
92
-
93
- url_keyed_object.url_key.should == 'a2url'
94
- end
81
+ ar_helper.expects(:valid_url_key?).with('a2url').returns(true)
82
+
83
+ ar_helper.generate_valid_url_key(url_keyed_object)
84
+
85
+ url_keyed_object.url_key.should == 'a2url'
95
86
  end
96
-
97
- it "should use a before_create callback to ensure that a URL key is created" do
98
- @url_keyed_class.should use_method(:generate_valid_url_key).for_callback(:before_create)
87
+
88
+ it "uses a before_create callback to ensure that a URL key is created" do
89
+ UrlKeyedModel.url_key_helper.expects(:generate_valid_url_key).with(url_keyed_object)
90
+
91
+ url_keyed_object.save
99
92
  end
100
93
  end
101
- end
94
+ end
@@ -4,30 +4,30 @@ describe UrlKeyedObject do
4
4
  it "should be able to generate a 5-character URL key" do
5
5
  UrlKeyedObject.generate_unchecked_url_key.should match(/[0-9abcdefghjkmnpqrsvwxyz]{5}/)
6
6
  end
7
-
7
+
8
8
  it "should be able to generate an arbitrary-length URL key" do
9
9
  UrlKeyedObject.generate_unchecked_url_key(7).should match(/[0-9abcdefghjkmnpqrsvwxyz]{7}/)
10
10
  end
11
-
11
+
12
12
  describe "decoding a moderately dirty URL key (case insensitivity, ambiguous character replacement)" do
13
13
  it "should be able to cope with O o 0 ambiguity" do
14
14
  UrlKeyedObject.decode_url_key('Oo0ab').should == '000ab'
15
15
  end
16
-
16
+
17
17
  it "should be able to cope with 1 I i L l ambiguity" do
18
18
  UrlKeyedObject.decode_url_key('1IiLl').should == '11111'
19
19
  end
20
-
20
+
21
21
  it "should be able to cope with uppercase" do
22
22
  UrlKeyedObject.decode_url_key('ABCDE').should == 'abcde'
23
23
  end
24
24
  end
25
-
25
+
26
26
  describe "well-formedness of URL keys" do
27
27
  it "should be able to confirm that a URL key is well-formed" do
28
28
  UrlKeyedObject.well_formed_url_key?('0ab9d').should be_true
29
29
  end
30
-
30
+
31
31
  it "should report that malformed URL keys are NOT well-formed" do
32
32
  ['DfZZZ', # upper case
33
33
  'abcdef', # too long
@@ -41,12 +41,12 @@ describe UrlKeyedObject do
41
41
  UrlKeyedObject.well_formed_url_key?(malformed_url_key).should be_false
42
42
  end
43
43
  end
44
-
44
+
45
45
  it "should be able to cope with a different specified length" do
46
46
  UrlKeyedObject.well_formed_url_key?('abcdef', 6).should be_true
47
47
  end
48
48
  end
49
-
49
+
50
50
  describe "validity of URL keys" do
51
51
  it "should be able to evaluate a block to check key validity, repeating until it generates one" do
52
52
  valid_key_sequence = sequence('valid key sequence')
@@ -54,14 +54,17 @@ describe UrlKeyedObject do
54
54
  in_sequence(valid_key_sequence)
55
55
  UrlKeyedObject.expects(:generate_unchecked_url_key).with(5).returns('a2url').
56
56
  in_sequence(valid_key_sequence)
57
-
57
+
58
58
  key = UrlKeyedObject.generate_checked_url_key { |value| value != 'a1url' }
59
-
59
+
60
60
  key.should == 'a2url'
61
61
  end
62
-
63
- it "should description" do
64
-
65
- end
66
62
  end
67
- end
63
+
64
+ it "can return a decoded key that has been checked for well-formedness" do
65
+ UrlKeyedObject.expects(:decode_url_key).with('ABCDE').returns('abcde')
66
+ UrlKeyedObject.expects(:well_formed_url_key?).with('abcde', 5).returns('abcde')
67
+
68
+ UrlKeyedObject.decode_well_formed_url_key('ABCDE').should == 'abcde'
69
+ end
70
+ end
metadata CHANGED
@@ -1,73 +1,80 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: url_keyed_object
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 3
8
- - 0
9
- version: 0.3.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Matt Patterson
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2010-06-11 00:00:00 +01:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2010-06-11 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rspec
16
+ requirement: &2164422500 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '2.8'
22
+ type: :development
22
23
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 1
29
- - 2
30
- - 9
31
- version: 1.2.9
24
+ version_requirements: *2164422500
25
+ - !ruby/object:Gem::Dependency
26
+ name: mocha
27
+ requirement: &2164422000 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
32
33
  type: :development
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: cucumber
36
34
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- - 5
44
- version: "0.5"
35
+ version_requirements: *2164422000
36
+ - !ruby/object:Gem::Dependency
37
+ name: cucumber
38
+ requirement: &2164421340 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0.5'
45
44
  type: :development
46
- version_requirements: *id002
47
- - !ruby/object:Gem::Dependency
45
+ prerelease: false
46
+ version_requirements: *2164421340
47
+ - !ruby/object:Gem::Dependency
48
48
  name: activerecord
49
+ requirement: &2164420800 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '3.2'
55
+ type: :development
49
56
  prerelease: false
50
- requirement: &id003 !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- segments:
55
- - 2
56
- - 3
57
- version: "2.3"
57
+ version_requirements: *2164420800
58
+ - !ruby/object:Gem::Dependency
59
+ name: sqlite3
60
+ requirement: &2164420300 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
58
66
  type: :development
59
- version_requirements: *id003
60
- description: Making it easy to work with Rails objects which use a URL key in their URL instead of their database ID.
67
+ prerelease: false
68
+ version_requirements: *2164420300
69
+ description: Making it easy to work with Rails objects which use a URL key in their
70
+ URL instead of their database ID.
61
71
  email: matt@reprocessed.org
62
72
  executables: []
63
-
64
73
  extensions: []
65
-
66
- extra_rdoc_files:
74
+ extra_rdoc_files:
67
75
  - LICENSE
68
76
  - README.rdoc
69
- files:
70
- - VERSION
77
+ files:
71
78
  - README.rdoc
72
79
  - LICENSE
73
80
  - Rakefile
@@ -76,38 +83,44 @@ files:
76
83
  - lib/url_keyed_object/railtie.rb
77
84
  - lib/url_keyed_object.rb
78
85
  - rails/init.rb
79
- has_rdoc: true
86
+ - spec/spec_helper.rb
87
+ - spec/url_keyed_object/active_record_spec.rb
88
+ - spec/url_keyed_object_spec.rb
89
+ - features/step_definitions/database_steps.rb
90
+ - features/step_definitions/eval_steps.rb
91
+ - features/step_definitions/feedback_steps.rb
92
+ - features/support/env.rb
93
+ - features/support/hooks.rb
94
+ - features/support/recording_logger.rb
95
+ - features/for_url_key-like_uses.feature
96
+ - features/with_active_record-basic.feature
97
+ - features/with_active_record-more-advanced.feature
80
98
  homepage: http://github.com/fidothe/url_keyed_object
81
99
  licenses: []
82
-
83
100
  post_install_message:
84
- rdoc_options:
101
+ rdoc_options:
85
102
  - --charset=UTF-8
86
- require_paths:
103
+ require_paths:
87
104
  - lib
88
- required_ruby_version: !ruby/object:Gem::Requirement
89
- requirements:
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- segments:
93
- - 0
94
- version: "0"
95
- required_rubygems_version: !ruby/object:Gem::Requirement
96
- requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- segments:
100
- - 0
101
- version: "0"
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
102
117
  requirements: []
103
-
104
118
  rubyforge_project:
105
- rubygems_version: 1.3.6
119
+ rubygems_version: 1.8.10
106
120
  signing_key:
107
121
  specification_version: 3
108
122
  summary: Making it easy to work with objects with URL keys
109
- test_files:
110
- - spec/spec.opts
123
+ test_files:
111
124
  - spec/spec_helper.rb
112
125
  - spec/url_keyed_object/active_record_spec.rb
113
126
  - spec/url_keyed_object_spec.rb
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.3.0
data/spec/spec.opts DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --format=specdoc