charisma 0.0.1 → 0.1.0

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.
@@ -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