glue 0.19.0 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +41 -0
- data/README +10 -2
- data/doc/RELEASES +42 -1
- data/lib/glue.rb +1 -1
- data/lib/glue/annotation.rb +33 -0
- data/lib/glue/attribute.rb +2 -14
- data/lib/glue/configuration.rb +126 -0
- data/lib/glue/helper.rb +31 -0
- data/lib/glue/object.rb +15 -12
- data/lib/glue/settings.rb +5 -0
- data/lib/glue/uri.rb +192 -0
- data/test/glue/tc_configuration.rb +125 -0
- data/test/glue/tc_uri.rb +97 -0
- metadata +11 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,44 @@
|
|
1
|
+
12-07-2005 George Moschovitis <gm@navel.gr>
|
2
|
+
|
3
|
+
* lib/glue/helper.rb: moved here from nitro.
|
4
|
+
|
5
|
+
11-07-2005 George Moschovitis <gm@navel.gr>
|
6
|
+
|
7
|
+
* doc/RELEASES: updated.
|
8
|
+
|
9
|
+
04-07-2005 George Moschovitis <gm@navel.gr>
|
10
|
+
|
11
|
+
* test/glue/tc_configuration.rb: changes to work under rake.
|
12
|
+
|
13
|
+
25-06-2005 George Moschovitis <gm@navel.gr>
|
14
|
+
|
15
|
+
* lib/glue/object.rb (#subclasses_of): small update in the
|
16
|
+
code.
|
17
|
+
|
18
|
+
24-06-2005 George Moschovitis <gm@navel.gr>
|
19
|
+
|
20
|
+
* lib/glue/configuration.rb (#parse): handle namespaces,
|
21
|
+
fixed check for default param.
|
22
|
+
|
23
|
+
23-06-2005 George Moschovitis <gm@navel.gr>
|
24
|
+
|
25
|
+
* test/glue/tc_configuration.rb: introduced.
|
26
|
+
|
27
|
+
* lib/glue/configuration.rb: introduced,
|
28
|
+
kinda works :),
|
29
|
+
(Configuration#settings): per owner filter,
|
30
|
+
use a hash to store settings.
|
31
|
+
setting the owner updates the configuration metadata,
|
32
|
+
reverse setting works too :-)
|
33
|
+
(#parse, #load, #setup): implemented.
|
34
|
+
the parsing support just ROCKS!
|
35
|
+
(Settings): alias for configuration.
|
36
|
+
|
37
|
+
* README: updated.
|
38
|
+
|
39
|
+
* lib/glue/annotation.rb: introduced and adapted [ahellesoy],
|
40
|
+
override Module.
|
41
|
+
|
1
42
|
17-06-2005 George Moschovitis <gm@navel.gr>
|
2
43
|
|
3
44
|
* lib/glue/autoreload.rb: added.
|
data/README
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
= Glue 0.
|
1
|
+
= Glue 0.19.0 README
|
2
2
|
|
3
3
|
Useful utilites and methods.
|
4
4
|
|
5
|
+
|
6
|
+
== Purpose
|
7
|
+
|
8
|
+
Useful libraries are stored here. An attempt is made to
|
9
|
+
graduate mature libraries to the more general Facets
|
10
|
+
ruby project.
|
11
|
+
|
12
|
+
|
5
13
|
== Licence
|
6
14
|
|
7
|
-
Copyright (c) 2004-2005, George '
|
15
|
+
Copyright (c) 2004-2005, George 'gmosx' Moschovitis.
|
8
16
|
Copyright (c) 2004-2005, Navel Ltd (http://www.navel.gr)
|
9
17
|
|
10
18
|
Glue (http://www.rubyforge.org/projects/nitro) is copyrighted free
|
data/doc/RELEASES
CHANGED
@@ -1,4 +1,45 @@
|
|
1
|
-
== Version 0.
|
1
|
+
== Version 0.20.0
|
2
|
+
|
3
|
+
* Brand new, self-documenting configuration system. There is a new
|
4
|
+
keyword for defining configuration settings:
|
5
|
+
|
6
|
+
Here is an example:
|
7
|
+
|
8
|
+
class Render
|
9
|
+
setting :template_extension, :default => 'xhtml', :doc => 'The default template extension'
|
10
|
+
end
|
11
|
+
|
12
|
+
class Session
|
13
|
+
setting :store, :default => 'memory', :doc => 'The session store'
|
14
|
+
end
|
15
|
+
|
16
|
+
You can configure the Application using ruby code or yaml files:
|
17
|
+
|
18
|
+
Render.template_extension = 'xhtml'
|
19
|
+
Session.store = 'drb'
|
20
|
+
|
21
|
+
or
|
22
|
+
|
23
|
+
Render:
|
24
|
+
template_extension: xhtml
|
25
|
+
Session:
|
26
|
+
store: drb
|
27
|
+
|
28
|
+
You can access all defined settings:
|
29
|
+
|
30
|
+
Configuration.settings.each { |s| ... }
|
31
|
+
|
32
|
+
You can view the settings of the application along with documentation
|
33
|
+
on the following url:
|
34
|
+
|
35
|
+
www.myapp.com/settings
|
36
|
+
|
37
|
+
* Flexob, many improvements.
|
38
|
+
|
39
|
+
* Many bug fixes.
|
40
|
+
|
41
|
+
|
42
|
+
== Version 0.19.0 was released on 31/05/2005.
|
2
43
|
|
3
44
|
* Improved Logger.
|
4
45
|
|
data/lib/glue.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Based on an original idea by Aslak Hellesoy.
|
2
|
+
|
3
|
+
require 'glue/hash'
|
4
|
+
|
5
|
+
class Module
|
6
|
+
def ann(anns)
|
7
|
+
@@anns ||= SafeHash.new
|
8
|
+
def self.method_missing(sym, *args) #:nodoc:
|
9
|
+
@@anns[sym]
|
10
|
+
end
|
11
|
+
t = Thread.current
|
12
|
+
t[:attr_anns] ||= {}
|
13
|
+
t[:attr_anns].merge!(anns)
|
14
|
+
end
|
15
|
+
|
16
|
+
alias old_attr_reader attr_reader #:nodoc:
|
17
|
+
def attr_reader(*syms) #:nodoc:
|
18
|
+
t = Thread.current
|
19
|
+
syms.each do |sym|
|
20
|
+
@@anns[sym] = t[:attr_anns]
|
21
|
+
end
|
22
|
+
|
23
|
+
t[:attr_anns] = nil
|
24
|
+
old_attr_reader(*syms)
|
25
|
+
end
|
26
|
+
|
27
|
+
def attr_accessor(*syms) #:nodoc:
|
28
|
+
attr_reader(*syms)
|
29
|
+
attr_writer(*syms)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/attribute.rb
CHANGED
@@ -33,13 +33,7 @@ class Module # :nodoc:
|
|
33
33
|
def self.#{sym.id2name}
|
34
34
|
@@#{sym}
|
35
35
|
end
|
36
|
-
|
37
|
-
# gmosx: NOT NEEDED!
|
38
|
-
|
39
|
-
def #{sym.id2name}
|
40
|
-
@@#{sym}
|
41
|
-
end
|
42
|
-
=end
|
36
|
+
|
43
37
|
end_eval
|
44
38
|
end
|
45
39
|
end
|
@@ -65,13 +59,7 @@ class Module # :nodoc:
|
|
65
59
|
def self.set_#{sym.id2name}(obj)
|
66
60
|
@@#{sym.id2name} = obj
|
67
61
|
end
|
68
|
-
|
69
|
-
# gmosx: NOT NEEDED!
|
70
|
-
|
71
|
-
def #{sym.id2name}=(obj)
|
72
|
-
@@#{sym} = obj
|
73
|
-
end
|
74
|
-
=end
|
62
|
+
|
75
63
|
end_eval
|
76
64
|
end
|
77
65
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
require 'facet/object/constant'
|
4
|
+
|
5
|
+
require 'glue/attribute'
|
6
|
+
require 'glue/hash'
|
7
|
+
require 'glue/flexob'
|
8
|
+
|
9
|
+
# A Configuration holds a group of Settings organized by
|
10
|
+
# Owners.
|
11
|
+
#--
|
12
|
+
# TODO: implement with annotations.
|
13
|
+
#++
|
14
|
+
|
15
|
+
class Configuration
|
16
|
+
|
17
|
+
# A hash of setting owners. Use double @'s to allow for
|
18
|
+
# the Settings alias.
|
19
|
+
#--
|
20
|
+
# TODO: find a better name.
|
21
|
+
#++
|
22
|
+
|
23
|
+
@@owners = Glue::SafeHash.new
|
24
|
+
|
25
|
+
# A datastructure to store Settings metadata.
|
26
|
+
|
27
|
+
class Setting
|
28
|
+
attr_accessor :owner, :name, :type, :value, :options
|
29
|
+
|
30
|
+
def initialize(owner, name, options)
|
31
|
+
raise ArgumentError.new('A default value is required') unless options.key?(:default)
|
32
|
+
@owner, @name = owner, name
|
33
|
+
@options = options
|
34
|
+
@value = options[:default]
|
35
|
+
@type = options[:type] = options[:type] || @value.class
|
36
|
+
end
|
37
|
+
|
38
|
+
def value=(value)
|
39
|
+
@value = value
|
40
|
+
constant(@owner).module_eval %{
|
41
|
+
@@#{@name} = #{value.inspect}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
@value.to_s
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class << self
|
51
|
+
|
52
|
+
def setup(options)
|
53
|
+
options.each do |owner, ss|
|
54
|
+
owner = constant(owner)
|
55
|
+
ss.each do |name, s|
|
56
|
+
@@owners[owner][name.to_sym].value = s
|
57
|
+
owner.module_eval %{
|
58
|
+
@@#{name} = #{s.inspect}
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse(options)
|
65
|
+
temp = YAML::load(options)
|
66
|
+
options = {}
|
67
|
+
temp.each { |k, v| options[constant(k.gsub(/\./, '::').to_sym)] = v }
|
68
|
+
setup(options)
|
69
|
+
end
|
70
|
+
|
71
|
+
def load(filename)
|
72
|
+
parse(File.read(filename))
|
73
|
+
end
|
74
|
+
|
75
|
+
def add_setting(owner, name, options)
|
76
|
+
s = @@owners[owner] || {}
|
77
|
+
s[name] = Setting.new(owner, name, options)
|
78
|
+
@@owners[owner] = s
|
79
|
+
end
|
80
|
+
|
81
|
+
def settings(owner = nil)
|
82
|
+
if owner
|
83
|
+
@@owners[owner]
|
84
|
+
else
|
85
|
+
@@owners.values.inject([]) { |memo, obj| memo.concat(obj.values) }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
alias_method :all, :settings
|
89
|
+
alias_method :[], :settings
|
90
|
+
|
91
|
+
def method_missing(sym)
|
92
|
+
if sym.to_s =~ /[A-Z]/ # facet's capitalized? is buggy at the moment.
|
93
|
+
Flexob.new(self[constant(sym)])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
# Alias for the Configuration class (shorter).
|
101
|
+
|
102
|
+
class Settings < Configuration
|
103
|
+
end
|
104
|
+
|
105
|
+
class Module
|
106
|
+
|
107
|
+
# Defines a configuration setting.
|
108
|
+
#--
|
109
|
+
# TODO: implement with annotations.
|
110
|
+
#++
|
111
|
+
|
112
|
+
def setting(sym, options = {})
|
113
|
+
Configuration.add_setting(self, sym, options)
|
114
|
+
module_eval %{
|
115
|
+
mattr_accessor sym, options[:default]
|
116
|
+
|
117
|
+
def self.#{sym.id2name}=(obj)
|
118
|
+
@@#{sym.id2name} = obj
|
119
|
+
Configuration[#{self}][:#{sym}].value = obj
|
120
|
+
end
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'facet/module/by_name'
|
2
|
+
|
3
|
+
require 'glue/object'
|
4
|
+
require 'glue/attribute'
|
5
|
+
|
6
|
+
module Glue
|
7
|
+
|
8
|
+
# Helpers are standard Ruby modules that contain utility
|
9
|
+
# methods. By using the special 'helper'
|
10
|
+
# macro provided by HelperSupport, the utility methods are
|
11
|
+
# included as private methods.
|
12
|
+
|
13
|
+
module Helpers
|
14
|
+
|
15
|
+
def self.append_features(base)
|
16
|
+
base.module_eval do
|
17
|
+
def self.helper(*modules)
|
18
|
+
for mod in modules
|
19
|
+
symbols = mod.instance_methods.collect { |m| m.to_sym }
|
20
|
+
self.send(:include, mod)
|
21
|
+
self.send(:private, *symbols)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/object.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
|
5
|
-
# Code from RubyOnRails (http://www.rubyonrails.com)
|
1
|
+
# Original code from RubyOnRails (http://www.rubyonrails.com)
|
2
|
+
#--
|
3
|
+
# TODO: suggest inclusion in Facets.
|
4
|
+
#++
|
6
5
|
|
7
6
|
class Object #:nodoc:
|
8
7
|
def remove_subclasses_of(superclass)
|
9
|
-
subclasses_of(superclass).each
|
8
|
+
subclasses_of(superclass).each do |subclass|
|
9
|
+
Object.send(:remove_const, subclass) rescue nil
|
10
|
+
end
|
10
11
|
end
|
11
12
|
|
12
13
|
def subclasses_of(superclass)
|
13
14
|
subclasses = []
|
14
|
-
ObjectSpace.each_object(Class) do |
|
15
|
-
|
16
|
-
|
15
|
+
ObjectSpace.each_object(Class) do |c|
|
16
|
+
if c.ancestors.include?(superclass) and superclass != c
|
17
|
+
subclasses << c
|
18
|
+
end
|
17
19
|
end
|
18
|
-
subclasses
|
20
|
+
return subclasses
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
# Code from RubyOnRails (http://www.rubyonrails.com)
|
23
|
-
|
24
24
|
class Class #:nodoc:
|
25
25
|
def remove_subclasses
|
26
26
|
Object.remove_subclasses_of(self)
|
@@ -29,4 +29,7 @@ class Class #:nodoc:
|
|
29
29
|
def subclasses
|
30
30
|
Object.subclasses_of(self)
|
31
31
|
end
|
32
|
+
alias_method :descendants, :subclasses
|
32
33
|
end
|
34
|
+
|
35
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/uri.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
require 'glue/string'
|
5
|
+
|
6
|
+
module Glue
|
7
|
+
|
8
|
+
# URI utilities collection.
|
9
|
+
#
|
10
|
+
# === Design
|
11
|
+
#
|
12
|
+
# Implement as a module to avoid class polution. You can still
|
13
|
+
# use Ruby's advanced features to include the module in your
|
14
|
+
# class. Passing the object to act upon allows to check for nil,
|
15
|
+
# which isn't possible if you use self.
|
16
|
+
#
|
17
|
+
# The uris passed as parameters are typically strings.
|
18
|
+
#--
|
19
|
+
# gmosx, TODO: deprecate this.
|
20
|
+
#++
|
21
|
+
|
22
|
+
module UriUtils
|
23
|
+
|
24
|
+
# Decode the uri components.
|
25
|
+
|
26
|
+
def self.decode(uri)
|
27
|
+
# gmosx: hmm is this needed?
|
28
|
+
# guard against invalid filenames for example pictures with
|
29
|
+
# spaces uploaded by users
|
30
|
+
escaped_uri = uri.gsub(/ /, "+")
|
31
|
+
|
32
|
+
if md = URI::REGEXP::REL_URI.match(escaped_uri)
|
33
|
+
|
34
|
+
path = "#{md[5]}#{md[6]}"
|
35
|
+
type = File.extname(path)
|
36
|
+
query_string = md[7]
|
37
|
+
|
38
|
+
# real_path = "#{$root_dir}/#{path}"
|
39
|
+
|
40
|
+
parameters = UriUtils.query_string_to_hash(query_string)
|
41
|
+
path.gsub!(/\+/, " ")
|
42
|
+
|
43
|
+
return [path, type, parameters, query_string]
|
44
|
+
|
45
|
+
end # match
|
46
|
+
|
47
|
+
# this is usefull for uncovering bugs!
|
48
|
+
raise ArgumentError.new("the parameter '#{uri}' is not a valid uri")
|
49
|
+
end
|
50
|
+
|
51
|
+
# Extend the basic query string parser provided by the cgi module.
|
52
|
+
# converts single valued params (the most common case) to
|
53
|
+
# objects instead of arrays
|
54
|
+
#
|
55
|
+
# Input:
|
56
|
+
# the query string
|
57
|
+
#
|
58
|
+
# Output:
|
59
|
+
# hash of parameters, contains arrays for multivalued parameters
|
60
|
+
# (multiselect, checkboxes , etc)
|
61
|
+
# If no query string is provided (nil or "") returns an empty hash.
|
62
|
+
|
63
|
+
def self.query_string_to_hash(query_string)
|
64
|
+
return {} unless query_string
|
65
|
+
|
66
|
+
query_parameters = CGI::parse(query_string)
|
67
|
+
|
68
|
+
query_parameters.each { |key, val|
|
69
|
+
# replace the array with an object
|
70
|
+
query_parameters[key] = val[0] if 1 == val.length
|
71
|
+
}
|
72
|
+
|
73
|
+
# set default value to nil! cgi sets this to []
|
74
|
+
query_parameters.default = nil
|
75
|
+
|
76
|
+
return query_parameters
|
77
|
+
end
|
78
|
+
|
79
|
+
# Given a hash with parameter/value pairs construct a
|
80
|
+
# standard query string. This method only encodes simple
|
81
|
+
# types (Numeric, String) to avoid query string polution
|
82
|
+
# with marshal, etc.
|
83
|
+
#
|
84
|
+
# gmosx, FIXME: only numeric and strings are passed to
|
85
|
+
# the latest code, so update old code and optimize this!
|
86
|
+
#
|
87
|
+
# Input:
|
88
|
+
# the parameter hash
|
89
|
+
#
|
90
|
+
# Output:
|
91
|
+
# the query string
|
92
|
+
|
93
|
+
def self.hash_to_query_string(parameters)
|
94
|
+
return nil unless parameters
|
95
|
+
pairs = []
|
96
|
+
parameters.each { |param, value|
|
97
|
+
# only encode simple classes !
|
98
|
+
|
99
|
+
if value.is_a?(Numeric) or value.is_a?(String)
|
100
|
+
pairs << "#{param}=#{value}"
|
101
|
+
end
|
102
|
+
}
|
103
|
+
return pairs.join(";")
|
104
|
+
end
|
105
|
+
|
106
|
+
# This method returns the query string of a uri
|
107
|
+
#
|
108
|
+
# Input:
|
109
|
+
# the uri
|
110
|
+
#
|
111
|
+
# Output:
|
112
|
+
# the query string.
|
113
|
+
# returns nil if no query string
|
114
|
+
|
115
|
+
def self.get_query_string(uri)
|
116
|
+
return nil unless uri
|
117
|
+
# gmosx: INVESTIGATE ruby's URI seems to differently handle
|
118
|
+
# abs and rel uris.
|
119
|
+
if md = URI::REGEXP::ABS_URI.match(uri)
|
120
|
+
return md[8]
|
121
|
+
elsif md = URI::REGEXP::REL_URI.match(uri)
|
122
|
+
return md[7]
|
123
|
+
end
|
124
|
+
return nil
|
125
|
+
end
|
126
|
+
|
127
|
+
# Removes the query string from a uri
|
128
|
+
#
|
129
|
+
# Input:
|
130
|
+
# the uri
|
131
|
+
#
|
132
|
+
# Output:
|
133
|
+
# the chomped uri.
|
134
|
+
|
135
|
+
def self.chomp_query_string(uri)
|
136
|
+
return nil unless uri
|
137
|
+
query_string = self.get_query_string(uri)
|
138
|
+
return uri.dup.chomp("?#{query_string}")
|
139
|
+
end
|
140
|
+
|
141
|
+
# Get a uri and a hash of parameters. Inject the hash values
|
142
|
+
# as parameters in the query sting path. Returns the full
|
143
|
+
# uri.
|
144
|
+
#
|
145
|
+
# Input:
|
146
|
+
# the uri to filter (String)
|
147
|
+
# hash of parameters to update
|
148
|
+
#
|
149
|
+
# Output:
|
150
|
+
# the full updated query string
|
151
|
+
#
|
152
|
+
# === TODO:
|
153
|
+
# optimize this a litle bit.
|
154
|
+
|
155
|
+
def self.update_query_string(uri, parameters)
|
156
|
+
query_string = self.get_query_string(uri)
|
157
|
+
rest = uri.dup.gsub(/\?#{query_string}/, "")
|
158
|
+
|
159
|
+
hash = self.query_string_to_hash(query_string)
|
160
|
+
hash.update(parameters)
|
161
|
+
query_string = self.hash_to_query_string(hash)
|
162
|
+
|
163
|
+
if Glue::StringUtils.valid?(query_string)
|
164
|
+
return "#{rest}?#{query_string}"
|
165
|
+
else
|
166
|
+
return rest
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# TODO: find a better name.
|
171
|
+
# Gets the request uri, injects extra parameters in the query string
|
172
|
+
# and returns a new uri. The request object is not modified.
|
173
|
+
# There is always a qs string so an extra test is skipped.
|
174
|
+
|
175
|
+
def self.update_request_uri(request, parameters)
|
176
|
+
hash = request.parameters.dup()
|
177
|
+
hash.update(parameters)
|
178
|
+
|
179
|
+
# use this in hash_to_querystring.
|
180
|
+
query_string = hash.collect { |k, v|
|
181
|
+
"#{k}=#{v}"
|
182
|
+
}.join(";")
|
183
|
+
|
184
|
+
return "#{request.translated_uri}?#{query_string}"
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
# * George Moschovitis <gm@navel.gr>
|
192
|
+
|
@@ -0,0 +1,125 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'glue/configuration'
|
5
|
+
|
6
|
+
# Hack: To make compatible with rake test.
|
7
|
+
|
8
|
+
class Dummy
|
9
|
+
setting :root_dir, :default => '/home/gmosx', :doc => 'The root directory for the app'
|
10
|
+
setting :conn_count, :default => 5, :type => Fixnum
|
11
|
+
end
|
12
|
+
|
13
|
+
class Another
|
14
|
+
setting :max_age, :default => 4, :doc => 'Maximum allowed age'
|
15
|
+
end
|
16
|
+
|
17
|
+
class Configuration
|
18
|
+
def self.clear_all_settings
|
19
|
+
@@owners = Hash.new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class TC_Configuration < Test::Unit::TestCase # :nodoc: all
|
24
|
+
|
25
|
+
class Internal
|
26
|
+
setting :radius, :default => 4
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup
|
30
|
+
# gmosx: A hack to make compatible with rake. All code in this
|
31
|
+
# method is not needed if you only run this test (or in your
|
32
|
+
# real aplications of course).
|
33
|
+
|
34
|
+
Configuration.clear_all_settings
|
35
|
+
|
36
|
+
Dummy.class_eval do
|
37
|
+
setting :root_dir, :default => '/home/gmosx', :doc => 'The root directory for the app'
|
38
|
+
setting :conn_count, :default => 5, :type => Fixnum
|
39
|
+
end
|
40
|
+
|
41
|
+
Another.class_eval do
|
42
|
+
setting :max_age, :default => 4, :doc => 'Maximum allowed age'
|
43
|
+
end
|
44
|
+
|
45
|
+
Internal.class_eval do
|
46
|
+
setting :radius, :default => 4
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_all
|
51
|
+
assert_equal 4, Configuration.settings.size
|
52
|
+
assert_equal 4, Configuration.all.size
|
53
|
+
|
54
|
+
assert_equal 2, Configuration.settings(Dummy).size
|
55
|
+
assert_equal 1, Configuration.settings(Another).size
|
56
|
+
|
57
|
+
assert_equal Fixnum, Configuration.settings(Dummy)[:conn_count].type
|
58
|
+
assert_equal String, Configuration[Dummy][:root_dir].type
|
59
|
+
|
60
|
+
assert_equal '/home/gmosx', Dummy.root_dir
|
61
|
+
assert_equal 4, Another.max_age
|
62
|
+
|
63
|
+
Dummy.root_dir = '/changed/dir'
|
64
|
+
assert_equal '/changed/dir', Dummy.root_dir
|
65
|
+
assert_equal '/changed/dir', Configuration[Dummy][:root_dir].value
|
66
|
+
|
67
|
+
Another.max_age = 99
|
68
|
+
assert_equal 99, Configuration[Another][:max_age].value
|
69
|
+
|
70
|
+
# test reverse setting.
|
71
|
+
|
72
|
+
Configuration[Another][:max_age].value = 69
|
73
|
+
assert_equal 69, Configuration[Another][:max_age].value
|
74
|
+
assert_equal 69, Another.max_age
|
75
|
+
|
76
|
+
# setup
|
77
|
+
|
78
|
+
Configuration.setup(
|
79
|
+
Dummy => {
|
80
|
+
:root_dir => '/gmosx/2',
|
81
|
+
:conn_count => 12
|
82
|
+
},
|
83
|
+
Another => {
|
84
|
+
:max_age => 2
|
85
|
+
},
|
86
|
+
TC_Configuration::Internal => {
|
87
|
+
:radius => 99
|
88
|
+
}
|
89
|
+
)
|
90
|
+
|
91
|
+
assert_equal '/gmosx/2', Dummy.root_dir
|
92
|
+
assert_equal '/gmosx/2', Configuration[Dummy][:root_dir].value
|
93
|
+
assert_equal 2, Another.max_age
|
94
|
+
|
95
|
+
Configuration.parse <<-end_val
|
96
|
+
Another:
|
97
|
+
max_age: 5
|
98
|
+
TC_Configuration.Internal:
|
99
|
+
radius: 99
|
100
|
+
Dummy:
|
101
|
+
root_dir: /gmosx/99
|
102
|
+
conn_count: 33
|
103
|
+
end_val
|
104
|
+
|
105
|
+
assert_equal '/gmosx/99', Dummy.root_dir
|
106
|
+
assert_equal '/gmosx/99', Configuration[Dummy][:root_dir].value
|
107
|
+
assert_equal 5, Another.max_age
|
108
|
+
|
109
|
+
# cooler ;-)
|
110
|
+
|
111
|
+
assert_equal String, Configuration.Dummy[:root_dir].type
|
112
|
+
assert_equal String, Configuration.Dummy.root_dir.type
|
113
|
+
|
114
|
+
# alias
|
115
|
+
|
116
|
+
assert_equal String, Settings.Dummy.root_dir.type
|
117
|
+
assert_equal 5, Settings.Another.max_age.value
|
118
|
+
|
119
|
+
# Handle namespace
|
120
|
+
|
121
|
+
assert_equal 99, Internal.radius
|
122
|
+
assert_equal 99, TC_Configuration::Internal.radius
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
data/test/glue/tc_uri.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'glue/uri'
|
3
|
+
|
4
|
+
class Dummy # :nodoc: all
|
5
|
+
attr_accessor :test1, :test2
|
6
|
+
end
|
7
|
+
|
8
|
+
class TC_Uri < Test::Unit::TestCase # :nodoc: all
|
9
|
+
include Glue
|
10
|
+
|
11
|
+
def test_query_string_to_hash
|
12
|
+
# bad query string
|
13
|
+
|
14
|
+
assert_equal(0, UriUtils.query_string_to_hash("").length)
|
15
|
+
assert_equal(0, UriUtils.query_string_to_hash(nil).length)
|
16
|
+
|
17
|
+
# single valued
|
18
|
+
|
19
|
+
parameters = UriUtils.query_string_to_hash("koko=2&lala=3")
|
20
|
+
assert_equal("2", parameters["koko"])
|
21
|
+
assert_equal("3", parameters["lala"])
|
22
|
+
|
23
|
+
parameters = UriUtils.query_string_to_hash("koko=2;lala=3")
|
24
|
+
assert_equal("2", parameters["koko"])
|
25
|
+
assert_equal("3", parameters["lala"])
|
26
|
+
|
27
|
+
# multivalued
|
28
|
+
|
29
|
+
parameters = UriUtils.query_string_to_hash("koko=2;lala=3&koko=5")
|
30
|
+
assert_equal(2, parameters["koko"].length)
|
31
|
+
assert_equal("2", parameters["koko"][0])
|
32
|
+
assert_equal("3", parameters["lala"])
|
33
|
+
assert_equal("5", parameters["koko"][1])
|
34
|
+
|
35
|
+
# non existing value
|
36
|
+
assert_equal(nil, parameters["non-existing-value"])
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_hash_to_query_string
|
40
|
+
hash = { "koko" => 1, "lala" => 2}
|
41
|
+
qs = "koko=1;lala=2"
|
42
|
+
assert_equal(qs, UriUtils.hash_to_query_string(hash))
|
43
|
+
|
44
|
+
assert_equal(nil, UriUtils.hash_to_query_string(nil))
|
45
|
+
|
46
|
+
# bug: dont encode complex objects
|
47
|
+
hash = { "a" => 2, "b" => 3, "c" => Dummy.new }
|
48
|
+
qs = "a=2;b=3"
|
49
|
+
assert_equal(qs, UriUtils.hash_to_query_string(hash))
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_get_query_string
|
53
|
+
uri = "people/gmosx.sx?koko=1;lala=2"
|
54
|
+
assert_equal("koko=1;lala=2", UriUtils.get_query_string(uri))
|
55
|
+
|
56
|
+
uri = "http://www.navel.gr/people/gmosx.sx?koko=1&lala=2"
|
57
|
+
assert_equal("koko=1&lala=2", UriUtils.get_query_string(uri))
|
58
|
+
|
59
|
+
uri = "http://www.navel.gr:8080/people/gmosx.sx?koko=1;lala=2"
|
60
|
+
assert_equal("koko=1;lala=2", UriUtils.get_query_string(uri))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_chomp_query_string
|
64
|
+
uri = "people/gmosx.sx"
|
65
|
+
assert_equal("people/gmosx.sx", UriUtils.chomp_query_string(uri))
|
66
|
+
|
67
|
+
uri = "people/gmosx.sx?koko=1;lala=2"
|
68
|
+
assert_equal("people/gmosx.sx", UriUtils.chomp_query_string(uri))
|
69
|
+
|
70
|
+
uri = "http://www.navel.gr/people/gmosx.sx?koko=1&lala=2"
|
71
|
+
assert_equal("http://www.navel.gr/people/gmosx.sx", UriUtils.chomp_query_string(uri))
|
72
|
+
|
73
|
+
uri = "http://www.navel.gr:8080/people/gmosx.sx?koko=1;lala=2"
|
74
|
+
assert_equal("http://www.navel.gr:8080/people/gmosx.sx", UriUtils.chomp_query_string(uri))
|
75
|
+
|
76
|
+
assert_equal(nil, UriUtils.chomp_query_string(nil))
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_update_query_string
|
80
|
+
uri = "ko/index.sx?koko=1"
|
81
|
+
hash = {"lala" => 2, "kaka" => 3}
|
82
|
+
assert_equal("ko/index.sx?koko=1;lala=2;kaka=3", UriUtils.update_query_string(uri, hash))
|
83
|
+
|
84
|
+
uri = "http://www.navel.gr:8080/ko/index.sx?koko=1"
|
85
|
+
hash = {"lala" => 2, "kaka" => 3}
|
86
|
+
assert_equal("http://www.navel.gr:8080/ko/index.sx?koko=1;lala=2;kaka=3", UriUtils.update_query_string(uri, hash))
|
87
|
+
|
88
|
+
uri = "http://www.navel.gr"
|
89
|
+
hash = {"lala" => 2, "kaka" => 3}
|
90
|
+
assert_equal("http://www.navel.gr?lala=2;kaka=3", UriUtils.update_query_string(uri, hash))
|
91
|
+
|
92
|
+
# bug: no ? when passed an empty hash
|
93
|
+
uri = "http://www.navel.gr"
|
94
|
+
assert_equal("http://www.navel.gr", UriUtils.update_query_string(uri, {}))
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: glue
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-
|
6
|
+
version: 0.20.0
|
7
|
+
date: 2005-07-12
|
8
8
|
summary: Glue utilities
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -27,10 +27,10 @@ platform: ruby
|
|
27
27
|
authors:
|
28
28
|
- George Moschovitis
|
29
29
|
files:
|
30
|
+
- README
|
30
31
|
- CHANGELOG
|
31
32
|
- Rakefile
|
32
33
|
- INSTALL
|
33
|
-
- README
|
34
34
|
- install.rb
|
35
35
|
- doc/RELEASES
|
36
36
|
- doc/LICENSE
|
@@ -47,19 +47,25 @@ files:
|
|
47
47
|
- lib/glue/sanitize.rb
|
48
48
|
- lib/glue/number.rb
|
49
49
|
- lib/glue/autoreload.rb
|
50
|
+
- lib/glue/uri.rb
|
50
51
|
- lib/glue/aspects.rb
|
51
52
|
- lib/glue/misc.rb
|
52
53
|
- lib/glue/time.rb
|
54
|
+
- lib/glue/annotation.rb
|
53
55
|
- lib/glue/attribute.rb
|
54
56
|
- lib/glue/string.rb
|
55
57
|
- lib/glue/object.rb
|
56
58
|
- lib/glue/mixins.rb
|
57
59
|
- lib/glue/pool.rb
|
60
|
+
- lib/glue/configuration.rb
|
61
|
+
- lib/glue/helper.rb
|
62
|
+
- lib/glue/settings.rb
|
58
63
|
- lib/html/document.rb
|
59
64
|
- lib/html/node.rb
|
60
65
|
- lib/html/version.rb
|
61
66
|
- lib/html/tokenizer.rb
|
62
67
|
- test/glue
|
68
|
+
- test/glue/tc_configuration.rb
|
63
69
|
- test/glue/tc_strings.rb
|
64
70
|
- test/glue/tc_validation.rb
|
65
71
|
- test/glue/tc_numbers.rb
|
@@ -71,6 +77,7 @@ files:
|
|
71
77
|
- test/glue/tc_hash.rb
|
72
78
|
- test/glue/tc_attribute.rb
|
73
79
|
- test/glue/tc_property.rb
|
80
|
+
- test/glue/tc_uri.rb
|
74
81
|
test_files: []
|
75
82
|
rdoc_options:
|
76
83
|
- "--main"
|
@@ -80,10 +87,10 @@ rdoc_options:
|
|
80
87
|
- "--all"
|
81
88
|
- "--inline-source"
|
82
89
|
extra_rdoc_files:
|
90
|
+
- README
|
83
91
|
- CHANGELOG
|
84
92
|
- Rakefile
|
85
93
|
- INSTALL
|
86
|
-
- README
|
87
94
|
executables: []
|
88
95
|
extensions: []
|
89
96
|
requirements: []
|