ish 0.0.1
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/ish.rb +103 -0
- data/lib/ish/fixnum.rb +2 -0
- data/lib/ish/number.rb +9 -0
- data/lib/ish/time.rb +9 -0
- data/lib/ish/version.rb +3 -0
- data/test/ish_test.rb +116 -0
- data/test/test_helper.rb +52 -0
- metadata +76 -0
data/lib/ish.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'ish/version'
|
2
|
+
require 'ish/number'
|
3
|
+
require 'ish/time'
|
4
|
+
|
5
|
+
|
6
|
+
module Ish
|
7
|
+
|
8
|
+
def self.default_precision
|
9
|
+
@default_precision ||= 0.05
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.default_precision=(val)
|
13
|
+
@default_precision = val
|
14
|
+
end
|
15
|
+
|
16
|
+
# 5 min = 300 sec
|
17
|
+
def self.default_time_offset_seconds
|
18
|
+
@default_time_offset_seconds ||= 300
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.default_time_offset_seconds=(val)
|
22
|
+
@default_time_offset_seconds = val
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.fuzzify(num, opts={})
|
26
|
+
raise "argument must be a number!" if !num.respond_to?(:abs)
|
27
|
+
|
28
|
+
offset = offset_from_opts(num, opts)
|
29
|
+
|
30
|
+
# min offset for fixnum is 1
|
31
|
+
offset = 1 if num.is_a?(Fixnum) && offset.abs < 1
|
32
|
+
|
33
|
+
rand_offset = if num.is_a? Fixnum
|
34
|
+
rand_integer_offset(offset)
|
35
|
+
else
|
36
|
+
rand_float_offset(offset)
|
37
|
+
end
|
38
|
+
|
39
|
+
result = num + rand_offset
|
40
|
+
|
41
|
+
# Fixnum in, fixnum out, aka FIFO
|
42
|
+
if num.is_a? Fixnum
|
43
|
+
result.to_i
|
44
|
+
else
|
45
|
+
result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.fuzzify_time(time, opts={})
|
50
|
+
raise 'argument must be a time!' if !time.is_a? Time
|
51
|
+
offset = time_offset_from_opts(opts)
|
52
|
+
rand_offset = rand_integer_offset(offset)
|
53
|
+
time + rand_offset
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.rand_integer_offset(offset)
|
57
|
+
range = offset + 1 # because rand(1) only returns 0
|
58
|
+
term = rand(range)
|
59
|
+
term *= -1 if rand(2) == 0 # minus half the time
|
60
|
+
term
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.rand_float_offset(offset)
|
64
|
+
term = offset * rand # rand is between 0.0 and 1.0
|
65
|
+
term *= -1 if rand(2) == 0 # minus half the time
|
66
|
+
term
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def self.offset_from_opts(num, opts={})
|
72
|
+
precision = opts[:precision] || default_precision
|
73
|
+
|
74
|
+
if offset = opts[:offset]
|
75
|
+
raise ":offset must be a number!" if !offset.respond_to?(:abs)
|
76
|
+
offset.abs
|
77
|
+
else
|
78
|
+
num.abs * precision
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.time_offset_from_opts(opts={})
|
83
|
+
offset = opts[:offset] || default_time_offset_seconds
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
class Fixnum
|
89
|
+
include Ish::Number
|
90
|
+
end
|
91
|
+
|
92
|
+
class Float
|
93
|
+
include Ish::Number
|
94
|
+
end
|
95
|
+
|
96
|
+
class Time
|
97
|
+
include Ish::Time
|
98
|
+
end
|
99
|
+
|
100
|
+
class DateTime
|
101
|
+
include Ish::Time
|
102
|
+
end
|
103
|
+
|
data/lib/ish/fixnum.rb
ADDED
data/lib/ish/number.rb
ADDED
data/lib/ish/time.rb
ADDED
data/lib/ish/version.rb
ADDED
data/test/ish_test.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
$:.unshift '.'; require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class IshTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_default_precission
|
6
|
+
assert_equal 0.05, Ish.default_precision
|
7
|
+
Ish.default_precision = 0.01
|
8
|
+
assert_equal 0.01, Ish.default_precision
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_fuzzify_fixnum
|
12
|
+
assert_returns_all([19, 20, 21]) do
|
13
|
+
Ish.fuzzify(20)
|
14
|
+
end
|
15
|
+
|
16
|
+
assert_always_between(19, 21) do
|
17
|
+
Ish.fuzzify(20)
|
18
|
+
end
|
19
|
+
|
20
|
+
assert_always_between(90, 110) do
|
21
|
+
Ish.fuzzify(100)
|
22
|
+
end
|
23
|
+
|
24
|
+
assert_returns_all([0, 1, 2]) do
|
25
|
+
Ish.fuzzify(1)
|
26
|
+
end
|
27
|
+
|
28
|
+
assert_returns_all([-1, 0, 1]) do
|
29
|
+
Ish.fuzzify(0)
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_returns_all([-2, -1, 0]) do
|
33
|
+
Ish.fuzzify(-1)
|
34
|
+
end
|
35
|
+
|
36
|
+
assert_returns_all([-21, -20, -19]) do
|
37
|
+
Ish.fuzzify(-20)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_fuzzify_fixnum_with_custom_offset
|
42
|
+
assert_returns_all([-2, -1, 0, 1, 2]) do
|
43
|
+
Ish.fuzzify(0, offset: 2)
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_returns_all([47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]) do
|
47
|
+
Ish.fuzzify(52, offset: 5)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_fuzzify_fixnum_with_custom_precision
|
52
|
+
assert_returns_all([-98, -99, -100, -101, -102]) do
|
53
|
+
Ish.fuzzify(-100, precision: 0.02)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_fuzzify_float
|
58
|
+
assert_always_between(0.95, 1.05) do
|
59
|
+
Ish.fuzzify(1.0)
|
60
|
+
end
|
61
|
+
|
62
|
+
assert_always_between(-1.05, -0.95) do
|
63
|
+
Ish.fuzzify(-1.0)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_fuzzify_float_with_custom_offset
|
68
|
+
assert_always_between(90, 110) do
|
69
|
+
Ish.fuzzify(100.0, offset: 10)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_fuzzify_float_with_custom_precision
|
74
|
+
assert_always_between(90, 110) do
|
75
|
+
Ish.fuzzify(100.0, offset: 0.10)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_fixnum
|
80
|
+
assert_returns_all([1, 2, 3]) do
|
81
|
+
2.ish
|
82
|
+
end
|
83
|
+
|
84
|
+
assert_returns_all([-112, -111, -110]) do
|
85
|
+
-111.ish(offset: 1)
|
86
|
+
end
|
87
|
+
|
88
|
+
assert_returns_all([2, 3, 4, 5, 6]) do
|
89
|
+
4.ish(precision: 0.5)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_float
|
94
|
+
assert_always_between(19, 21) do
|
95
|
+
20.0.ish
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_time
|
100
|
+
now = Time.now
|
101
|
+
five_min_ago = now - 300
|
102
|
+
five_min_from_now = now + 300
|
103
|
+
|
104
|
+
assert_always_between(five_min_ago, five_min_from_now) do
|
105
|
+
now.ish
|
106
|
+
end
|
107
|
+
|
108
|
+
one_min_ago = now - 60
|
109
|
+
one_min_from_now = now + 60
|
110
|
+
|
111
|
+
assert_always_between(one_min_ago, one_min_from_now) do
|
112
|
+
now.ish(offset: 60)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
require 'rubygems'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'active_support/all'
|
5
|
+
require 'ish'
|
6
|
+
|
7
|
+
|
8
|
+
INITIAL_DEFAULT_PRECISION = Ish.default_precision
|
9
|
+
SAMPLE_RATE = 200
|
10
|
+
|
11
|
+
class Test::Unit::TestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
Ish.default_precision = INITIAL_DEFAULT_PRECISION
|
15
|
+
end
|
16
|
+
|
17
|
+
def assert_returns_all(arr)
|
18
|
+
seen = arr.clone
|
19
|
+
unexpected = []
|
20
|
+
SAMPLE_RATE.times do
|
21
|
+
val = yield
|
22
|
+
# puts val
|
23
|
+
if arr.include? val
|
24
|
+
seen.delete(val)
|
25
|
+
else
|
26
|
+
unexpected << val
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
unexpected.uniq!
|
31
|
+
|
32
|
+
if seen.length > 0
|
33
|
+
assert false, "#{arr} values were never returned"
|
34
|
+
elsif unexpected.length > 0
|
35
|
+
assert false, "#{unexpected} values were returned unexpectedly"
|
36
|
+
else
|
37
|
+
assert true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def assert_always_between(low, high)
|
42
|
+
SAMPLE_RATE.times do
|
43
|
+
val = yield
|
44
|
+
# puts val
|
45
|
+
if val < low || val > high
|
46
|
+
assert false, "#{val} was not between #{low} and #{high}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
assert true
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ish
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Zachary Kloepping
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70118388176580 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70118388176580
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
requirement: &70118388176100 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70118388176100
|
36
|
+
description:
|
37
|
+
email:
|
38
|
+
executables: []
|
39
|
+
extensions: []
|
40
|
+
extra_rdoc_files: []
|
41
|
+
files:
|
42
|
+
- lib/ish/fixnum.rb
|
43
|
+
- lib/ish/number.rb
|
44
|
+
- lib/ish/time.rb
|
45
|
+
- lib/ish/version.rb
|
46
|
+
- lib/ish.rb
|
47
|
+
- test/ish_test.rb
|
48
|
+
- test/test_helper.rb
|
49
|
+
homepage: https://github.com/spilliton/ish
|
50
|
+
licenses:
|
51
|
+
- MIT
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.15
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Adds random fuzzy helper methods to various ruby classes
|
74
|
+
test_files:
|
75
|
+
- test/ish_test.rb
|
76
|
+
- test/test_helper.rb
|