simply_useful 0.1.5
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/.gitignore +9 -0
- data/MIT-LICENSE +21 -0
- data/README +14 -0
- data/Rakefile +72 -0
- data/VERSION.yml +4 -0
- data/lib/bsearch.rb +125 -0
- data/lib/core_ext/hash.rb +42 -0
- data/lib/core_ext.rb +1 -0
- data/lib/format.rb +6 -0
- data/lib/has_attributes.rb +19 -0
- data/lib/java_native2ascii.rb +42 -0
- data/lib/simply_useful.rb +5 -0
- data/simply_useful.gemspec +65 -0
- data/spec/bsearch_spec.rb +58 -0
- data/spec/core_ext/hash_spec.rb +22 -0
- data/spec/has_attributes_spec.rb +55 -0
- data/spec/java_native2ascii_spec.rb +32 -0
- data/spec/simply_useful_spec.rb +18 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +5 -0
- metadata +86 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2008 Maciej Biłas
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
# Gem building
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |s|
|
8
|
+
s.name = "simply_useful"
|
9
|
+
s.summary = "A set of simply useful classes"
|
10
|
+
s.email = "maciej@inszy.org"
|
11
|
+
s.homepage = "http://github.com/maciej/simply_useful"
|
12
|
+
s.description = "A set of simply useful classes. Contains extensions to core Ruby classes."
|
13
|
+
s.authors = ["Maciej Bilas"]
|
14
|
+
s.rubyforge_project = %q{simply_useful}
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Specs
|
21
|
+
begin
|
22
|
+
require 'spec'
|
23
|
+
rescue LoadError
|
24
|
+
require 'spec'
|
25
|
+
end
|
26
|
+
begin
|
27
|
+
require 'spec/rake/spectask'
|
28
|
+
rescue LoadError
|
29
|
+
puts <<-EOS
|
30
|
+
To use rspec for testing you must install rspec gem:
|
31
|
+
gem install rspec
|
32
|
+
EOS
|
33
|
+
exit(0)
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Run the specs under spec/models"
|
37
|
+
Spec::Rake::SpecTask.new do |t|
|
38
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
39
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
40
|
+
end
|
41
|
+
|
42
|
+
# Coverage
|
43
|
+
begin
|
44
|
+
require 'rcov/rcovtask'
|
45
|
+
Rcov::RcovTask.new do |t|
|
46
|
+
t.libs << 'test'
|
47
|
+
t.test_files = FileList['test/**/*_test.rb']
|
48
|
+
t.verbose = true
|
49
|
+
end
|
50
|
+
rescue LoadError
|
51
|
+
puts "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
52
|
+
end
|
53
|
+
|
54
|
+
# RDoc
|
55
|
+
require 'rake/rdoctask'
|
56
|
+
Rake::RDocTask.new do |rdoc|
|
57
|
+
rdoc.rdoc_dir = 'rdoc'
|
58
|
+
rdoc.title = 'the-perfect-gemx'
|
59
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
60
|
+
rdoc.rdoc_files.include('README*')
|
61
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
62
|
+
end
|
63
|
+
|
64
|
+
# Cucumber
|
65
|
+
begin
|
66
|
+
require 'cucumber/rake/task'
|
67
|
+
Cucumber::Rake::Task.new(:features)
|
68
|
+
rescue LoadError
|
69
|
+
puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
70
|
+
end
|
71
|
+
|
72
|
+
task :default => :spec
|
data/VERSION.yml
ADDED
data/lib/bsearch.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
#
|
2
|
+
# Ruby/Bsearch - a binary search library for Ruby.
|
3
|
+
#
|
4
|
+
# Copyright (C) 2001 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the Ruby's licence.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# % irb -r ./bsearch.rb
|
14
|
+
# >> %w(a b c c c d e f).bsearch_first {|x| x <=> "c"}
|
15
|
+
# => 2
|
16
|
+
# >> %w(a b c c c d e f).bsearch_last {|x| x <=> "c"}
|
17
|
+
# => 4
|
18
|
+
# >> %w(a b c e f).bsearch_first {|x| x <=> "c"}
|
19
|
+
# => 2
|
20
|
+
# >> %w(a b e f).bsearch_first {|x| x <=> "c"}
|
21
|
+
# => nil
|
22
|
+
# >> %w(a b e f).bsearch_last {|x| x <=> "c"}
|
23
|
+
# => nil
|
24
|
+
# >> %w(a b e f).bsearch_lower_boundary {|x| x <=> "c"}
|
25
|
+
# => 2
|
26
|
+
# >> %w(a b e f).bsearch_upper_boundary {|x| x <=> "c"}
|
27
|
+
# => 2
|
28
|
+
# >> %w(a b c c c d e f).bsearch_range {|x| x <=> "c"}
|
29
|
+
# => 2...5
|
30
|
+
# >> %w(a b c d e f).bsearch_range {|x| x <=> "c"}
|
31
|
+
# => 2...3
|
32
|
+
# >> %w(a b d e f).bsearch_range {|x| x <=> "c"}
|
33
|
+
# => 2...2
|
34
|
+
|
35
|
+
module Bsearch
|
36
|
+
#VERSION = '1.5'
|
37
|
+
|
38
|
+
#
|
39
|
+
# The binary search algorithm is extracted from Jon Bentley's
|
40
|
+
# Programming Pearls 2nd ed. p.93
|
41
|
+
#
|
42
|
+
|
43
|
+
#
|
44
|
+
# Return the lower boundary. (inside)
|
45
|
+
#
|
46
|
+
def bsearch_lower_boundary (range = 0 ... self.length, &block)
|
47
|
+
lower = range.first() -1
|
48
|
+
upper = if range.exclude_end? then range.last else range.last + 1 end
|
49
|
+
while lower + 1 != upper
|
50
|
+
mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational)
|
51
|
+
if yield(self[mid]) < 0
|
52
|
+
lower = mid
|
53
|
+
else
|
54
|
+
upper = mid
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return upper
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# This method searches the FIRST occurrence which satisfies a
|
62
|
+
# condition given by a block in binary fashion and return the
|
63
|
+
# index of the first occurrence. Return nil if not found.
|
64
|
+
#
|
65
|
+
def bsearch_first (range = 0 ... self.length, &block)
|
66
|
+
boundary = bsearch_lower_boundary(range, &block)
|
67
|
+
if boundary >= self.length || yield(self[boundary]) != 0
|
68
|
+
return nil
|
69
|
+
else
|
70
|
+
return boundary
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
alias bsearch bsearch_first
|
75
|
+
|
76
|
+
#
|
77
|
+
# Return the upper boundary. (outside)
|
78
|
+
#
|
79
|
+
def bsearch_upper_boundary (range = 0 ... self.length, &block)
|
80
|
+
lower = range.first() -1
|
81
|
+
upper = if range.exclude_end? then range.last else range.last + 1 end
|
82
|
+
while lower + 1 != upper
|
83
|
+
mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational)
|
84
|
+
if yield(self[mid]) <= 0
|
85
|
+
lower = mid
|
86
|
+
else
|
87
|
+
upper = mid
|
88
|
+
end
|
89
|
+
end
|
90
|
+
return lower + 1 # outside of the matching range.
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# This method searches the LAST occurrence which satisfies a
|
95
|
+
# condition given by a block in binary fashion and return the
|
96
|
+
# index of the last occurrence. Return nil if not found.
|
97
|
+
#
|
98
|
+
def bsearch_last (range = 0 ... self.length, &block)
|
99
|
+
# `- 1' for canceling `lower + 1' in bsearch_upper_boundary.
|
100
|
+
boundary = bsearch_upper_boundary(range, &block) - 1
|
101
|
+
|
102
|
+
if (boundary <= -1 || yield(self[boundary]) != 0)
|
103
|
+
return nil
|
104
|
+
else
|
105
|
+
return boundary
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Return the search result as a Range object.
|
111
|
+
#
|
112
|
+
def bsearch_range (range = 0 ... self.length, &block)
|
113
|
+
lower = bsearch_lower_boundary(range, &block)
|
114
|
+
upper = bsearch_upper_boundary(range, &block)
|
115
|
+
return lower ... upper
|
116
|
+
end
|
117
|
+
|
118
|
+
def bfind(range = 0 ... self.length, &block)
|
119
|
+
pos = self.bsearch(range, &block)
|
120
|
+
return nil if pos.nil?
|
121
|
+
self[pos]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
Array.send :include, Bsearch
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SimplyUseful
|
2
|
+
module CoreExtensions
|
3
|
+
module Keys
|
4
|
+
|
5
|
+
# How it's done in active support
|
6
|
+
# File lib/active_support/core_ext/hash/keys.rb, line 22
|
7
|
+
#22: def symbolize_keys
|
8
|
+
#23: inject({}) do |options, (key, value)|
|
9
|
+
#24: options[(key.to_sym rescue key) || key] = value
|
10
|
+
#25: options
|
11
|
+
#26: end
|
12
|
+
#27: end
|
13
|
+
|
14
|
+
# Another article mentioning that method
|
15
|
+
# http://www.any-where.de/blog/ruby-hash-convert-string-keys-to-symbols/
|
16
|
+
|
17
|
+
def deep_symbolize_keys
|
18
|
+
_deep_symbolize_keys(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def deep_symbolize_keys!
|
22
|
+
self.replace(self.deep_symbolize_keys)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def _deep_symbolize_keys(value)
|
28
|
+
return value unless value.is_a?(Hash)
|
29
|
+
hash = value.inject({}) do |memo,(k,v)|
|
30
|
+
memo[(k.to_sym rescue k)|| k] = _deep_symbolize_keys(v)
|
31
|
+
memo
|
32
|
+
end
|
33
|
+
return hash
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Hash
|
41
|
+
include SimplyUseful::CoreExtensions::Keys
|
42
|
+
end
|
data/lib/core_ext.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'core_ext/hash'
|
data/lib/format.rb
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
# Taken from Mephisto (http://mephistoblog.com/)
|
2
|
+
module Format
|
3
|
+
DOMAIN = /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|(h[kmnrtu]#{(defined? RAILS_ENV) && RAILS_ENV=='test'?'|host':''})|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/ unless const_defined?(:DOMAIN)
|
4
|
+
STRING = /^[a-z0-9-]+$/
|
5
|
+
EMAIL = /(\A(\s*)\Z)|(\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z)/i
|
6
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module HasAttributes
|
2
|
+
def initialize(attributes = nil)
|
3
|
+
self.attributes = attributes
|
4
|
+
yield self if block_given?
|
5
|
+
end
|
6
|
+
|
7
|
+
def attributes=(attributes) # , guard_protected_attributes = true
|
8
|
+
#attributes = filter_attributes(attributes) if !attributes.blank? && guard_protected_attributes
|
9
|
+
attributes.each do |key,value|
|
10
|
+
send(key.to_s + '=', value)
|
11
|
+
end if attributes
|
12
|
+
end
|
13
|
+
|
14
|
+
def attributes
|
15
|
+
attributes = instance_variables
|
16
|
+
attributes.delete("@errors")
|
17
|
+
Hash[*attributes.collect { |attribute| [attribute[1..-1].to_sym, instance_variable_get(attribute)] }.flatten]
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require('iconv')
|
2
|
+
|
3
|
+
# Mimics Java's native2ascii tool
|
4
|
+
class JavaNative2Ascii
|
5
|
+
def self.ascii2native str
|
6
|
+
str.gsub(/\\u[0-9a-f]{4}/i) do |s|
|
7
|
+
out = ""
|
8
|
+
i = s[2,4].hex
|
9
|
+
out << (i & 0xFF)
|
10
|
+
out << (i >> 8)
|
11
|
+
out = Iconv.conv("UTF-8", "UNICODE", out)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.native2ascii str
|
16
|
+
out = ""
|
17
|
+
|
18
|
+
arr = str.unpack("U*")
|
19
|
+
return out if arr.nil?
|
20
|
+
# arr_s = arr.size
|
21
|
+
# i = 0
|
22
|
+
#
|
23
|
+
# while i < arr_s
|
24
|
+
# c = arr[i]
|
25
|
+
# if c > 127
|
26
|
+
# out << sprintf("\\u%04x", c)
|
27
|
+
# else
|
28
|
+
# out << c
|
29
|
+
# end
|
30
|
+
# i+=1
|
31
|
+
# end
|
32
|
+
arr.each do |c|
|
33
|
+
if c > 127
|
34
|
+
out << sprintf("\\u%04x", c)
|
35
|
+
else
|
36
|
+
out << c
|
37
|
+
end
|
38
|
+
end
|
39
|
+
out
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{simply_useful}
|
8
|
+
s.version = "0.1.5"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Maciej Bilas"]
|
12
|
+
s.date = %q{2010-03-19}
|
13
|
+
s.description = %q{A set of simply useful classes. Contains extensions to core Ruby classes.}
|
14
|
+
s.email = %q{maciej@inszy.org}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"MIT-LICENSE",
|
21
|
+
"README",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION.yml",
|
24
|
+
"lib/bsearch.rb",
|
25
|
+
"lib/core_ext.rb",
|
26
|
+
"lib/core_ext/hash.rb",
|
27
|
+
"lib/format.rb",
|
28
|
+
"lib/has_attributes.rb",
|
29
|
+
"lib/java_native2ascii.rb",
|
30
|
+
"lib/simply_useful.rb",
|
31
|
+
"simply_useful.gemspec",
|
32
|
+
"spec/bsearch_spec.rb",
|
33
|
+
"spec/core_ext/hash_spec.rb",
|
34
|
+
"spec/has_attributes_spec.rb",
|
35
|
+
"spec/java_native2ascii_spec.rb",
|
36
|
+
"spec/simply_useful_spec.rb",
|
37
|
+
"spec/spec.opts",
|
38
|
+
"spec/spec_helper.rb"
|
39
|
+
]
|
40
|
+
s.homepage = %q{http://github.com/maciej/simply_useful}
|
41
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubyforge_project = %q{simply_useful}
|
44
|
+
s.rubygems_version = %q{1.3.6}
|
45
|
+
s.summary = %q{A set of simply useful classes}
|
46
|
+
s.test_files = [
|
47
|
+
"spec/spec_helper.rb",
|
48
|
+
"spec/simply_useful_spec.rb",
|
49
|
+
"spec/core_ext/hash_spec.rb",
|
50
|
+
"spec/bsearch_spec.rb",
|
51
|
+
"spec/has_attributes_spec.rb",
|
52
|
+
"spec/java_native2ascii_spec.rb"
|
53
|
+
]
|
54
|
+
|
55
|
+
if s.respond_to? :specification_version then
|
56
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
57
|
+
s.specification_version = 3
|
58
|
+
|
59
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
60
|
+
else
|
61
|
+
end
|
62
|
+
else
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'bsearch'
|
3
|
+
|
4
|
+
describe Bsearch do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@sorted_array = [0,1,2,3,8,16,32,64,100]
|
8
|
+
@array_with_duplicates = [1,1,1,3,4,4,5,10,14,14,20]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should add BSearch to Array" do
|
12
|
+
# Were looking only for two most important methods here
|
13
|
+
@sorted_array.should respond_to(:bsearch)
|
14
|
+
@sorted_array.should respond_to(:bfind)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".bfind" do
|
18
|
+
|
19
|
+
it "should return the object when it finds it" do
|
20
|
+
@sorted_array.bfind{|x| x <=> 16}.should == 16
|
21
|
+
@sorted_array.bfind{|x| x <=> 100}.should == 100
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return nil if it doesn't find it" do
|
25
|
+
@sorted_array.bfind{|x| x <=> 4}.should == nil
|
26
|
+
@sorted_array.bfind{|x| x <=> -10}.should == nil
|
27
|
+
@sorted_array.bfind{|x| x <=> 120}.should == nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe ".bsearch" do
|
32
|
+
it "should return the first position of an object" do
|
33
|
+
@array_with_duplicates.bsearch{|x| x <=> 1}.should == 0
|
34
|
+
@array_with_duplicates.bsearch{|x| x <=> 3}.should == 3
|
35
|
+
@array_with_duplicates.bsearch{|x| x <=> 4}.should == 4
|
36
|
+
@array_with_duplicates.bsearch{|x| x <=> 14}.should == @array_with_duplicates.length-3
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".bsearch_last" do
|
41
|
+
it "should return the last position of an object" do
|
42
|
+
@array_with_duplicates.bsearch_last{|x| x <=> 1}.should == 2
|
43
|
+
@array_with_duplicates.bsearch_last{|x| x <=> 3}.should == 3
|
44
|
+
@array_with_duplicates.bsearch_last{|x| x <=> 4}.should == 5
|
45
|
+
@array_with_duplicates.bsearch_last{|x| x <=> 14}.should == @array_with_duplicates.length-2
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe ".bsearch_range" do
|
50
|
+
it "should return a range of matching objects" do
|
51
|
+
@array_with_duplicates.bsearch_range{|x| x <=> 1}.should == (0...3)
|
52
|
+
@array_with_duplicates.bsearch_range{|x| x <=> 3}.should == (3...4)
|
53
|
+
@array_with_duplicates.bsearch_range{|x| x <=> 4}.should == (4...6)
|
54
|
+
@array_with_duplicates.bsearch_range{|x| x <=> 14}.should ==
|
55
|
+
(@array_with_duplicates.length-3...@array_with_duplicates.length-1)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
require 'core_ext/hash'
|
3
|
+
|
4
|
+
describe SimplyUseful::CoreExtensions::Keys do
|
5
|
+
|
6
|
+
describe ".deep_symbolize_keys" do
|
7
|
+
it "should symbolize keys in a simple one-level hash" do
|
8
|
+
t = {"a" => "b", "c" => 2}
|
9
|
+
ta = t.deep_symbolize_keys
|
10
|
+
te = {:a => "b", :c => 2}
|
11
|
+
te.should == ta
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should symbolize keys in a two-level deep hash" do
|
15
|
+
t = {"a" => {"b" => "c"}}
|
16
|
+
ta = t.deep_symbolize_keys
|
17
|
+
te = {:a => {:b => "c"}}
|
18
|
+
te.should == ta
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'has_attributes'
|
3
|
+
|
4
|
+
class ObjectWithAttributes
|
5
|
+
include HasAttributes
|
6
|
+
|
7
|
+
attr_accessor :foo
|
8
|
+
|
9
|
+
def set_some_variables
|
10
|
+
@foo = "foo"; @bar = "bar"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe HasAttributes do
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
@object_with_attributes = ObjectWithAttributes.new
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should define attributes methods" do
|
21
|
+
@object_with_attributes.should respond_to("attributes", "attributes=")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be add an initialize method" do
|
25
|
+
@object_with_attributes = ObjectWithAttributes.new(:foo => "new value")
|
26
|
+
@object_with_attributes.foo.should == "new value"
|
27
|
+
end
|
28
|
+
|
29
|
+
describe ".attributes" do
|
30
|
+
it "should return all instance variables" do
|
31
|
+
@object_with_attributes.set_some_variables
|
32
|
+
@object_with_attributes.attributes.keys.should include(:foo, :bar)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return instance variables values" do
|
36
|
+
@object_with_attributes.set_some_variables
|
37
|
+
@object_with_attributes.attributes[:foo].should == "foo"
|
38
|
+
@object_with_attributes.foo = "foo2"
|
39
|
+
@object_with_attributes.attributes[:foo].should == "foo2"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ".attributes=" do
|
44
|
+
it "should set properties" do
|
45
|
+
attributes = {:foo => "value1"}
|
46
|
+
@object_with_attributes.attributes= attributes
|
47
|
+
@object_with_attributes.attributes.should == attributes
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise an error when you try to set a non-property attribute" do
|
51
|
+
attributes = {:foo => "value1", :bar => "value2"}
|
52
|
+
lambda { @object_with_attributes.attributes=(attributes) }.should raise_error
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'java_native2ascii'
|
3
|
+
|
4
|
+
class JavaNative2AsciiHelper
|
5
|
+
def native_ascii_pairs
|
6
|
+
[
|
7
|
+
["foo=ęéëèAZ中文", "foo=\\u0119\\u00e9\\u00eb\\u00e8AZ\\u4e2d\\u6587"],
|
8
|
+
["foo=\304\231", "foo=\\u0119"],
|
9
|
+
["bar=bbzz", "bar=bbzz"]
|
10
|
+
] # Believe me! Those characters are there (even if they are not in your fontset!
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe JavaNative2Ascii do
|
15
|
+
before(:all) do
|
16
|
+
@helper = JavaNative2AsciiHelper.new
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should convert from ascii to native" do
|
20
|
+
@helper.native_ascii_pairs.each do |native_ascii|
|
21
|
+
native,ascii = native_ascii
|
22
|
+
JavaNative2Ascii.ascii2native(ascii).should == native
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should convert from native to ascii" do
|
27
|
+
@helper.native_ascii_pairs.each do |native_ascii|
|
28
|
+
native,ascii = native_ascii
|
29
|
+
JavaNative2Ascii.native2ascii(native).should == ascii
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'simply_useful'
|
3
|
+
|
4
|
+
describe SimplyUseful do
|
5
|
+
it "should load" do
|
6
|
+
# if it gets here then it means no errors were raised during loading of the module (probably, right?)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "included modules" do
|
10
|
+
|
11
|
+
it "should define Hash.deep_symbolize_keys!" do
|
12
|
+
lambda { {"a" => "b"}.deep_symbolize_keys! }.should_not raise_error
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simply_useful
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 5
|
9
|
+
version: 0.1.5
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Maciej Bilas
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-19 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: A set of simply useful classes. Contains extensions to core Ruby classes.
|
22
|
+
email: maciej@inszy.org
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README
|
29
|
+
files:
|
30
|
+
- .gitignore
|
31
|
+
- MIT-LICENSE
|
32
|
+
- README
|
33
|
+
- Rakefile
|
34
|
+
- VERSION.yml
|
35
|
+
- lib/bsearch.rb
|
36
|
+
- lib/core_ext.rb
|
37
|
+
- lib/core_ext/hash.rb
|
38
|
+
- lib/format.rb
|
39
|
+
- lib/has_attributes.rb
|
40
|
+
- lib/java_native2ascii.rb
|
41
|
+
- lib/simply_useful.rb
|
42
|
+
- simply_useful.gemspec
|
43
|
+
- spec/bsearch_spec.rb
|
44
|
+
- spec/core_ext/hash_spec.rb
|
45
|
+
- spec/has_attributes_spec.rb
|
46
|
+
- spec/java_native2ascii_spec.rb
|
47
|
+
- spec/simply_useful_spec.rb
|
48
|
+
- spec/spec.opts
|
49
|
+
- spec/spec_helper.rb
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://github.com/maciej/simply_useful
|
52
|
+
licenses: []
|
53
|
+
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --charset=UTF-8
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project: simply_useful
|
76
|
+
rubygems_version: 1.3.6
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: A set of simply useful classes
|
80
|
+
test_files:
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
- spec/simply_useful_spec.rb
|
83
|
+
- spec/core_ext/hash_spec.rb
|
84
|
+
- spec/bsearch_spec.rb
|
85
|
+
- spec/has_attributes_spec.rb
|
86
|
+
- spec/java_native2ascii_spec.rb
|