glue 0.22.0 → 0.23.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.
- data/README +3 -3
- data/Rakefile +3 -3
- data/{CHANGELOG → doc/CHANGELOG.1} +0 -0
- data/doc/RELEASES +10 -0
- data/lib/glue.rb +7 -12
- data/lib/glue/configuration.rb +4 -4
- data/lib/glue/fixture.rb +3 -4
- data/lib/glue/helper.rb +1 -2
- data/lib/glue/logger.rb +43 -23
- data/lib/glue/metadata.rb +60 -0
- data/lib/glue/mock.rb +40 -0
- data/lib/glue/property.rb +33 -9
- data/lib/glue/property.rb.old +438 -0
- data/lib/glue/template.rb +1 -1
- data/lib/glue/uri.rb +2 -2
- data/test/glue/tc_metadata.rb +33 -0
- metadata +53 -57
- data/lib/glue/annotation.rb +0 -33
- data/lib/glue/array.rb +0 -61
- data/lib/glue/autoreload.rb +0 -30
- data/lib/glue/cache.rb +0 -189
- data/lib/glue/hash.rb +0 -122
- data/lib/glue/misc.rb +0 -15
- data/lib/glue/number.rb +0 -24
- data/lib/glue/object.rb +0 -35
- data/lib/glue/pool.rb +0 -60
- data/lib/glue/snapshot.rb +0 -104
- data/lib/glue/string.rb +0 -162
- data/lib/glue/time.rb +0 -85
- data/lib/vendor/blankslate.rb +0 -53
- data/test/glue/tc_hash.rb +0 -36
- data/test/glue/tc_numbers.rb +0 -18
- data/test/glue/tc_strings.rb +0 -102
data/lib/glue/hash.rb
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: hash.rb 182 2005-07-22 10:07:50Z gmosx $
|
4
|
-
|
5
|
-
require 'sync'
|
6
|
-
|
7
|
-
module Glue
|
8
|
-
|
9
|
-
# A thread-safe hash. We use a sync object instead of a mutex,
|
10
|
-
# because it is re-entrant. An exclusive lock is needed when
|
11
|
-
# writing, a shared lock IS NEEDED when reading
|
12
|
-
# uses the delegator pattern to allow for multiple
|
13
|
-
# implementations!
|
14
|
-
|
15
|
-
class SafeHash < Hash
|
16
|
-
attr :sync
|
17
|
-
|
18
|
-
# gmosx: delegator is not used.
|
19
|
-
#
|
20
|
-
def initialize(delegator = nil)
|
21
|
-
@sync = ::Sync.new
|
22
|
-
end
|
23
|
-
|
24
|
-
def [](key)
|
25
|
-
@sync.synchronize(::Sync::SH) { super }
|
26
|
-
end
|
27
|
-
|
28
|
-
def []=(key, value)
|
29
|
-
@sync.synchronize(::Sync::EX) { super }
|
30
|
-
end
|
31
|
-
|
32
|
-
def delete(key)
|
33
|
-
@sync.synchronize(::Sync::EX) { super }
|
34
|
-
end
|
35
|
-
|
36
|
-
def clear
|
37
|
-
@sync.synchronize(::Sync::EX) { super }
|
38
|
-
end
|
39
|
-
|
40
|
-
def size
|
41
|
-
@sync.synchronize(::Sync::SH) { super }
|
42
|
-
end
|
43
|
-
|
44
|
-
def values
|
45
|
-
@sync.synchronize(::Sync::SH) { super }
|
46
|
-
end
|
47
|
-
|
48
|
-
def keys
|
49
|
-
@sync.synchronize(::Sync::SH) { super }
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
# A thread-safe hash. We use a sync object instead of a mutex,
|
55
|
-
# because it is re-entrant. An exclusive lock is needed when
|
56
|
-
# writing, a shared lock IS NEEDED when reading.
|
57
|
-
#
|
58
|
-
# === Design
|
59
|
-
#
|
60
|
-
# This class uses the delegator pattern. However we dont use rubys
|
61
|
-
# delegation facilities, they are more general and powerfull than we
|
62
|
-
# need here (and slower). Instead a custom (but simple) solution is
|
63
|
-
# used.
|
64
|
-
#
|
65
|
-
# === Example
|
66
|
-
#
|
67
|
-
# hash = SafeHashDelegator.new(Hash.new)
|
68
|
-
# hash = SafeHashDelegator.new(Hash.new)
|
69
|
-
|
70
|
-
class SafeHashDelegator < Hash
|
71
|
-
attr :delegate, :sync
|
72
|
-
|
73
|
-
def initialize(delegate)
|
74
|
-
@delegate = delegate
|
75
|
-
@sync = ::Sync.new
|
76
|
-
end
|
77
|
-
|
78
|
-
def [](key)
|
79
|
-
@sync.synchronize(::Sync::SH) {
|
80
|
-
@delegate[key]
|
81
|
-
}
|
82
|
-
end
|
83
|
-
|
84
|
-
def []=(key, value)
|
85
|
-
@sync.synchronize(::Sync::EX) {
|
86
|
-
@delegate[key] = value
|
87
|
-
}
|
88
|
-
end
|
89
|
-
|
90
|
-
def delete(key)
|
91
|
-
@sync.synchronize(::Sync::EX) {
|
92
|
-
@delegate.delete(key)
|
93
|
-
}
|
94
|
-
end
|
95
|
-
|
96
|
-
def clear
|
97
|
-
@sync.synchronize(::Sync::EX) {
|
98
|
-
@delegate.clear
|
99
|
-
}
|
100
|
-
end
|
101
|
-
|
102
|
-
def size
|
103
|
-
@sync.synchronize(::Sync::SH) {
|
104
|
-
@delegate.size()
|
105
|
-
}
|
106
|
-
end
|
107
|
-
|
108
|
-
def values
|
109
|
-
@sync.synchronize(::Sync::SH) {
|
110
|
-
@delegate.values()
|
111
|
-
}
|
112
|
-
end
|
113
|
-
|
114
|
-
def keys
|
115
|
-
@sync.synchronize(::Sync::SH) {
|
116
|
-
@delegate.keys()
|
117
|
-
}
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
data/lib/glue/misc.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: misc.rb 182 2005-07-22 10:07:50Z gmosx $
|
4
|
-
|
5
|
-
# Executes a Ruby block without warnings.
|
6
|
-
|
7
|
-
def silence_warnings
|
8
|
-
old_verbose, $VERBOSE = $VERBOSE, nil
|
9
|
-
begin
|
10
|
-
yield
|
11
|
-
ensure
|
12
|
-
$VERBOSE = old_verbose
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
data/lib/glue/number.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: number.rb 182 2005-07-22 10:07:50Z gmosx $
|
4
|
-
|
5
|
-
module Glue;
|
6
|
-
|
7
|
-
# Implement as a module to avoid class polution. You can
|
8
|
-
# still use Ruby's advanced features to include the module in your
|
9
|
-
# class. Passing the object to act upon allows to check for nil,
|
10
|
-
# which isn't possible if you use self.
|
11
|
-
|
12
|
-
module NumberUtils
|
13
|
-
|
14
|
-
# Returns the multiple ceil of a number
|
15
|
-
|
16
|
-
def self.ceil_multiple(num, multiple)
|
17
|
-
# gmosx: to_f is needed!
|
18
|
-
# gmosx: IS THERE a more optimized way to do this?
|
19
|
-
return ((num.to_f/multiple).ceil*multiple)
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
data/lib/glue/object.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# Original code from RubyOnRails (http://www.rubyonrails.com)
|
2
|
-
#--
|
3
|
-
# TODO: suggest inclusion in Facets.
|
4
|
-
#++
|
5
|
-
|
6
|
-
class Object #:nodoc:
|
7
|
-
def remove_subclasses_of(superclass)
|
8
|
-
subclasses_of(superclass).each do |subclass|
|
9
|
-
Object.send(:remove_const, subclass) rescue nil
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def subclasses_of(superclass)
|
14
|
-
subclasses = []
|
15
|
-
ObjectSpace.each_object(Class) do |c|
|
16
|
-
if c.ancestors.include?(superclass) and superclass != c
|
17
|
-
subclasses << c
|
18
|
-
end
|
19
|
-
end
|
20
|
-
return subclasses
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class Class #:nodoc:
|
25
|
-
def remove_subclasses
|
26
|
-
Object.remove_subclasses_of(self)
|
27
|
-
end
|
28
|
-
|
29
|
-
def subclasses
|
30
|
-
Object.subclasses_of(self)
|
31
|
-
end
|
32
|
-
alias_method :descendants, :subclasses
|
33
|
-
end
|
34
|
-
|
35
|
-
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/pool.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: pool.rb 182 2005-07-22 10:07:50Z gmosx $
|
4
|
-
|
5
|
-
require 'thread'
|
6
|
-
require 'monitor'
|
7
|
-
|
8
|
-
module Glue
|
9
|
-
|
10
|
-
# Generalized object pool implementation. Implemented as a thread
|
11
|
-
# safe stack. Exclusive locking is needed both for push and pop.
|
12
|
-
#
|
13
|
-
# INVESTIGATE: Could use the SizedQueue/Queue.
|
14
|
-
|
15
|
-
class Pool < Array
|
16
|
-
include MonitorMixin
|
17
|
-
|
18
|
-
def initialize
|
19
|
-
super
|
20
|
-
@cv = new_cond()
|
21
|
-
end
|
22
|
-
|
23
|
-
# Add, restore an object to the pool.
|
24
|
-
|
25
|
-
def push(obj)
|
26
|
-
synchronize do
|
27
|
-
super
|
28
|
-
@cv.signal()
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Obtain an object from the pool.
|
33
|
-
|
34
|
-
def pop
|
35
|
-
synchronize do
|
36
|
-
@cv.wait_while { empty? }
|
37
|
-
super
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Obtains an object, passes it to a block for processing
|
42
|
-
# and restores it to the pool.
|
43
|
-
|
44
|
-
def obtain
|
45
|
-
result = nil
|
46
|
-
|
47
|
-
begin
|
48
|
-
obj = pop()
|
49
|
-
|
50
|
-
result = yield(obj)
|
51
|
-
ensure
|
52
|
-
push(obj)
|
53
|
-
end
|
54
|
-
|
55
|
-
return result
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
data/lib/glue/snapshot.rb
DELETED
@@ -1,104 +0,0 @@
|
|
1
|
-
module Glue
|
2
|
-
|
3
|
-
# Class Snapshot simply represents a collection of objects from
|
4
|
-
# which snapshots were taken via their methods #take_snapshot.
|
5
|
-
# It provides methods to add an object to a snapshot
|
6
|
-
# (method Glue::Snapshot#add) as well as to restore all objects
|
7
|
-
# of the snapshot to their state stored in the snapshot (method
|
8
|
-
# Glue::Snapshot#restore).
|
9
|
-
#
|
10
|
-
# In Wee, this class is used to backtracking the state of
|
11
|
-
# components (or decorations/presenters). Components that want
|
12
|
-
# an undo-facility to be implemented (triggered for example by
|
13
|
-
# a browsers back-button), have to overwrite the
|
14
|
-
# Wee::Component#backtrack_state method.
|
15
|
-
|
16
|
-
class Snapshot
|
17
|
-
def initialize
|
18
|
-
@objects = Hash.new
|
19
|
-
end
|
20
|
-
|
21
|
-
def add(object)
|
22
|
-
oid = object.object_id
|
23
|
-
@objects[oid] = [object, object.take_snapshot] unless @objects.include?(oid)
|
24
|
-
end
|
25
|
-
|
26
|
-
def restore
|
27
|
-
@objects.each_value { |object, value| object.restore_snapshot(value) }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
module DupReplaceSnapshotMixin
|
32
|
-
def take_snapshot
|
33
|
-
dup
|
34
|
-
end
|
35
|
-
|
36
|
-
def restore_snapshot(snap)
|
37
|
-
replace(snap)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Implements a value holder. In Wee this is useful for
|
42
|
-
# backtracking the reference assigned to an instance variable
|
43
|
-
# (not the object itself!). An example where this is used is the
|
44
|
-
# <tt>@__decoration</tt> attribute of class Wee::Component.
|
45
|
-
|
46
|
-
class ValueHolder
|
47
|
-
attr_accessor :value
|
48
|
-
|
49
|
-
def initialize(value=nil)
|
50
|
-
@value = value
|
51
|
-
end
|
52
|
-
|
53
|
-
def take_snapshot
|
54
|
-
@value
|
55
|
-
end
|
56
|
-
|
57
|
-
def restore_snapshot(value)
|
58
|
-
@value = value
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
#--
|
65
|
-
# Extend some base classes of Ruby (Object, Array, String, Hash,
|
66
|
-
# Struct) for the two methods #take_snapshot and
|
67
|
-
# #restore_snapshot, required by Snapshot.
|
68
|
-
#++
|
69
|
-
|
70
|
-
class Object
|
71
|
-
def take_snapshot
|
72
|
-
snap = Hash.new
|
73
|
-
instance_variables.each do |iv|
|
74
|
-
snap[iv] = instance_variable_get(iv)
|
75
|
-
end
|
76
|
-
snap
|
77
|
-
end
|
78
|
-
|
79
|
-
def restore_snapshot(snap)
|
80
|
-
instance_variables.each do |iv|
|
81
|
-
instance_variable_set(iv, snap[iv])
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
class Array; include Glue::DupReplaceSnapshotMixin end
|
87
|
-
|
88
|
-
class String; include Glue::DupReplaceSnapshotMixin end
|
89
|
-
|
90
|
-
class Hash; include Glue::DupReplaceSnapshotMixin end
|
91
|
-
|
92
|
-
class Struct
|
93
|
-
def take_snapshot
|
94
|
-
snap = Hash.new
|
95
|
-
each_pair {|k,v| snap[k] = v}
|
96
|
-
snap
|
97
|
-
end
|
98
|
-
|
99
|
-
def restore_snapshot(snap)
|
100
|
-
snap.each_pair {|k,v| send(k.to_s + "=", v)}
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# * Michael Neumann <mneumann@ntecs.de>
|
data/lib/glue/string.rb
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# * Anastasios Koutoumanos <ak@navel.gr>
|
3
|
-
# * Elias Karakoulakis <ekarak@ktismata.com>
|
4
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
5
|
-
# $Id: string.rb 182 2005-07-22 10:07:50Z gmosx $
|
6
|
-
|
7
|
-
require 'uri'
|
8
|
-
|
9
|
-
module Glue;
|
10
|
-
|
11
|
-
# General string utilities collection.
|
12
|
-
#
|
13
|
-
# === Design:
|
14
|
-
#
|
15
|
-
# Implement as a module to avoid class polution. You can
|
16
|
-
# still Ruby's advanced features to include the module in your
|
17
|
-
# class. Passing the object to act upon allows to check for nil,
|
18
|
-
# which isn't possible if you use self.
|
19
|
-
#
|
20
|
-
# === TODO:
|
21
|
-
#
|
22
|
-
# - implement a method that returns easy to remember
|
23
|
-
# pseudo-random strings
|
24
|
-
# - add aliases for those methods in Kernel.
|
25
|
-
|
26
|
-
module StringUtils
|
27
|
-
|
28
|
-
# Move this in String class?
|
29
|
-
#
|
30
|
-
# Tests a string for a valid value (non nil, not empty)
|
31
|
-
#
|
32
|
-
def self.valid?(string)
|
33
|
-
return (not ((nil == string) or (string.empty?)))
|
34
|
-
end
|
35
|
-
|
36
|
-
# returns short abstract of long strings (first 'count'
|
37
|
-
# characters, chopped at the nearest word, appended by '...')
|
38
|
-
# force_cutoff: break forcibly at 'count' chars. Does not accept
|
39
|
-
# count < 2.
|
40
|
-
|
41
|
-
def self.head(string, count = 128, force_cutoff = false, ellipsis="...")
|
42
|
-
return nil unless string
|
43
|
-
return nil if count < 2
|
44
|
-
|
45
|
-
if string.size > count
|
46
|
-
cut_at = force_cutoff ? count : (string.index(' ', count-1) || count)
|
47
|
-
xstring = string.slice(0, cut_at)
|
48
|
-
return xstring.chomp(" ") + ellipsis
|
49
|
-
else
|
50
|
-
return string
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Apply a set of rules (regular expression matches) to the
|
55
|
-
# string
|
56
|
-
#
|
57
|
-
# === Requirements:
|
58
|
-
# - the rules must be applied in order! So we cannot use a
|
59
|
-
# hash because the ordering is not guaranteed! we use an
|
60
|
-
# array instead.
|
61
|
-
#
|
62
|
-
# === Input:
|
63
|
-
# the string to rewrite
|
64
|
-
# the array containing rule-pairs (match, rewrite)
|
65
|
-
#
|
66
|
-
# === Output:
|
67
|
-
# the rewritten string
|
68
|
-
|
69
|
-
MATCH = 0
|
70
|
-
REWRITE = 1
|
71
|
-
|
72
|
-
def self.rewrite(string, rules)
|
73
|
-
return nil unless string
|
74
|
-
|
75
|
-
# gmosx: helps to find bugs
|
76
|
-
raise ArgumentError.new('The rules parameter is nil') unless rules
|
77
|
-
|
78
|
-
rewritten_string = string.dup
|
79
|
-
|
80
|
-
for rule in rules
|
81
|
-
rewritten_string.gsub!(rule[MATCH], rule[REWRITE])
|
82
|
-
end
|
83
|
-
|
84
|
-
return (rewritten_string or string)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Enforces a maximum width of a string inside an
|
88
|
-
# html container. If the string exceeds this maximum width
|
89
|
-
# the string gets wraped.
|
90
|
-
#
|
91
|
-
# Not really useful, better use the CSS overflow: hidden
|
92
|
-
# functionality.
|
93
|
-
#
|
94
|
-
# === Input:
|
95
|
-
# the string to be wrapped
|
96
|
-
# the enforced width
|
97
|
-
# the separator used for wrapping
|
98
|
-
#
|
99
|
-
# === Output:
|
100
|
-
# the wrapped string
|
101
|
-
#
|
102
|
-
# === Example:
|
103
|
-
# text = "1111111111111111111111111111111111111111111"
|
104
|
-
# text = wrap(text, 10, " ")
|
105
|
-
# p text # => "1111111111 1111111111 1111111111"
|
106
|
-
#
|
107
|
-
# See the test cases to better understand the behaviour!
|
108
|
-
|
109
|
-
def self.wrap(string, width = 20, separator = " ")
|
110
|
-
return nil unless string
|
111
|
-
|
112
|
-
re = /([^#{separator}]{1,#{width}})/
|
113
|
-
wrapped_string = string.scan(re).join(separator)
|
114
|
-
|
115
|
-
return wrapped_string
|
116
|
-
end
|
117
|
-
|
118
|
-
# Replace dangerours chars in filenames
|
119
|
-
=begin
|
120
|
-
def self.rationalize_filename(filename)
|
121
|
-
return nil unless filename
|
122
|
-
# gmosx: rationalize a copy!!! (add unit test)
|
123
|
-
xfilename = filename.dup()
|
124
|
-
# gmosx: replace some dangerous chars!
|
125
|
-
xfilename.gsub!(/ /, "-")
|
126
|
-
xfilename.gsub!(/!/, "")
|
127
|
-
xfilename.gsub!(/'/, "")
|
128
|
-
xfilename.gsub!(/\(/, "")
|
129
|
-
xfilename.gsub!(/\)/, "")
|
130
|
-
# xfilename = self.to_greeklish(xfilename)
|
131
|
-
return xfilename
|
132
|
-
end
|
133
|
-
=end
|
134
|
-
|
135
|
-
# Returns a random string. one possible use is
|
136
|
-
# password initialization.
|
137
|
-
#
|
138
|
-
# === Input:
|
139
|
-
# the maximum length of the string
|
140
|
-
#
|
141
|
-
# === Output:
|
142
|
-
# the random string
|
143
|
-
|
144
|
-
def self.random(max_length = 8, char_re = /[\w\d]/)
|
145
|
-
# gmosx: this is a nice example of input parameter checking.
|
146
|
-
# this is NOT a real time called method so we can add this
|
147
|
-
# check. Congrats to the author.
|
148
|
-
raise ArgumentError.new('char_re must be a regular expression!') unless char_re.is_a?(Regexp)
|
149
|
-
|
150
|
-
string = ""
|
151
|
-
|
152
|
-
while string.length < max_length
|
153
|
-
ch = rand(255).chr
|
154
|
-
string << ch if ch =~ char_re
|
155
|
-
end
|
156
|
-
|
157
|
-
return string
|
158
|
-
end
|
159
|
-
|
160
|
-
end
|
161
|
-
|
162
|
-
end
|