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 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.17.0 README
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 'tml' Moschovitis.
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
@@ -1,4 +1,45 @@
1
- == Version 0.19.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
 
@@ -61,7 +61,7 @@ module Glue
61
61
 
62
62
  # The version.
63
63
 
64
- Version = '0.19.0'
64
+ Version = '0.20.0'
65
65
 
66
66
  # Library path.
67
67
 
@@ -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>
@@ -33,13 +33,7 @@ class Module # :nodoc:
33
33
  def self.#{sym.id2name}
34
34
  @@#{sym}
35
35
  end
36
- =begin
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
- =begin
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>
@@ -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>
@@ -1,26 +1,26 @@
1
- # * George Moschovitis <gm@navel.gr>
2
- # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: object.rb 1 2005-04-11 11:04:30Z gmosx $
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 { |subclass| Object.send(:remove_const, subclass) rescue nil }
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 |k|
15
- next if !k.ancestors.include?(superclass) || superclass == k || k.to_s.include?("::") || subclasses.include?(k.to_s)
16
- subclasses << k.to_s
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>
@@ -0,0 +1,5 @@
1
+ # Just an alias for glue/configuration.
2
+
3
+ require 'glue/configuration'
4
+
5
+ # * George Moschovitis <gm@navel.gr>
@@ -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
@@ -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.19.0
7
- date: 2005-06-17
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: []