monetra-ruby 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/Rakefile +35 -0
  2. data/lib/monetra.rb +239 -0
  3. data/lib/monetra/active_support.rb +42 -0
  4. data/lib/monetra/active_support/binding_of_caller.rb +84 -0
  5. data/lib/monetra/active_support/breakpoint.rb +523 -0
  6. data/lib/monetra/active_support/caching_tools.rb +62 -0
  7. data/lib/monetra/active_support/clean_logger.rb +38 -0
  8. data/lib/monetra/active_support/core_ext.rb +1 -0
  9. data/lib/monetra/active_support/core_ext/array.rb +7 -0
  10. data/lib/monetra/active_support/core_ext/array/conversions.rb +72 -0
  11. data/lib/monetra/active_support/core_ext/array/grouping.rb +46 -0
  12. data/lib/monetra/active_support/core_ext/bigdecimal.rb +3 -0
  13. data/lib/monetra/active_support/core_ext/bigdecimal/formatting.rb +7 -0
  14. data/lib/monetra/active_support/core_ext/blank.rb +50 -0
  15. data/lib/monetra/active_support/core_ext/cgi.rb +5 -0
  16. data/lib/monetra/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
  17. data/lib/monetra/active_support/core_ext/class.rb +3 -0
  18. data/lib/monetra/active_support/core_ext/class/attribute_accessors.rb +44 -0
  19. data/lib/monetra/active_support/core_ext/class/inheritable_attributes.rb +115 -0
  20. data/lib/monetra/active_support/core_ext/class/removal.rb +24 -0
  21. data/lib/monetra/active_support/core_ext/date.rb +6 -0
  22. data/lib/monetra/active_support/core_ext/date/conversions.rb +39 -0
  23. data/lib/monetra/active_support/core_ext/enumerable.rb +62 -0
  24. data/lib/monetra/active_support/core_ext/exception.rb +33 -0
  25. data/lib/monetra/active_support/core_ext/hash.rb +13 -0
  26. data/lib/monetra/active_support/core_ext/hash/conversions.rb +148 -0
  27. data/lib/monetra/active_support/core_ext/hash/diff.rb +11 -0
  28. data/lib/monetra/active_support/core_ext/hash/indifferent_access.rb +88 -0
  29. data/lib/monetra/active_support/core_ext/hash/keys.rb +53 -0
  30. data/lib/monetra/active_support/core_ext/hash/reverse_merge.rb +25 -0
  31. data/lib/monetra/active_support/core_ext/integer.rb +7 -0
  32. data/lib/monetra/active_support/core_ext/integer/even_odd.rb +24 -0
  33. data/lib/monetra/active_support/core_ext/integer/inflections.rb +15 -0
  34. data/lib/monetra/active_support/core_ext/kernel.rb +4 -0
  35. data/lib/monetra/active_support/core_ext/kernel/agnostics.rb +11 -0
  36. data/lib/monetra/active_support/core_ext/kernel/daemonizing.rb +15 -0
  37. data/lib/monetra/active_support/core_ext/kernel/reporting.rb +51 -0
  38. data/lib/monetra/active_support/core_ext/kernel/requires.rb +24 -0
  39. data/lib/monetra/active_support/core_ext/load_error.rb +38 -0
  40. data/lib/monetra/active_support/core_ext/logger.rb +16 -0
  41. data/lib/monetra/active_support/core_ext/module.rb +7 -0
  42. data/lib/monetra/active_support/core_ext/module/aliasing.rb +57 -0
  43. data/lib/monetra/active_support/core_ext/module/attr_internal.rb +31 -0
  44. data/lib/monetra/active_support/core_ext/module/attribute_accessors.rb +44 -0
  45. data/lib/monetra/active_support/core_ext/module/delegation.rb +41 -0
  46. data/lib/monetra/active_support/core_ext/module/inclusion.rb +11 -0
  47. data/lib/monetra/active_support/core_ext/module/introspection.rb +21 -0
  48. data/lib/monetra/active_support/core_ext/module/loading.rb +13 -0
  49. data/lib/monetra/active_support/core_ext/name_error.rb +20 -0
  50. data/lib/monetra/active_support/core_ext/numeric.rb +7 -0
  51. data/lib/monetra/active_support/core_ext/numeric/bytes.rb +44 -0
  52. data/lib/monetra/active_support/core_ext/numeric/time.rb +72 -0
  53. data/lib/monetra/active_support/core_ext/object.rb +2 -0
  54. data/lib/monetra/active_support/core_ext/object/extending.rb +47 -0
  55. data/lib/monetra/active_support/core_ext/object/misc.rb +34 -0
  56. data/lib/monetra/active_support/core_ext/pathname.rb +7 -0
  57. data/lib/monetra/active_support/core_ext/pathname/clean_within.rb +14 -0
  58. data/lib/monetra/active_support/core_ext/proc.rb +12 -0
  59. data/lib/monetra/active_support/core_ext/range.rb +5 -0
  60. data/lib/monetra/active_support/core_ext/range/conversions.rb +21 -0
  61. data/lib/monetra/active_support/core_ext/string.rb +13 -0
  62. data/lib/monetra/active_support/core_ext/string/access.rb +58 -0
  63. data/lib/monetra/active_support/core_ext/string/conversions.rb +19 -0
  64. data/lib/monetra/active_support/core_ext/string/inflections.rb +153 -0
  65. data/lib/monetra/active_support/core_ext/string/iterators.rb +17 -0
  66. data/lib/monetra/active_support/core_ext/string/starts_ends_with.rb +20 -0
  67. data/lib/monetra/active_support/core_ext/symbol.rb +12 -0
  68. data/lib/monetra/active_support/core_ext/time.rb +7 -0
  69. data/lib/monetra/active_support/core_ext/time/calculations.rb +188 -0
  70. data/lib/monetra/active_support/core_ext/time/conversions.rb +36 -0
  71. data/lib/monetra/active_support/dependencies.rb +187 -0
  72. data/lib/monetra/active_support/deprecation.rb +106 -0
  73. data/lib/monetra/active_support/inflections.rb +53 -0
  74. data/lib/monetra/active_support/inflector.rb +179 -0
  75. data/lib/monetra/active_support/json.rb +37 -0
  76. data/lib/monetra/active_support/json/encoders.rb +25 -0
  77. data/lib/monetra/active_support/json/encoders/core.rb +65 -0
  78. data/lib/monetra/active_support/option_merger.rb +25 -0
  79. data/lib/monetra/active_support/ordered_options.rb +50 -0
  80. data/lib/monetra/active_support/reloadable.rb +30 -0
  81. data/lib/monetra/active_support/values/time_zone.rb +180 -0
  82. data/lib/monetra/active_support/vendor/builder.rb +13 -0
  83. data/lib/monetra/active_support/vendor/builder/blankslate.rb +63 -0
  84. data/lib/monetra/active_support/vendor/builder/xchar.rb +112 -0
  85. data/lib/monetra/active_support/vendor/builder/xmlbase.rb +145 -0
  86. data/lib/monetra/active_support/vendor/builder/xmlevents.rb +63 -0
  87. data/lib/monetra/active_support/vendor/builder/xmlmarkup.rb +328 -0
  88. data/lib/monetra/active_support/vendor/flexmock.rb +84 -0
  89. data/lib/monetra/active_support/vendor/xml_simple.rb +1019 -0
  90. data/lib/monetra/active_support/version.rb +9 -0
  91. data/lib/monetra/active_support/whiny_nil.rb +38 -0
  92. data/test/test.rb +21 -0
  93. metadata +167 -0
@@ -0,0 +1,24 @@
1
+ class Class #:nodoc:
2
+ def remove_subclasses
3
+ Object.remove_subclasses_of(self)
4
+ end
5
+
6
+ def subclasses
7
+ Object.subclasses_of(self).map { |o| o.to_s }
8
+ end
9
+
10
+ def remove_class(*klasses)
11
+ klasses.flatten.each do |klass|
12
+ # Skip this class if there is nothing bound to this name
13
+ next unless defined?(klass.name)
14
+
15
+ basename = klass.to_s.split("::").last
16
+ parent = klass.parent
17
+
18
+ # Skip this class if it does not match the current one bound to this name
19
+ next unless parent.const_defined?(basename) && klass = parent.const_get(basename)
20
+
21
+ parent.send :remove_const, basename unless parent == klass
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ require 'date'
2
+ require File.dirname(__FILE__) + '/date/conversions'
3
+
4
+ class Date#:nodoc:
5
+ include ActiveSupport::CoreExtensions::Date::Conversions
6
+ end
@@ -0,0 +1,39 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module Date #:nodoc:
4
+ # Getting dates in different convenient string representations and other objects
5
+ module Conversions
6
+ DATE_FORMATS = {
7
+ :short => "%e %b",
8
+ :long => "%B %e, %Y"
9
+ }
10
+
11
+ def self.included(klass) #:nodoc:
12
+ klass.send(:alias_method, :to_default_s, :to_s)
13
+ klass.send(:alias_method, :to_s, :to_formatted_s)
14
+ end
15
+
16
+ def to_formatted_s(format = :default)
17
+ DATE_FORMATS[format] ? strftime(DATE_FORMATS[format]).strip : to_default_s
18
+ end
19
+
20
+ # To be able to keep Dates and Times interchangeable on conversions
21
+ def to_date
22
+ self
23
+ end
24
+
25
+ def to_time(form = :local)
26
+ if respond_to?(:hour)
27
+ ::Time.send(form, year, month, day, hour, min, sec)
28
+ else
29
+ ::Time.send(form, year, month, day)
30
+ end
31
+ end
32
+
33
+ def xmlschema
34
+ to_time.xmlschema
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,62 @@
1
+ module Enumerable #:nodoc:
2
+ # Collect an enumerable into sets, grouped by the result of a block. Useful,
3
+ # for example, for grouping records by date.
4
+ #
5
+ # e.g.
6
+ #
7
+ # latest_transcripts.group_by(&:day).each do |day, transcripts|
8
+ # p "#{day} -> #{transcripts.map(&:class) * ', '}"
9
+ # end
10
+ # "2006-03-01 -> Transcript"
11
+ # "2006-02-28 -> Transcript"
12
+ # "2006-02-27 -> Transcript, Transcript"
13
+ # "2006-02-26 -> Transcript, Transcript"
14
+ # "2006-02-25 -> Transcript"
15
+ # "2006-02-24 -> Transcript, Transcript"
16
+ # "2006-02-23 -> Transcript"
17
+ def group_by
18
+ inject({}) do |groups, element|
19
+ (groups[yield(element)] ||= []) << element
20
+ groups
21
+ end
22
+ end
23
+
24
+ # Calculates a sum from the elements. Examples:
25
+ #
26
+ # payments.sum { |p| p.price * p.tax_rate }
27
+ # payments.sum(&:price)
28
+ #
29
+ # This is instead of payments.inject { |sum, p| sum + p.price }
30
+ #
31
+ # Also calculates sums without the use of a block:
32
+ # [5, 15, 10].sum # => 30
33
+ #
34
+ # The default identity (sum of an empty list) is zero.
35
+ # However, you can override this default:
36
+ #
37
+ # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
38
+ #
39
+ def sum(identity = 0, &block)
40
+ return identity unless size > 0
41
+ if block_given?
42
+ map(&block).sum
43
+ else
44
+ inject { |sum, element| sum + element }
45
+ end
46
+ end
47
+
48
+ # Convert an enumerable to a hash. Examples:
49
+ #
50
+ # people.index_by(&:login)
51
+ # => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
52
+ # people.index_by { |person| "#{person.first_name} #{person.last_name}" }
53
+ # => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
54
+ #
55
+ def index_by
56
+ inject({}) do |accum, elem|
57
+ accum[yield(elem)] = elem
58
+ accum
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,33 @@
1
+ class Exception # :nodoc:
2
+ def clean_message
3
+ Pathname.clean_within message
4
+ end
5
+
6
+ TraceSubstitutions = []
7
+ FrameworkRegexp = /generated|vendor|dispatch|ruby|script\/\w+/
8
+
9
+ def clean_backtrace
10
+ backtrace.collect do |line|
11
+ Pathname.clean_within(TraceSubstitutions.inject(line) do |line, (regexp, sub)|
12
+ line.gsub regexp, sub
13
+ end)
14
+ end
15
+ end
16
+
17
+ def application_backtrace
18
+ before_application_frame = true
19
+
20
+ trace = clean_backtrace.reject do |line|
21
+ non_app_frame = (line =~ FrameworkRegexp)
22
+ before_application_frame = false unless non_app_frame
23
+ non_app_frame && ! before_application_frame
24
+ end
25
+
26
+ # If we didn't find any application frames, return an empty app trace.
27
+ before_application_frame ? [] : trace
28
+ end
29
+
30
+ def framework_backtrace
31
+ clean_backtrace.select {|line| line =~ FrameworkRegexp}
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/hash/keys'
2
+ require File.dirname(__FILE__) + '/hash/indifferent_access'
3
+ require File.dirname(__FILE__) + '/hash/reverse_merge'
4
+ require File.dirname(__FILE__) + '/hash/conversions'
5
+ require File.dirname(__FILE__) + '/hash/diff'
6
+
7
+ class Hash #:nodoc:
8
+ include ActiveSupport::CoreExtensions::Hash::Keys
9
+ include ActiveSupport::CoreExtensions::Hash::IndifferentAccess
10
+ include ActiveSupport::CoreExtensions::Hash::ReverseMerge
11
+ include ActiveSupport::CoreExtensions::Hash::Conversions
12
+ include ActiveSupport::CoreExtensions::Hash::Diff
13
+ end
@@ -0,0 +1,148 @@
1
+ require 'date'
2
+ require 'xml_simple'
3
+
4
+ module ActiveSupport #:nodoc:
5
+ module CoreExtensions #:nodoc:
6
+ module Hash #:nodoc:
7
+ module Conversions
8
+ XML_TYPE_NAMES = {
9
+ ::Fixnum => "integer",
10
+ ::Float => "float",
11
+ ::Date => "date",
12
+ ::DateTime => "datetime",
13
+ ::Time => "datetime",
14
+ ::TrueClass => "boolean",
15
+ ::FalseClass => "boolean"
16
+ } unless defined? XML_TYPE_NAMES
17
+
18
+ XML_FORMATTING = {
19
+ "date" => Proc.new { |date| date.to_s(:db) },
20
+ "datetime" => Proc.new { |time| time.xmlschema },
21
+ "binary" => Proc.new { |binary| Base64.encode64(binary) }
22
+ } unless defined? XML_FORMATTING
23
+
24
+ def self.included(klass)
25
+ klass.extend(ClassMethods)
26
+ end
27
+
28
+ def to_xml(options = {})
29
+ options[:indent] ||= 2
30
+ options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
31
+ :root => "hash" })
32
+ options[:builder].instruct! unless options.delete(:skip_instruct)
33
+ dasherize = !options.has_key?(:dasherize) || options[:dasherize]
34
+ root = dasherize ? options[:root].to_s.dasherize : options[:root].to_s
35
+
36
+ options[:builder].__send__(root) do
37
+ each do |key, value|
38
+ case value
39
+ when ::Hash
40
+ value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
41
+ when ::Array
42
+ value.to_xml(options.merge({ :root => key, :children => key.to_s.singularize, :skip_instruct => true}))
43
+ when ::Method, ::Proc
44
+ # If the Method or Proc takes two arguments, then
45
+ # pass the suggested child element name. This is
46
+ # used if the Method or Proc will be operating over
47
+ # multiple records and needs to create an containing
48
+ # element that will contain the objects being
49
+ # serialized.
50
+ if 1 == value.arity
51
+ value.call(options.merge({ :root => key, :skip_instruct => true }))
52
+ else
53
+ value.call(options.merge({ :root => key, :skip_instruct => true }), key.to_s.singularize)
54
+ end
55
+ else
56
+ if value.respond_to?(:to_xml)
57
+ value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
58
+ else
59
+ type_name = XML_TYPE_NAMES[value.class]
60
+
61
+ key = dasherize ? key.to_s.dasherize : key.to_s
62
+
63
+ attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
64
+ if value.nil?
65
+ attributes[:nil] = true
66
+ end
67
+
68
+ options[:builder].tag!(key,
69
+ XML_FORMATTING[type_name] ? XML_FORMATTING[type_name].call(value) : value,
70
+ attributes
71
+ )
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ module ClassMethods
80
+ def create_from_xml(xml)
81
+ # TODO: Refactor this into something much cleaner that doesn't rely on XmlSimple
82
+ undasherize_keys(typecast_xml_value(XmlSimple.xml_in(xml,
83
+ 'forcearray' => false,
84
+ 'forcecontent' => true,
85
+ 'keeproot' => true,
86
+ 'contentkey' => '__content__')
87
+ ))
88
+ end
89
+
90
+ private
91
+ def typecast_xml_value(value)
92
+ case value.class.to_s
93
+ when "Hash"
94
+ if value.has_key?("__content__")
95
+ content = translate_xml_entities(value["__content__"])
96
+ case value["type"]
97
+ when "integer" then content.to_i
98
+ when "boolean" then content.strip == "true"
99
+ when "datetime" then ::Time.parse(content).utc
100
+ when "date" then ::Date.parse(content)
101
+ else content
102
+ end
103
+ else
104
+ value.empty? || value['nil'] == 'true' ? nil : value.inject({}) do |h,(k,v)|
105
+ h[k] = typecast_xml_value(v)
106
+ h
107
+ end
108
+ end
109
+ when "Array"
110
+ value.map! { |i| typecast_xml_value(i) }
111
+ case value.length
112
+ when 0 then nil
113
+ when 1 then value.first
114
+ else value
115
+ end
116
+ when "String"
117
+ value
118
+ else
119
+ raise "can't typecast #{value.inspect}"
120
+ end
121
+ end
122
+
123
+ def translate_xml_entities(value)
124
+ value.gsub(/&lt;/, "<").
125
+ gsub(/&gt;/, ">").
126
+ gsub(/&quot;/, '"').
127
+ gsub(/&apos;/, "'").
128
+ gsub(/&amp;/, "&")
129
+ end
130
+
131
+ def undasherize_keys(params)
132
+ case params.class.to_s
133
+ when "Hash"
134
+ params.inject({}) do |h,(k,v)|
135
+ h[k.to_s.tr("-", "_")] = undasherize_keys(v)
136
+ h
137
+ end
138
+ when "Array"
139
+ params.map { |v| undasherize_keys(v) }
140
+ else
141
+ params
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module Hash #:nodoc:
4
+ module Diff
5
+ def diff(h2)
6
+ self.dup.delete_if { |k, v| h2[k] == v }.merge(h2.dup.delete_if { |k, v| self.has_key?(k) })
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,88 @@
1
+ # this class has dubious semantics and we only have it so that
2
+ # people can write params[:key] instead of params['key']
3
+
4
+ class HashWithIndifferentAccess < Hash
5
+ def initialize(constructor = {})
6
+ if constructor.is_a?(Hash)
7
+ super()
8
+ update(constructor)
9
+ else
10
+ super(constructor)
11
+ end
12
+ end
13
+
14
+ def default(key = nil)
15
+ if key.is_a?(Symbol) && include?(key = key.to_s)
16
+ self[key]
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
23
+ alias_method :regular_update, :update unless method_defined?(:regular_update)
24
+
25
+ def []=(key, value)
26
+ regular_writer(convert_key(key), convert_value(value))
27
+ end
28
+
29
+ def update(other_hash)
30
+ other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
31
+ self
32
+ end
33
+
34
+ alias_method :merge!, :update
35
+
36
+ def key?(key)
37
+ super(convert_key(key))
38
+ end
39
+
40
+ alias_method :include?, :key?
41
+ alias_method :has_key?, :key?
42
+ alias_method :member?, :key?
43
+
44
+ def fetch(key, *extras)
45
+ super(convert_key(key), *extras)
46
+ end
47
+
48
+ def values_at(*indices)
49
+ indices.collect {|key| self[convert_key(key)]}
50
+ end
51
+
52
+ def dup
53
+ HashWithIndifferentAccess.new(self)
54
+ end
55
+
56
+ def merge(hash)
57
+ self.dup.update(hash)
58
+ end
59
+
60
+ def delete(key)
61
+ super(convert_key(key))
62
+ end
63
+
64
+ def stringify_keys!; self end
65
+ def symbolize_keys!; self end
66
+
67
+ protected
68
+ def convert_key(key)
69
+ key.kind_of?(Symbol) ? key.to_s : key
70
+ end
71
+ def convert_value(value)
72
+ value.is_a?(Hash) ? value.with_indifferent_access : value
73
+ end
74
+ end
75
+
76
+ module ActiveSupport #:nodoc:
77
+ module CoreExtensions #:nodoc:
78
+ module Hash #:nodoc:
79
+ module IndifferentAccess #:nodoc:
80
+ def with_indifferent_access
81
+ hash = HashWithIndifferentAccess.new(self)
82
+ hash.default = self.default
83
+ hash
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,53 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module Hash #:nodoc:
4
+ module Keys
5
+ # Return a new hash with all keys converted to strings.
6
+ def stringify_keys
7
+ inject({}) do |options, (key, value)|
8
+ options[key.to_s] = value
9
+ options
10
+ end
11
+ end
12
+
13
+ # Destructively convert all keys to strings.
14
+ def stringify_keys!
15
+ keys.each do |key|
16
+ unless key.class.to_s == "String" # weird hack to make the tests run when string_ext_test.rb is also running
17
+ self[key.to_s] = self[key]
18
+ delete(key)
19
+ end
20
+ end
21
+ self
22
+ end
23
+
24
+ # Return a new hash with all keys converted to symbols.
25
+ def symbolize_keys
26
+ inject({}) do |options, (key, value)|
27
+ options[key.to_sym] = value
28
+ options
29
+ end
30
+ end
31
+
32
+ # Destructively convert all keys to symbols.
33
+ def symbolize_keys!
34
+ keys.each do |key|
35
+ unless key.is_a?(Symbol)
36
+ self[key.to_sym] = self[key]
37
+ delete(key)
38
+ end
39
+ end
40
+ self
41
+ end
42
+
43
+ alias_method :to_options, :symbolize_keys
44
+ alias_method :to_options!, :symbolize_keys!
45
+
46
+ def assert_valid_keys(*valid_keys)
47
+ unknown_keys = keys - [valid_keys].flatten
48
+ raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end