ss-se_gem 0.0.6 → 1.0.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/lib/core_ext.rb CHANGED
@@ -1,2 +1,3 @@
1
- require 'lib/se/core_ext/meta_class'
1
+ require 'lib/se/core_ext/benchmark'
2
+ require 'lib/se/core_ext/date'
2
3
  require 'lib/se/core_ext/object'
data/lib/se/aspect.rb ADDED
@@ -0,0 +1,118 @@
1
+ #
2
+ # I had a look at AspectR [1], and it looked awfully confusing.
3
+ # I then had a look at AOP on wikipedia [2], I think the people
4
+ # who contributed to that have possibly gone whacko. An excerpt:
5
+ #
6
+ # "Since the risk is to code written by others, code weaving can
7
+ # be emotional for the authors of the original code. There is
8
+ # little moral grounding to guide programmers in these matters
9
+ # because morality isn't something often applied to coding practices"
10
+ #
11
+ # What??!
12
+ #
13
+ # Here is my non-academic completely morality-free implementation.
14
+ #
15
+ # See line 99 for the API. Feedback is appreciated.
16
+ #
17
+ # Ryan Allen (aspect@yeahnah.org)
18
+ #
19
+ # [1] http://aspectr.sourceforge.net/
20
+ # [2] http://en.wikipedia.org/wiki/Aspect-oriented_programming
21
+ #
22
+
23
+ #
24
+ # Example:
25
+ #
26
+ # class Foo
27
+ # def self.class_method
28
+ # puts 'class_method'
29
+ # end
30
+ # def instance_method
31
+ # puts 'instance_method'
32
+ # end
33
+ # end
34
+ #
35
+ # SE::Aspect.define do
36
+ # with_class(Foo).before(:class_method) do |klass|
37
+ # puts 'before class_method'
38
+ # end
39
+ #
40
+ # with_instance_of(Foo).before(:instance_method) do |instance|
41
+ # puts 'before instance_method'
42
+ # end
43
+ #
44
+ # with_class(Foo).after(:class_method) do | klass|
45
+ # puts 'after class_method'
46
+ # end
47
+ #
48
+ # with_instance_of(Foo).after(:instance_method) do |instance|
49
+ # puts 'after instance_method'
50
+ # end
51
+ # end
52
+ #
53
+ # Foo.class_method
54
+ # #=> before class_method
55
+ # #=> class_method
56
+ # #=> after class_method
57
+ #
58
+ # Foo.new.instance_method
59
+ # #=> before instance_method
60
+ # #=> instance_method
61
+ # #=> after instance_method
62
+ #
63
+ module SE
64
+ module Aspect
65
+
66
+ class << self
67
+
68
+ def define(&aspects)
69
+ instance_eval(&aspects)
70
+ end
71
+
72
+ def with_instance_of(klass)
73
+ @class = klass
74
+ @subject = :instance
75
+ self
76
+ end
77
+
78
+ def with_class(klass)
79
+ @class = klass
80
+ @subject = :class
81
+ self
82
+ end
83
+
84
+ def before(method_name, &perform_before)
85
+ with_scope do
86
+ method_prior = instance_method(method_name)
87
+ define_method method_name do |*args|
88
+ perform_before.call(self, *args)
89
+ method_prior.bind(self).call(*args)
90
+ end
91
+ end
92
+ end
93
+
94
+ def after(method_name, &perform_after)
95
+ with_scope do
96
+ method_prior = instance_method(method_name)
97
+ define_method method_name do |*args|
98
+ return_value = method_prior.bind(self).call(*args)
99
+ perform_after.call(self, *args)
100
+ return_value
101
+ end
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def with_scope(&code)
108
+ if @subject == :class
109
+ @class.class_eval { class << self; self; end }.instance_eval(&code)
110
+ else
111
+ @class.class_eval(&code)
112
+ end
113
+ end
114
+
115
+ end # class << self
116
+
117
+ end # module Aspect
118
+ end # module SE
@@ -0,0 +1,11 @@
1
+ module Benchmark
2
+ # from: http://blog.pluron.com/2008/01/guerrillas-way.html
3
+ # optimization to prevent unnecessary object creation
4
+ def realtime
5
+ r0 = Time.now
6
+ yield
7
+ r1 = Time.now
8
+ r1.to_f - r0.to_f
9
+ end
10
+ module_function :realtime
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'date'
2
+
3
+ class Date
4
+
5
+ # returns the number of days in the year
6
+ def days_in_year
7
+ leap? ? 366 : 365
8
+ end
9
+
10
+ end
@@ -0,0 +1,20 @@
1
+ class Regexp
2
+
3
+ def blank?
4
+ false
5
+ end
6
+
7
+ #
8
+ # Allow a Regexp to be used instead of an Array for matching a value.
9
+ #
10
+ # Instead of:
11
+ # ['a-1','a-2'].include?(value)
12
+ #
13
+ # We can:
14
+ # /a-[12]/.include?(value)
15
+ #
16
+ def include?(value)
17
+ not match(value.to_s).nil?
18
+ end
19
+
20
+ end
@@ -0,0 +1,32 @@
1
+ # From: http://blog.codefront.net/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/
2
+ #
3
+ # Adds +retryable+ method to Kernel.
4
+ #
5
+ module Kernel
6
+
7
+ # Options:
8
+ # * :tries - Number of retries to perform. Defaults to 1.
9
+ # * :on - The Exception on which a retry will be performed. (default Exception)
10
+ #
11
+ # Example
12
+ # =======
13
+ # retryable(:tries => 1, :on => OpenURI::HTTPError) do
14
+ # # your code here
15
+ # end
16
+ def retryable(options = {}, &block)
17
+ opts = {:tries => 1}.merge!(options)
18
+
19
+ retry_exception = opts[:on] || Exception
20
+
21
+ begin
22
+ return yield
23
+ rescue retry_exception
24
+ (opts[:tries] - 1).times do
25
+ return yield rescue retry_exception
26
+ end
27
+ end
28
+
29
+ yield
30
+ end
31
+
32
+ end
@@ -0,0 +1,24 @@
1
+
2
+
3
+ # from http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
4
+ #
5
+ # This method does NOT make a connection or send any packets to 64.233.187.99
6
+ # (Google). Since UDP is a stateless protocol connect() merely makes a
7
+ # system call which figures out how to route the packets based on the address
8
+ # and what interface (and therefore IP address) it should bind to. addr()
9
+ # returns an array containing the family (AF_INET), local port, and local
10
+ # address (which is what we want) of the socket.
11
+ #
12
+ def Socket.local_ip
13
+ @local_ip ||= begin
14
+ # turn off reverse DNS resolution temporarily
15
+ orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
16
+ UDPSocket.open do |s|
17
+ s.connect '64.233.187.99', 1
18
+ s.addr.last
19
+ end
20
+ end
21
+ ensure
22
+ Socket.do_not_reverse_lookup = orig
23
+ end
24
+
@@ -0,0 +1,13 @@
1
+
2
+
3
+ #
4
+ # Read a file, run it through ERB, then YAML::load.
5
+ #
6
+ # The caller is expected to have loaded ERB.
7
+ #
8
+ # +filename+ - name of file
9
+ # +args+ - arguments for ERB.new call
10
+ #
11
+ def YAML.load_erb_file(filename, *args)
12
+ YAML::load(ERB.new(IO.read(filename), *args).result)
13
+ end
@@ -0,0 +1,93 @@
1
+ # From http://scottstuff.net/blog/articles/2006/08/17/memory-leak-profiling-with-rails
2
+
3
+ # Simple memory profiler.
4
+ #
5
+ # Calling SE::MemoryProfiler.start will spin up a thread that writes
6
+ # instance counts to +log_file_name+ and optionally writes String
7
+ # values to +string_log_file_name+.
8
+ #
9
+ # Example:
10
+ #
11
+ # # write to log every 3 seconds
12
+ # SE::MemoryProfiler.start(:every=>3)
13
+ #
14
+ module SE
15
+ class MemoryProfiler
16
+ DEFAULTS = {:every => 10, :string_debug => false}
17
+
18
+ # Start the profiler.
19
+ #
20
+ # opts can be one of:
21
+ # +every+ => delay in seconds between output to +log_file_name+ (default 10)
22
+ # +string_debug+ => whether to write string values to +string_log_file_name+ (default false)
23
+ #
24
+ def self.start(opt={})
25
+ opt = DEFAULTS.dup.merge(opt)
26
+
27
+ Thread.new do
28
+ prev = Hash.new(0)
29
+ curr = Hash.new(0)
30
+ curr_strings = []
31
+ delta = Hash.new(0)
32
+
33
+ file = File.open(log_file_name,'w')
34
+
35
+ loop do
36
+ begin
37
+ GC.start
38
+ curr.clear
39
+
40
+ curr_strings = [] if opt[:string_debug]
41
+
42
+ ObjectSpace.each_object do |o|
43
+ curr[o.class] += 1 #Marshal.dump(o).size rescue 1
44
+ if opt[:string_debug] and o.class == String
45
+ curr_strings.push o
46
+ end
47
+ end
48
+
49
+ if opt[:string_debug]
50
+ File.open(string_log_file_name, 'w') do |f|
51
+ curr_strings.sort.each do |s|
52
+ f.puts s
53
+ end
54
+ end
55
+ curr_strings.clear
56
+ end
57
+
58
+ delta.clear
59
+ (curr.keys + delta.keys).uniq.each do |k,v|
60
+ delta[k] = curr[k]-prev[k]
61
+ end
62
+
63
+ file.puts "Top 20"
64
+ delta.sort_by { |k,v| -v.abs }[0..19].sort_by { |k,v| -v}.each do |k,v|
65
+ file.printf "%+5d: %s (%d)\n", v, k.name, curr[k] unless v == 0
66
+ end
67
+ file.flush
68
+
69
+ delta.clear
70
+ prev.clear
71
+ prev.update curr
72
+ GC.start
73
+ rescue Exception => err
74
+ STDERR.puts "** memory_profiler error: #{err}"
75
+ end
76
+ sleep opt[:every].to_i
77
+ end
78
+ end
79
+ end
80
+
81
+
82
+ # log file where object counts are written
83
+ def self.log_file_name
84
+ 'memory_profiler.log'
85
+ end
86
+
87
+ # log file where string values are written
88
+ def self.string_log_file_name(time=Time.now)
89
+ "memory_profiler_strings.log.#{time.to_i}"
90
+ end
91
+
92
+ end # class MemoryProfile
93
+ end # module SE
data/lib/se/negator.rb ADDED
@@ -0,0 +1,23 @@
1
+ # http://probablycorey.wordpress.com/2008/03/28/abusing-rubys-question-mark-methods/
2
+ #
3
+ # Takes an object as a parameter and will invert the return values of all its
4
+ # methods.
5
+ #
6
+
7
+ module SE
8
+ class Negator
9
+ def initialize(object)
10
+ @object = object
11
+ end
12
+
13
+ def method_missing(symbol, *args)
14
+ !@object.send(symbol, *args)
15
+ end
16
+ end
17
+ end
18
+
19
+ class Object
20
+ def not
21
+ SE::Negator.new(self)
22
+ end
23
+ end
data/lib/se/pager.rb ADDED
@@ -0,0 +1,39 @@
1
+ # From: http://nex-3.com/posts/73-git-style-automatic-paging-in-ruby
2
+ #
3
+ # Route STDOUT and STDERR through +less+ if output is more than one screen
4
+ #
5
+ # Call +SE::Pager.run_pager+ before you emit output in your program.
6
+ #
7
+ module SE
8
+ module Pager
9
+ def self.run_pager(less_opts='FRSX')
10
+ return if PLATFORM =~ /win32/
11
+ return unless STDOUT.tty?
12
+
13
+ read, write = IO.pipe
14
+
15
+ if Kernel.fork.nil?
16
+ # Child process
17
+ STDOUT.reopen(write)
18
+ STDERR.reopen(write) if STDERR.tty?
19
+ read.close
20
+ write.close
21
+ return
22
+ end
23
+
24
+ # Parent process, become pager
25
+ STDIN.reopen(read)
26
+ read.close
27
+ write.close
28
+
29
+ # set less options via envar
30
+ ENV['LESS'] = less_opts
31
+
32
+ # Wait until we have input before we start the pager
33
+ Kernel.select [STDIN]
34
+
35
+ pager = ENV['PAGER'] || 'less'
36
+ exec pager rescue exec "/bin/sh", "-c", pager
37
+ end
38
+ end # module Pager
39
+ end # module SE
data/lib/se/sleeper.rb ADDED
@@ -0,0 +1,105 @@
1
+ # Sleep, execute block, repeat.
2
+ # Allow resetting of the timer.
3
+ #
4
+ # An array of sleepers is stored in +Thread.main[:sleepers]+ to make
5
+ # sure we terminate all sleeper threads when a signal is trapped.
6
+ #
7
+ class Sleeper
8
+
9
+ # a hash of signals and their old handlers
10
+ OLD_HANDLERS = {
11
+ 'INT' => nil,
12
+ 'TERM' => nil,
13
+ }
14
+
15
+ class Reset < Exception ; end
16
+
17
+ attr_reader :thread
18
+
19
+ # Return an array of Sleepers in this process.
20
+ def self.sleepers
21
+ Thread.main[:sleepers] ||= begin
22
+ set_traps
23
+ []
24
+ end
25
+ end
26
+
27
+
28
+ # Initialize the sleeper by passing a +timetout+ in seconds and an
29
+ # optional block.
30
+ #
31
+ def initialize(timeout, &block)
32
+ after_wake &block if block_given?
33
+
34
+ Sleeper.sleepers << self
35
+
36
+ @thread = Thread.new do
37
+ while true do
38
+ begin
39
+ sleep(timeout.to_i)
40
+ # TODO: investigate using Thread.critical
41
+ Thread.current[:awake] = true
42
+ @after_wake.each {|block| block.call} if @after_wake
43
+ rescue Reset
44
+ @after_reset.each {|block| block.call} if @after_reset
45
+ # re-start sleep cycle
46
+ ensure
47
+ Thread.current[:awake] = false
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ # Reset the sleeper.
55
+ #
56
+ # This will cause all +after_reset+ handlers to be executed.
57
+ #
58
+ def reset
59
+ thread.raise(Reset.new) unless thread[:awake]
60
+ end
61
+
62
+ # Terminate the Sleeper.
63
+ #
64
+ # This will cause all +after_terminate+ handlers to be executed.
65
+ #
66
+ def terminate
67
+ Sleeper.sleepers.delete(self)
68
+ thread.terminate
69
+ @after_terminate.each {|block| block.call} if @after_terminate
70
+ @thread = nil
71
+ end
72
+
73
+ # Add a block to be executed after the Sleeper wakes up.
74
+ def after_wake(&block)
75
+ (@after_wake ||= []) << block
76
+ end
77
+
78
+ # Add a block to be executed after the Sleeper is reset.
79
+ def after_reset(&block)
80
+ (@after_reset ||= []) << block
81
+ end
82
+
83
+ # Add a block to be executed after the Sleeper is terminated.
84
+ def after_terminate(&block)
85
+ (@after_terminate ||= []) << block
86
+ end
87
+
88
+ private
89
+
90
+ def self.set_traps
91
+ OLD_HANDLERS.keys.each do |sig|
92
+ OLD_HANDLERS[sig] = Signal.trap(sig) do
93
+ kill_all_sleepers
94
+ OLD_HANDLERS[sig].call unless 'DEFAULT' == OLD_HANDLERS[sig]
95
+ end
96
+ end
97
+ end
98
+
99
+ def self.kill_all_sleepers
100
+ while to_kill = Thread.main[:sleepers].pop do
101
+ to_kill.terminate
102
+ end
103
+ end
104
+
105
+ end
data/lib/se/timer.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'lib/se/aspect'
2
+
3
+ module SE
4
+ class Timer
5
+
6
+ class << self
7
+ attr_accessor :stats, :timers, :enabled
8
+
9
+ def start(item)
10
+ return unless enabled
11
+ timers[item] = Time.now
12
+ end
13
+
14
+ def end(item)
15
+ return unless enabled
16
+ return unless timers[item]
17
+ self.stats[item][:calls] += 1
18
+ self.stats[item][:time] += Time.now - timers[item]
19
+ end
20
+
21
+ def time_block(item)
22
+ self.start(item)
23
+ retval = yield
24
+ self.end(item)
25
+ return retval
26
+ end
27
+
28
+ # Note: Does not work on methods that take blocks.
29
+ def time_method(klass, method, item, type="instance")
30
+ item ||= "#{klass}::#{method}"
31
+ SE::Aspect.define do
32
+ if type == "instance"
33
+ with_instance_of(klass).before(method.to_sym) {SE::Timer.start(item)}
34
+ with_instance_of(klass).after(method.to_sym) {SE::Timer.end(item)}
35
+ else
36
+ with_class(klass).before(method.to_sym) {SE::Timer.start(item)}
37
+ with_class(klass).after(method.to_sym) {SE::Timer.end(item)}
38
+ end
39
+ end
40
+ end
41
+
42
+ def reset
43
+ stats.clear
44
+ timers.clear
45
+ enabled = true
46
+ end
47
+
48
+ def stats
49
+ Thread.current['SE::Timer.stats'] ||= Hash.new {|hash, key| hash[key] = Hash.new(0.0)}
50
+ end
51
+
52
+ def timers
53
+ Thread.current['Worfkeed::Timer.timers'] ||= {}
54
+ end
55
+
56
+ def enabled
57
+ Thread.current['SE::timer.enabled'] ||= false
58
+ end
59
+
60
+ def enabled=(value)
61
+ Thread.current['SE::timer.enabled'] = value
62
+ end
63
+
64
+ end
65
+
66
+ end # class Timer
67
+ end # module SE
data/lib/se/unicode.rb ADDED
@@ -0,0 +1,28 @@
1
+ # Source: http://snippets.dzone.com/posts/show/4546
2
+ #
3
+ # This module lazily defines constants of the form Uxxxx for all Unicode
4
+ # codepoints from +U0000+ to +U10FFFF+. The value of each constant is the
5
+ # UTF-8 string for the codepoint.
6
+ #
7
+ # Examples:
8
+ # copyright = SE::Unicode::U00A9
9
+ # euro = SE::Unicode::U20AC
10
+ # infinity = SE::Unicode::U221E
11
+ #
12
+ module SE
13
+ module Unicode
14
+
15
+ def self.const_missing(name)
16
+ # Check that the constant name is of the right form: U0000 to U10FFFF
17
+ if name.to_s =~ /^U([0-9a-fA-F]{4,5}|10[0-9a-fA-F]{4})$/
18
+ # Convert the codepoint to an immutable UTF-8 string,
19
+ # define a real constant for that value and return the value
20
+ #p name, name.class
21
+ const_set(name, [$1.to_i(16)].pack("U").freeze)
22
+ else # Raise an error for constants that are not Unicode.
23
+ raise NameError, "Uninitialized constant: Unicode::#{name}"
24
+ end
25
+ end
26
+
27
+ end # module Unicode
28
+ end # module SE
@@ -0,0 +1,43 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../lib/se/aspect"
3
+
4
+ class AspectTest < Test::Unit::TestCase
5
+
6
+ class Foo < Array
7
+ end
8
+
9
+
10
+ # need to do all tests at once or we'll have side effects between tests
11
+ def test_aspect
12
+ before_class = false
13
+ before_instance = false
14
+ after_instance = false
15
+ after_class = false
16
+
17
+ SE::Aspect.define do
18
+ with_class(Foo).before(:new) do |klass|
19
+ before_class = true
20
+ end
21
+
22
+ with_instance_of(Foo).before(:empty?) do |instance|
23
+ before_instance = true
24
+ end
25
+
26
+ with_class(Foo).after(:new) do |klass|
27
+ after_instance = true
28
+ end
29
+
30
+ with_instance_of(Foo).after(:empty?) do |instance|
31
+ after_class = true
32
+ end
33
+ end
34
+
35
+ Foo.new.empty?
36
+ assert_equal true, before_class, 'before class method failed'
37
+ assert_equal true, after_class, 'after class method failed'
38
+ assert_equal true, before_instance, 'before instance method failed'
39
+ assert_equal true, after_instance, 'after instance method failed'
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,15 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../../lib/se/core_ext/date"
3
+
4
+ class DateTest < Test::Unit::TestCase
5
+
6
+ def test_days_in_year_for_normal_year
7
+ assert_equal 365, Date.parse('2009-01-01').days_in_year
8
+ end
9
+
10
+ def test_days_in_year_for_leap_year
11
+ assert_equal 366, Date.parse('2000-01-01').days_in_year
12
+ end
13
+
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../../lib/se/core_ext/regexp"
3
+
4
+ class RegexpTest < Test::Unit::TestCase
5
+
6
+ def test_blank
7
+ assert_equal false, /abc/.blank?, 'blank? should always return false'
8
+ end
9
+
10
+ def test_include
11
+ assert_equal true, /a|b|c/.include?('a'), '/a|b|c/ should match a'
12
+ assert_equal false, /a|b|c/.include?('x'), '/a|b|c/ should not match a'
13
+ end
14
+
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../../lib/se/core_ext/retryable"
3
+
4
+ class RetryableTest < Test::Unit::TestCase
5
+
6
+ def test_retryable_smoke_test
7
+ flag = true
8
+ Kernel.retryable(:tries => 2) do
9
+ if flag
10
+ flag = false
11
+ raise 'oops!'
12
+ end
13
+ end
14
+ end
15
+
16
+ end
@@ -1,5 +1,5 @@
1
1
  require 'test/unit'
2
- require "#{File.dirname(__FILE__)}/../../../lib/se/debug/debug"
2
+ require "#{File.dirname(__FILE__)}/../../lib/se/debug"
3
3
 
4
4
  class DebugTest < Test::Unit::TestCase
5
5
 
@@ -0,0 +1,19 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../lib/se/memory_profiler"
3
+ require 'fileutils'
4
+
5
+ class MemoryProfilerTest < Test::Unit::TestCase
6
+
7
+ def teardown
8
+ FileUtils.rm(SE::MemoryProfiler.log_file_name)
9
+ end
10
+
11
+ def test_memory_profiler
12
+ SE::MemoryProfiler.start(:every=>1)
13
+ sleep 3
14
+ assert_equal true, File.exists?(SE::MemoryProfiler.log_file_name)
15
+ lines = File.open(SE::MemoryProfiler.log_file_name, 'r') {|f| f.readlines}
16
+ assert_equal 3, lines.grep(/Top 20/).size
17
+ end
18
+
19
+ end
@@ -0,0 +1,13 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../lib/se/negator"
3
+
4
+ class NegatorTest < Test::Unit::TestCase
5
+
6
+ def test_negation
7
+ assert_equal false, [].not.empty?
8
+ assert_equal true, ['1'].not.empty?
9
+ end
10
+
11
+ end
12
+
13
+
@@ -0,0 +1,54 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../lib/se/sleeper"
3
+
4
+ class SleeperTest < Test::Unit::TestCase
5
+
6
+ def teardown
7
+ Sleeper.send(:kill_all_sleepers)
8
+ end
9
+
10
+ def test_initialize_accepts_no_block
11
+ @sleeper = Sleeper.new(1)
12
+ end
13
+
14
+ def test_block_executed_multiple_times
15
+ wakes = 0
16
+ @sleeper = Sleeper.new(1) {wakes += 1}
17
+ sleep(3)
18
+ assert_equal 2, wakes
19
+ end
20
+
21
+ def test_reset_invokes_after_reset_blocks
22
+ resets = 0
23
+ @sleeper = Sleeper.new(1)
24
+ @sleeper.after_reset {resets += 1}
25
+ @sleeper.reset
26
+ assert_equal 1, resets, 'Invalid number of resets'
27
+ end
28
+
29
+ def test_reset_prevents_after_wake_execution
30
+ @sleeper = Sleeper.new(2) {raise %q{after_wake shouldn't be called}}
31
+ 3.times do
32
+ sleep(1)
33
+ @sleeper.reset
34
+ end
35
+ end
36
+
37
+ def test_terminate_invokes_after_terminate_blocks
38
+ terminates = 0
39
+ sleeper = Sleeper.new(5)
40
+ sleeper.after_terminate {terminates += 1}
41
+ sleeper.terminate
42
+ assert_equal 1, terminates, 'Invalid number of terminates'
43
+ end
44
+
45
+ def test_signals_kills_sleeper_threads
46
+ count = Thread.list.size
47
+ Sleeper::OLD_HANDLERS.keys.each do |sig|
48
+ 5.times {Sleeper.new(30)}
49
+ Process.kill(sig, $$)
50
+ assert_equal count, Thread.list.size, 'too many threads left'
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,37 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../lib/se/timer"
3
+
4
+ class TimerTest < Test::Unit::TestCase
5
+
6
+ def test_thread_safety
7
+ threads = []
8
+ 3.times do
9
+ threads << Thread.new do
10
+ SE::Timer.enabled = true
11
+ SE::Timer.start(:thread)
12
+ sleep(1)
13
+ SE::Timer.end(:thread)
14
+ assert_equal 1, SE::Timer.stats[:thread][:calls], 'Incorrect call count'
15
+ end
16
+ end
17
+ threads.each {|ii| ii.join}
18
+ end
19
+
20
+ class Base
21
+ def foo
22
+ :foo
23
+ end
24
+ end
25
+
26
+ class Foo < Base
27
+ end
28
+
29
+ def test_inherited_class_timing
30
+ SE::Timer.time_method(Base, :foo, 'base.foo')
31
+ SE::Timer.time_method(Foo, :foo, 'foo.foo' )
32
+ SE::Timer.enabled = true
33
+ Foo.new.foo
34
+ assert_equal ['base.foo','foo.foo'], SE::Timer.stats.keys.sort
35
+ end
36
+
37
+ end # class TimerTest
@@ -0,0 +1,16 @@
1
+ require 'test/unit'
2
+ require "#{File.dirname(__FILE__)}/../../lib/se/unicode"
3
+
4
+ class UnicodeTest < Test::Unit::TestCase
5
+
6
+ def test_unicode
7
+ assert_equal "a", "#{SE::Unicode::U0061}"
8
+ end
9
+
10
+ def test_excepton_raised_on_invalid_unicode_value
11
+ assert_raise NameError do
12
+ "#{SE::Unicode::U65}"
13
+ end
14
+ end
15
+
16
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ss-se_gem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Steadman
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-05 00:00:00 -07:00
12
+ date: 2009-07-12 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -25,12 +25,25 @@ extra_rdoc_files:
25
25
  files:
26
26
  - lib/core_ext.rb
27
27
  - lib/debug.rb
28
+ - lib/se/aspect.rb
28
29
  - lib/se/core_ext/array.rb
30
+ - lib/se/core_ext/benchmark.rb
31
+ - lib/se/core_ext/date.rb
29
32
  - lib/se/core_ext/dir.rb
30
- - lib/se/core_ext/meta_class.rb
31
33
  - lib/se/core_ext/object.rb
32
- - lib/se/debug/debug.rb
34
+ - lib/se/core_ext/regexp.rb
35
+ - lib/se/core_ext/retryable.rb
36
+ - lib/se/core_ext/socket.rb
37
+ - lib/se/core_ext/yaml.rb
38
+ - lib/se/debug.rb
39
+ - lib/se/memory_profiler.rb
40
+ - lib/se/metaclass.rb
41
+ - lib/se/negator.rb
42
+ - lib/se/pager.rb
43
+ - lib/se/sleeper.rb
33
44
  - lib/se/test/difference.rb
45
+ - lib/se/timer.rb
46
+ - lib/se/unicode.rb
34
47
  - lib/se_gem.rb
35
48
  - lib/test.rb
36
49
  - LICENSE
@@ -62,7 +75,16 @@ signing_key:
62
75
  specification_version: 3
63
76
  summary: A collection of handy scripts.
64
77
  test_files:
65
- - test/se/debug/debug_test.rb
78
+ - test/se/sleeper_test.rb
79
+ - test/se/aspect_test.rb
80
+ - test/se/negator_test.rb
81
+ - test/se/unicode_test.rb
66
82
  - test/se/core_ext/dir_test.rb
83
+ - test/se/core_ext/retryable_test.rb
67
84
  - test/se/core_ext/object_test.rb
85
+ - test/se/core_ext/date_test.rb
68
86
  - test/se/core_ext/array_test.rb
87
+ - test/se/core_ext/regexp_test.rb
88
+ - test/se/timer_test.rb
89
+ - test/se/memory_profiler_test.rb
90
+ - test/se/debug_test.rb
File without changes
File without changes