encoder 0.0.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 +10 -0
- data/MIT-LICENSE +20 -0
- data/README +44 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/install.rb +1 -0
- data/lib/encoder.rb +92 -0
- data/rails/init.rb +2 -0
- data/tasks/encoder_tasks.rake +4 -0
- data/test/database.rb +36 -0
- data/test/functional/encoder_test.rb +24 -0
- data/test/test_helper.rb +13 -0
- data/test/unit/encoder_test.rb +69 -0
- data/uninstall.rb +1 -0
- metadata +71 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Jon Morton
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
Encode
|
2
|
+
=========
|
3
|
+
|
4
|
+
Encode makes it easy to go from codes to meaningful strings.
|
5
|
+
|
6
|
+
Example
|
7
|
+
=======
|
8
|
+
|
9
|
+
Suppose you have a task in one of three possible states: pending, active, finished. When you store tasks, you'd like to have the state represented as P for pending, A for active, and F, for finished. However, you don't want to worry about the details of turning a state into a specific character.
|
10
|
+
|
11
|
+
t = Task.new('feed the cat')
|
12
|
+
|
13
|
+
# By default
|
14
|
+
t.status = Status::Pending
|
15
|
+
t.status # => 'P'
|
16
|
+
t.status.decode # => 'Pending'
|
17
|
+
|
18
|
+
# You'd probably encapsulate this in a method though wouldn't you?
|
19
|
+
t.finish!
|
20
|
+
|
21
|
+
# How should that be implemented though?
|
22
|
+
@status = 'f'
|
23
|
+
@status = 'finished'
|
24
|
+
@status = Task::Status::Finished
|
25
|
+
|
26
|
+
However, you want to store the state as a single character behind the scenes without having to define a bunch of custom getters or setters.
|
27
|
+
|
28
|
+
class Task
|
29
|
+
code :status do
|
30
|
+
Status::Pending = "P"
|
31
|
+
Status::Active = "A"
|
32
|
+
Status::Finished = "F"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
To Do
|
37
|
+
=====
|
38
|
+
|
39
|
+
[ ] Auto-mixin on init
|
40
|
+
[ ] Make a proper gem
|
41
|
+
[ ] Choose a better name
|
42
|
+
[ ] Use shoulda or rspec (maybe)
|
43
|
+
|
44
|
+
Copyright (c) 2010 Jon Morton, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the encode plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the encode plugin.'
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'Encode'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'jeweler'
|
27
|
+
Jeweler::Tasks.new do |gemspec|
|
28
|
+
gemspec.name = "encoder"
|
29
|
+
gemspec.summary = "Make magic numbers and letters meaningful."
|
30
|
+
gemspec.description = "Simplify turning abbreviations into descriptions and vice versa."
|
31
|
+
gemspec.email = "jon.morton@gmail.com "
|
32
|
+
gemspec.homepage = "http://github.com/jmorton/encoder"
|
33
|
+
gemspec.authors = ["Jon Morton"]
|
34
|
+
end
|
35
|
+
Jeweler::GemcutterTasks.new
|
36
|
+
rescue LoadError
|
37
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
38
|
+
end
|
39
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
data/lib/encoder.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
module Encoder
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
extend ClassMethods
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
#
|
12
|
+
# Creates getter and setter methods for an attribute. The getter
|
13
|
+
# returns a 'decodable' string that provides more meaning.
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
#
|
17
|
+
# class Task
|
18
|
+
# include Encoder
|
19
|
+
# code :priority do
|
20
|
+
# Priority::Low = "L"
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# t = Task.new
|
25
|
+
# t.priority = Priority::Low
|
26
|
+
# t.priority # => "L"
|
27
|
+
# t.priority.decode # => "Low"
|
28
|
+
#
|
29
|
+
def code(attribute_name, &block)
|
30
|
+
|
31
|
+
# Create a 'namespace' for constants
|
32
|
+
const_set(attribute_name.to_s.camelcase, Module.new)
|
33
|
+
|
34
|
+
# Expecting constants to be assigned values.
|
35
|
+
yield
|
36
|
+
|
37
|
+
# create setter for attribute
|
38
|
+
self.send(:define_method, "#{attribute_name}=") do |arg|
|
39
|
+
|
40
|
+
# At the end of this method, the underlying attribute will be set
|
41
|
+
# to the value of this variable.
|
42
|
+
encoded_value = nil
|
43
|
+
|
44
|
+
# Retrieve the module where the constants for this attribute are defined.
|
45
|
+
namespace = self.class.const_get(attribute_name.to_s.camelcase)
|
46
|
+
|
47
|
+
# Since the given value might not match the constant name exactly
|
48
|
+
# (because of case sensitivity or white space variations) we
|
49
|
+
# normalize it a bit.
|
50
|
+
normalized = arg && arg.gsub(/\s+/,'').downcase
|
51
|
+
|
52
|
+
# Now we look for a constant whose name or actual value match the
|
53
|
+
# normalized argument. We 'tap' whatever constant name is found
|
54
|
+
# and lookup the actual value.
|
55
|
+
namespace.constants.find do |const_name|
|
56
|
+
normalized == const_name.downcase ||
|
57
|
+
normalized == namespace.const_get(const_name).downcase
|
58
|
+
end.tap do |match|
|
59
|
+
encoded_value = namespace.const_get(match) if match
|
60
|
+
end
|
61
|
+
|
62
|
+
# Set the value to whatever we found, possibly nil
|
63
|
+
self.write_attribute(attribute_name, encoded_value)
|
64
|
+
end
|
65
|
+
|
66
|
+
# create getter for attribute
|
67
|
+
self.send(:define_method, attribute_name) do
|
68
|
+
|
69
|
+
encoded_attribute = self.read_attribute(attribute_name)
|
70
|
+
|
71
|
+
namespace = self.class.const_get(attribute_name.to_s.camelcase)
|
72
|
+
|
73
|
+
decoded_value = namespace.constants.select do |constant|
|
74
|
+
namespace.const_get(constant) == encoded_attribute
|
75
|
+
end.first
|
76
|
+
|
77
|
+
encoded_attribute.instance_variable_set(:@decoding, decoded_value)
|
78
|
+
|
79
|
+
class << encoded_attribute
|
80
|
+
def decode
|
81
|
+
@decoding && @decoding.underscore.titleize
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
return encoded_attribute
|
86
|
+
end # -- dynamic getter method
|
87
|
+
|
88
|
+
end # -- code()
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/rails/init.rb
ADDED
data/test/database.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_record'
|
5
|
+
gem 'sqlite3-ruby'
|
6
|
+
|
7
|
+
require File.dirname(__FILE__) + '/../rails/init'
|
8
|
+
|
9
|
+
ActiveRecord::Base.logger = Logger.new('/tmp/encoder.log')
|
10
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => '/tmp/encoder.sqlite')
|
11
|
+
ActiveRecord::Migration.verbose = false
|
12
|
+
ActiveRecord::Base.default_timezone = :utc if Time.zone.nil?
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define do
|
15
|
+
create_table :tasks, :force => true do |table|
|
16
|
+
table.string :status
|
17
|
+
table.string :priority
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Task < ActiveRecord::Base
|
22
|
+
include ::Encoder
|
23
|
+
|
24
|
+
code :status do
|
25
|
+
Status::New = "N"
|
26
|
+
Status::Pending = "P"
|
27
|
+
Status::Finished = "F"
|
28
|
+
Status::OverDue = "O"
|
29
|
+
end
|
30
|
+
|
31
|
+
code :priority do
|
32
|
+
Priority::High = "H"
|
33
|
+
Priority::Low = "L"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../test_helper'))
|
2
|
+
|
3
|
+
class EncoderTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "setting an attribute using a constant persists the encoding" do
|
6
|
+
task = ::Task.new
|
7
|
+
task.status = Task::Status::New
|
8
|
+
task.save
|
9
|
+
|
10
|
+
db_task = ::Task.first
|
11
|
+
assert db_task.status == 'N'
|
12
|
+
end
|
13
|
+
|
14
|
+
test "setting an attribute using a description persists the correct encoding" do
|
15
|
+
task = ::Task.new
|
16
|
+
task.status = 'New'
|
17
|
+
task.save
|
18
|
+
|
19
|
+
db_task = ::Task.first
|
20
|
+
assert db_task.status == 'N'
|
21
|
+
assert db_task.status.decode == 'New'
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'active_support'
|
9
|
+
require 'active_support/test_case'
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/encoder'))
|
13
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'database'))
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../test_helper'))
|
2
|
+
|
3
|
+
class EncoderTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "setting an attribute using a constant" do
|
6
|
+
task = ::Task.new
|
7
|
+
task.status = Task::Status::New
|
8
|
+
assert task.status == Task::Status::New
|
9
|
+
end
|
10
|
+
|
11
|
+
test "setting an attribute using a verbose value" do
|
12
|
+
task = ::Task.new
|
13
|
+
task.status = "New"
|
14
|
+
assert task.status == Task::Status::New
|
15
|
+
end
|
16
|
+
|
17
|
+
test "setting an attribute using a an invalid value overwrites a valid one" do
|
18
|
+
task = ::Task.new
|
19
|
+
task.status = "New"
|
20
|
+
task.status = "Invalid"
|
21
|
+
assert task.status == nil
|
22
|
+
end
|
23
|
+
|
24
|
+
test "decoding an attribute should match the constant name" do
|
25
|
+
task = ::Task.new
|
26
|
+
task.status = Task::Status::New
|
27
|
+
assert task.status.decode == 'New'
|
28
|
+
end
|
29
|
+
|
30
|
+
test "encoding a description ignores caps" do
|
31
|
+
task = ::Task.new
|
32
|
+
task.status = 'new'
|
33
|
+
assert task.status == Task::Status::New
|
34
|
+
task.status = 'NEW'
|
35
|
+
assert task.status == Task::Status::New
|
36
|
+
end
|
37
|
+
|
38
|
+
test "encoding a multiword description" do
|
39
|
+
task = ::Task.new
|
40
|
+
task.status = 'over due'
|
41
|
+
assert task.status == Task::Status::OverDue
|
42
|
+
end
|
43
|
+
|
44
|
+
test "decoding a multiword description" do
|
45
|
+
task = ::Task.new
|
46
|
+
task.status = Task::Status::OverDue
|
47
|
+
assert task.status.decode == 'Over Due'
|
48
|
+
end
|
49
|
+
|
50
|
+
test "setting an encoded attribute to nil" do
|
51
|
+
task = ::Task.new
|
52
|
+
task.status = nil
|
53
|
+
assert task.status == nil
|
54
|
+
end
|
55
|
+
|
56
|
+
test "a code's attribute name corresponds to a camelcased namespace" do
|
57
|
+
task = ::Task.new
|
58
|
+
|
59
|
+
class ::Task
|
60
|
+
code :foo_bar do
|
61
|
+
FooBar::Baz = 1
|
62
|
+
FooBar::Buzz = 2
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
assert Task.const_defined?(:FooBar)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: encoder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Morton
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-03-20 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Simplify turning abbreviations into descriptions and vice versa.
|
17
|
+
email: "jon.morton@gmail.com "
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- MIT-LICENSE
|
27
|
+
- README
|
28
|
+
- Rakefile
|
29
|
+
- VERSION
|
30
|
+
- install.rb
|
31
|
+
- lib/encoder.rb
|
32
|
+
- rails/init.rb
|
33
|
+
- tasks/encoder_tasks.rake
|
34
|
+
- test/database.rb
|
35
|
+
- test/functional/encoder_test.rb
|
36
|
+
- test/test_helper.rb
|
37
|
+
- test/unit/encoder_test.rb
|
38
|
+
- uninstall.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/jmorton/encoder
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.3.5
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Make magic numbers and letters meaningful.
|
67
|
+
test_files:
|
68
|
+
- test/database.rb
|
69
|
+
- test/functional/encoder_test.rb
|
70
|
+
- test/test_helper.rb
|
71
|
+
- test/unit/encoder_test.rb
|