glue 0.22.0 → 0.23.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|