charisma 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
5
5
  s.name = 'charisma'
6
6
  s.version = Charisma::VERSION
7
7
  s.platform = Gem::Platform::RUBY
8
- s.date = '2011-03-21'
8
+ s.date = "2011-03-22"
9
9
  s.authors = ['Andy Rossmeissl', 'Seamus Abshere']
10
10
  s.email = 'andy@rossmeissl.net'
11
11
  s.homepage = 'http://github.com/brighterplanet/charisma'
@@ -24,10 +24,16 @@ Gem::Specification.new do |s|
24
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
25
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
26
  s.require_paths = ['lib']
27
+
28
+ s.add_dependency 'activesupport'
29
+ s.add_dependency 'actionpack'
30
+ s.add_dependency 'blockenspiel'
31
+ s.add_dependency 'conversions'
27
32
 
28
33
  s.add_development_dependency 'bundler'
29
34
  s.add_development_dependency 'bueller'
30
35
  s.add_development_dependency 'rake'
31
36
  s.add_development_dependency 'rcov'
37
+ s.add_development_dependency 'supermodel'
32
38
  end
33
39
 
@@ -1,3 +1,39 @@
1
+ require 'active_support'
2
+ require 'active_support/version'
3
+ %w{
4
+ active_support/inflector/methods
5
+ active_support/core_ext/class/attribute_accessors
6
+ active_support/core_ext/string/output_safety
7
+ active_support/core_ext/module/delegation
8
+ }.each do |active_support_3_requirement|
9
+ require active_support_3_requirement
10
+ end if ActiveSupport::VERSION::MAJOR == 3
11
+
12
+ require 'action_pack'
13
+ require 'active_support/version'
14
+ %w{
15
+ action_view/helpers/number_helper
16
+ }.each do |action_pack_3_requirement|
17
+ require action_pack_3_requirement
18
+ end if ActionPack::VERSION::MAJOR == 3
19
+
20
+ require 'blockenspiel'
21
+ require 'conversions'
22
+
23
+ require 'charisma/base'
24
+ require 'charisma/base/class_methods'
25
+ require 'charisma/characteristic'
26
+ require 'charisma/characterization'
27
+ require 'charisma/measurement'
28
+ require 'charisma/measurement/length'
29
+ require 'charisma/curator'
30
+ require 'charisma/curator/curation'
31
+ require 'charisma/number_helper'
32
+
33
+
1
34
  module Charisma
2
- # Your code goes here...
35
+ def self.included(base)
36
+ base.send :include, Base
37
+ base.extend Base::ClassMethods
38
+ end
3
39
  end
@@ -0,0 +1,9 @@
1
+ module Charisma
2
+ module Base
3
+ def characteristics
4
+ @curator ||= Curator.new(self)
5
+ end
6
+ end
7
+
8
+ class InvalidMeasurementError < StandardError; end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Charisma
2
+ module Base
3
+ module ClassMethods
4
+ def self.extended(base)
5
+ base.send :class_variable_set, :@@characterization, Characterization.new
6
+ base.send :cattr_reader, :characterization
7
+ end
8
+ def characterize(&blk)
9
+ Blockenspiel.invoke(blk, characterization) if block_given?
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,12 @@
1
+ module Charisma
2
+ class Characteristic
3
+ attr_reader :name, :proc, :accessor, :measurement
4
+
5
+ def initialize(name, options, &blk)
6
+ @name = name
7
+ @proc = blk if block_given?
8
+ @accessor = options[:display_with]
9
+ @measurement = options[:measures]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ module Charisma
2
+ class Characterization
3
+ attr_reader :characteristics
4
+
5
+ def initialize
6
+ @characteristics = {}
7
+ end
8
+
9
+ def [](name)
10
+ characteristics[name]
11
+ end
12
+
13
+ include Blockenspiel::DSL
14
+ def has(name, options = {}, &blk)
15
+ name = name.to_sym
16
+ characteristics[name] = Characteristic.new(name, options, &blk)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module Charisma
2
+ class Curator
3
+ def initialize(base)
4
+ @subject = base
5
+ end
6
+
7
+ def [](name)
8
+ Curation.new @subject.send(name), @subject.class.characterization[name]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,65 @@
1
+ module Charisma
2
+ class Curator
3
+ class Curation
4
+ attr_reader :value, :characteristic
5
+
6
+ def initialize(value, characteristic)
7
+ @value = value
8
+ @characteristic = characteristic
9
+ end
10
+
11
+ delegate :to_s, :units, :u, :to => :render
12
+
13
+ def method_missing(*args)
14
+ begin
15
+ render.send(*args)
16
+ rescue NoMethodError
17
+ super
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def render
24
+ if characteristic.proc
25
+ render_proc
26
+ elsif characteristic.accessor
27
+ use_accessor
28
+ elsif characteristic.measurement
29
+ defer_to_measurement
30
+ elsif value.respond_to? :as_characteristic
31
+ defer_to_value
32
+ else
33
+ render_value
34
+ end
35
+ end
36
+
37
+ def render_proc
38
+ characteristic.proc.call(value)
39
+ end
40
+
41
+ def use_accessor
42
+ value.send(characteristic.accessor)
43
+ end
44
+
45
+ def defer_to_measurement
46
+ case characteristic.measurement
47
+ when Class
48
+ characteristic.measurement.new(value)
49
+ when Symbol
50
+ "Charisma::Measurement::#{characteristic.measurement.to_s.camelize}".constantize.new(value)
51
+ else
52
+ raise InvalidMeasurementError
53
+ end
54
+ end
55
+
56
+ def defer_to_value
57
+ value.as_characteristic
58
+ end
59
+
60
+ def render_value
61
+ value
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,47 @@
1
+ module Charisma
2
+ class Measurement
3
+ attr_reader :value
4
+
5
+ def initialize(value)
6
+ @value = value
7
+ end
8
+
9
+ def to_s
10
+ "#{NumberHelper.delimit value} #{u}"
11
+ end
12
+
13
+ def to_f
14
+ value.to_f
15
+ end
16
+
17
+ def units
18
+ self.class.unit
19
+ end
20
+
21
+ def u
22
+ self.class.unit_abbreviation
23
+ end
24
+
25
+ def method_missing(*args)
26
+ if Conversions.conversions[units.to_sym][args.first]
27
+ to_f.send(units.to_sym).to(args.first)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ class << self
34
+ def units(units)
35
+ @units, @units_abbreviation = units.to_a.flatten
36
+ end
37
+
38
+ def unit
39
+ @units
40
+ end
41
+
42
+ def unit_abbreviation
43
+ @units_abbreviation
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,7 @@
1
+ module Charisma
2
+ class Measurement
3
+ class Length < Measurement
4
+ units :meters => 'm'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module Charisma
2
+ class NumberHelper
3
+ extend ActionView::Helpers::NumberHelper
4
+
5
+ def self.delimit(number)
6
+ number_with_delimiter number, :delimiter => ",", :separator => "."
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
- module Charisma
2
- VERSION = "0.0.1"
3
- end
1
+ module Charisma
2
+ VERSION = "0.1.0"
3
+ end
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
+ require 'supermodel'
3
4
 
4
5
  $LOAD_PATH.unshift(File.dirname(__FILE__))
5
6
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
@@ -7,3 +8,56 @@ require 'charisma'
7
8
 
8
9
  class Test::Unit::TestCase
9
10
  end
11
+
12
+ class RelativeAstronomicMass < Charisma::Measurement # or don't inherit and provide everything yourself
13
+ units :hollagrams => 'hg'
14
+ # before_ and after_ filters or some other reason to use this as opposed to Charisma::Measurements::Mass
15
+ end
16
+
17
+ class Spaceship < SuperModel::Base
18
+ attributes :window_count, :name, :size
19
+ belongs_to :make, :class_name => 'SpaceshipMake', :primary_key => 'name'
20
+ belongs_to :fuel, :class_name => 'SpaceshipFuel', :primary_key => 'name'
21
+ belongs_to :destination, :class_name => 'Planet', :primary_key => 'name'
22
+
23
+ include Charisma
24
+ characterize do
25
+ has :make, :display_with => :name
26
+ has :fuel
27
+ has :window_count do |window_count|
28
+ "#{window_count} windows"
29
+ end
30
+ has :size, :measures => :length # uses Charisma::Measurements::Length
31
+ has :weight, :measures => RelativeAstronomicMass
32
+ has :name
33
+ has :destination
34
+ end
35
+ end
36
+
37
+ class SpaceshipMake < SuperModel::Base
38
+ has_many :spaceships
39
+ attributes :name
40
+ self.primary_key = :name
41
+ end
42
+
43
+ class SpaceshipFuel < SuperModel::Base
44
+ has_many :spaceships
45
+ attributes :name, :emission_factor
46
+ self.primary_key = :name
47
+
48
+ def as_characteristic
49
+ "#{name} (#{emission_factor} kg CO2/L)"
50
+ end
51
+ end
52
+
53
+ class Planet < SuperModel::Base
54
+ has_many :spaceships
55
+ attributes :name
56
+ self.primary_key = :name
57
+
58
+ def to_s
59
+ name
60
+ end
61
+ end
62
+
63
+ Conversions.register :hollagrams, :supertons, 2
@@ -1,7 +1,41 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestCharisma < Test::Unit::TestCase
4
- def test_something_for_real
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
4
+ def test_simple_attribute_characteristic
5
+ spaceship = Spaceship.new :name => 'Amaroq'
6
+ assert_equal 'Amaroq', spaceship.characteristics[:name].to_s
7
+ end
8
+ def test_measured_attribute
9
+ spaceship = Spaceship.new :size => 10 # meters
10
+ assert_equal '10 m', spaceship.characteristics[:size].to_s
11
+ end
12
+ def test_classified_attribute
13
+ spaceship = Spaceship.new :weight => 1_000_000 # hg
14
+ assert_equal '1,000,000 hg', spaceship.characteristics[:weight].to_s
15
+ end
16
+ def test_units
17
+ spaceship = Spaceship.new :weight => '1000000.1' # kg
18
+ assert_equal :hollagrams, spaceship.characteristics[:weight].units
19
+ assert_equal 'hg', spaceship.characteristics[:weight].u
20
+ assert_equal 2_000_000.2, spaceship.characteristics[:weight].supertons
21
+ end
22
+ def test_attribute_with_custom_display
23
+ spaceship = Spaceship.new :window_count => 10
24
+ assert_equal '10 windows', spaceship.characteristics[:window_count].to_s
25
+ end
26
+ def test_simple_association
27
+ planet = Planet.create :name => 'Pluto'
28
+ spaceship = Spaceship.new :destination => planet
29
+ assert_equal 'Pluto', spaceship.characteristics[:destination].to_s
30
+ end
31
+ def test_association_with_display_hint
32
+ make = SpaceshipMake.create :name => 'Boeing'
33
+ spaceship = Spaceship.new :make => make
34
+ assert_equal 'Boeing', spaceship.characteristics[:make].to_s
35
+ end
36
+ def test_association_with_prepared_display
37
+ fuel = SpaceshipFuel.create :name => 'Kerosene', :emission_factor => 10
38
+ spaceship = Spaceship.new :fuel => fuel
39
+ assert_equal 'Kerosene (10 kg CO2/L)', spaceship.characteristics[:fuel].to_s
6
40
  end
7
41
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: charisma
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 0
9
8
  - 1
10
- version: 0.0.1
9
+ - 0
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andy Rossmeissl
@@ -16,13 +16,13 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-03-21 00:00:00 -04:00
19
+ date: 2011-03-22 00:00:00 -04:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  prerelease: false
24
- name: bundler
25
- type: :development
24
+ name: activesupport
25
+ type: :runtime
26
26
  version_requirements: &id001 !ruby/object:Gem::Requirement
27
27
  none: false
28
28
  requirements:
@@ -35,8 +35,8 @@ dependencies:
35
35
  requirement: *id001
36
36
  - !ruby/object:Gem::Dependency
37
37
  prerelease: false
38
- name: bueller
39
- type: :development
38
+ name: actionpack
39
+ type: :runtime
40
40
  version_requirements: &id002 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
@@ -49,8 +49,8 @@ dependencies:
49
49
  requirement: *id002
50
50
  - !ruby/object:Gem::Dependency
51
51
  prerelease: false
52
- name: rake
53
- type: :development
52
+ name: blockenspiel
53
+ type: :runtime
54
54
  version_requirements: &id003 !ruby/object:Gem::Requirement
55
55
  none: false
56
56
  requirements:
@@ -63,8 +63,8 @@ dependencies:
63
63
  requirement: *id003
64
64
  - !ruby/object:Gem::Dependency
65
65
  prerelease: false
66
- name: rcov
67
- type: :development
66
+ name: conversions
67
+ type: :runtime
68
68
  version_requirements: &id004 !ruby/object:Gem::Requirement
69
69
  none: false
70
70
  requirements:
@@ -75,6 +75,76 @@ dependencies:
75
75
  - 0
76
76
  version: "0"
77
77
  requirement: *id004
78
+ - !ruby/object:Gem::Dependency
79
+ prerelease: false
80
+ name: bundler
81
+ type: :development
82
+ version_requirements: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ requirement: *id005
92
+ - !ruby/object:Gem::Dependency
93
+ prerelease: false
94
+ name: bueller
95
+ type: :development
96
+ version_requirements: &id006 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ requirement: *id006
106
+ - !ruby/object:Gem::Dependency
107
+ prerelease: false
108
+ name: rake
109
+ type: :development
110
+ version_requirements: &id007 !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: 3
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ requirement: *id007
120
+ - !ruby/object:Gem::Dependency
121
+ prerelease: false
122
+ name: rcov
123
+ type: :development
124
+ version_requirements: &id008 !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ hash: 3
130
+ segments:
131
+ - 0
132
+ version: "0"
133
+ requirement: *id008
134
+ - !ruby/object:Gem::Dependency
135
+ prerelease: false
136
+ name: supermodel
137
+ type: :development
138
+ version_requirements: &id009 !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ hash: 3
144
+ segments:
145
+ - 0
146
+ version: "0"
147
+ requirement: *id009
78
148
  description: Define strategies for accessing and displaying a subset of your classes' attributes
79
149
  email: andy@rossmeissl.net
80
150
  executables: []
@@ -93,6 +163,15 @@ files:
93
163
  - Rakefile
94
164
  - charisma.gemspec
95
165
  - lib/charisma.rb
166
+ - lib/charisma/base.rb
167
+ - lib/charisma/base/class_methods.rb
168
+ - lib/charisma/characteristic.rb
169
+ - lib/charisma/characterization.rb
170
+ - lib/charisma/curator.rb
171
+ - lib/charisma/curator/curation.rb
172
+ - lib/charisma/measurement.rb
173
+ - lib/charisma/measurement/length.rb
174
+ - lib/charisma/number_helper.rb
96
175
  - lib/charisma/version.rb
97
176
  - test/helper.rb
98
177
  - test/test_charisma.rb