tekido 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.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +188 -0
- data/Rakefile +11 -0
- data/USAGE_ja.md +153 -0
- data/lib/tekido.rb +7 -0
- data/lib/tekido/methods.rb +15 -0
- data/lib/tekido/methods/array.rb +48 -0
- data/lib/tekido/methods/boolean.rb +11 -0
- data/lib/tekido/methods/date.rb +39 -0
- data/lib/tekido/methods/numeric.rb +25 -0
- data/lib/tekido/methods/percentage.rb +26 -0
- data/lib/tekido/methods/string.rb +64 -0
- data/lib/tekido/version.rb +4 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/tekido/methods/array_spec.rb +81 -0
- data/spec/tekido/methods/boolean_spec.rb +36 -0
- data/spec/tekido/methods/date_spec.rb +131 -0
- data/spec/tekido/methods/numeric_spec.rb +138 -0
- data/spec/tekido/methods/percentage_spec.rb +102 -0
- data/spec/tekido/methods/string_spec.rb +273 -0
- data/tekido.gemspec +25 -0
- metadata +132 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "date"
|
3
|
+
|
4
|
+
module Tekido
|
5
|
+
module Methods
|
6
|
+
module ClassMethods
|
7
|
+
def date(arg = nil)
|
8
|
+
min, max = nil, nil
|
9
|
+
if arg.nil?
|
10
|
+
min, max = Date.new(1, 1, 1), Date.new(9999, 12, 31)
|
11
|
+
elsif arg.is_a?(Integer)
|
12
|
+
min, max = Date.new(arg, 1, 1), Date.new(arg, 12, 31)
|
13
|
+
elsif arg.is_a?(Range)
|
14
|
+
if arg.min.is_a?(Integer)
|
15
|
+
min, max = Date.new(arg.min, 1, 1), Date.new(arg.max, 12, 31)
|
16
|
+
elsif arg.min.is_a?(Date)
|
17
|
+
min, max = arg.min, arg.max
|
18
|
+
end
|
19
|
+
end
|
20
|
+
min ? min + integer((max - min).to_i) : nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def birthday(arg = nil)
|
24
|
+
if arg.nil?
|
25
|
+
min = (Date.today << 12 * 101) + 1
|
26
|
+
date(min..Date.today)
|
27
|
+
elsif arg.is_a?(Integer)
|
28
|
+
min = (Date.today << 12 * (arg + 1)) + 1
|
29
|
+
max = Date.today << 12 * arg
|
30
|
+
date(min..max)
|
31
|
+
elsif arg.is_a?(Range) && arg.min.is_a?(Integer)
|
32
|
+
min = (Date.today << 12 * (arg.max + 1)) + 1
|
33
|
+
max = Date.today << 12 * arg.min
|
34
|
+
date(min..max)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Tekido
|
3
|
+
module Methods
|
4
|
+
module ClassMethods
|
5
|
+
def integer(arg = nil)
|
6
|
+
if arg.nil?
|
7
|
+
max = 2 ** 30 - 1
|
8
|
+
rand(0..max)
|
9
|
+
else
|
10
|
+
rand(arg).to_i
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def float(arg = nil)
|
15
|
+
if arg.nil?
|
16
|
+
rand
|
17
|
+
elsif arg.is_a?(Range)
|
18
|
+
rand(arg.min.to_f..arg.max.to_f)
|
19
|
+
else
|
20
|
+
rand * arg.to_f
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Tekido
|
3
|
+
module Methods
|
4
|
+
module ClassMethods
|
5
|
+
def percent
|
6
|
+
percent_as(:integer)
|
7
|
+
end
|
8
|
+
|
9
|
+
def percent_as(type)
|
10
|
+
per = rand(0.0..100.0)
|
11
|
+
case type
|
12
|
+
when :float
|
13
|
+
per
|
14
|
+
when :integer
|
15
|
+
per.to_i
|
16
|
+
when :mo5
|
17
|
+
per.to_i / 5 * 5
|
18
|
+
when :deca, :mo10
|
19
|
+
per.to_i / 10 * 10
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Tekido
|
3
|
+
module Methods
|
4
|
+
module ClassMethods
|
5
|
+
UPPER_CHARS = ('A'..'Z').to_a
|
6
|
+
LOWER_CHARS = ('a'..'z').to_a
|
7
|
+
NUMBER_CHARS = ('0'..'9').to_a
|
8
|
+
EXAMPLE_DOMAINS = ["example.com", "exmple.net", "example.org"] +
|
9
|
+
["example.jp", "example.co.jp", "example.ne.jp"] +
|
10
|
+
(0..9).map { |i| ["example#{i}.jp", "example#{i}.co.jp", "example#{i}.ne.jp"] }.flatten
|
11
|
+
|
12
|
+
def string(options = {})
|
13
|
+
size = size_from(options[:size])
|
14
|
+
chars = chars_from(options[:chars], *options[:components])
|
15
|
+
|
16
|
+
"".tap do |str|
|
17
|
+
size.times do
|
18
|
+
str << chars.sample
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def email(*bases)
|
24
|
+
local = string(size: 3..32, components: [:lower, :number])
|
25
|
+
domains = bases.empty? ? EXAMPLE_DOMAINS : bases.map { |b| b.index("@") ? b[b.index('@').to_i+1..b.size] : b }
|
26
|
+
"#{local}@#{domains.sample}"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def size_from(option)
|
31
|
+
base_size = integer(1..255)
|
32
|
+
if option.nil?
|
33
|
+
base_size
|
34
|
+
elsif option.is_a?(Integer)
|
35
|
+
option > 0 ? option : base
|
36
|
+
elsif option.is_a?(Range)
|
37
|
+
new_size = integer(option)
|
38
|
+
new_size > 0 ? new_size : base
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def chars_from(chars, *components)
|
43
|
+
return chars if chars.is_a?(Array) && !chars.empty?
|
44
|
+
|
45
|
+
base_chars = UPPER_CHARS + LOWER_CHARS + NUMBER_CHARS
|
46
|
+
return base_chars if components.nil? || components.empty?
|
47
|
+
|
48
|
+
chars = []
|
49
|
+
if components.include?(:upper)
|
50
|
+
chars += UPPER_CHARS
|
51
|
+
end
|
52
|
+
if components.include?(:lower)
|
53
|
+
chars += LOWER_CHARS
|
54
|
+
end
|
55
|
+
if components.include?(:number)
|
56
|
+
chars += NUMBER_CHARS
|
57
|
+
end
|
58
|
+
chars.empty? ? base_chars : chars
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
3
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
4
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
5
|
+
# loaded once.
|
6
|
+
#
|
7
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
8
|
+
require "coveralls"
|
9
|
+
require "simplecov"
|
10
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
11
|
+
SimpleCov.start do
|
12
|
+
add_filter '/spec/'
|
13
|
+
add_filter '/bundle/'
|
14
|
+
end
|
15
|
+
require "tekido"
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
19
|
+
config.run_all_when_everything_filtered = true
|
20
|
+
config.filter_run :focus
|
21
|
+
|
22
|
+
# Run specs in random order to surface order dependencies. If you find an
|
23
|
+
# order dependency and want to debug it, you can fix the order by providing
|
24
|
+
# the seed, which is printed after each run.
|
25
|
+
# --seed 1234
|
26
|
+
config.order = 'random'
|
27
|
+
end
|
28
|
+
|
29
|
+
TRY_COUNT = 100000
|
30
|
+
ACCIDENTAL_RATE = 0.01
|
31
|
+
ACCIDENTAL_COUNT = TRY_COUNT * ACCIDENTAL_RATE
|
32
|
+
|
33
|
+
def valid_count(percent)
|
34
|
+
TRY_COUNT / 100 * percent
|
35
|
+
end
|
36
|
+
|
37
|
+
def expected_count(range_size = nil)
|
38
|
+
total = range_size && TRY_COUNT > range_size ? range_size : TRY_COUNT
|
39
|
+
(total * 0.9).to_i
|
40
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe Tekido::Methods do
|
5
|
+
describe "array methods" do
|
6
|
+
describe ".list" do
|
7
|
+
context "when size is #{TRY_COUNT}, values are :one, :two, :three and :four" do
|
8
|
+
let(:list) { Tekido.list(TRY_COUNT, [:one, :two, :three, :four]) }
|
9
|
+
it "returns array" do
|
10
|
+
expect(list).to be_an(Array)
|
11
|
+
end
|
12
|
+
it "returned array size is #{TRY_COUNT}" do
|
13
|
+
expect(list.size).to eq TRY_COUNT
|
14
|
+
end
|
15
|
+
it "returned array includes about 25% :one" do
|
16
|
+
expect(list.count { |item| item == :one }).to be_within(valid_count(25)).of(ACCIDENTAL_COUNT)
|
17
|
+
end
|
18
|
+
it "returned array includes about 25% :two" do
|
19
|
+
expect(list.count { |item| item == :two }).to be_within(valid_count(25)).of(ACCIDENTAL_COUNT)
|
20
|
+
end
|
21
|
+
it "returned array includes about 25% :three" do
|
22
|
+
expect(list.count { |item| item == :three }).to be_within(valid_count(25)).of(ACCIDENTAL_COUNT)
|
23
|
+
end
|
24
|
+
it "returned array includes about 25% :four" do
|
25
|
+
expect(list.count { |item| item == :four }).to be_within(valid_count(25)).of(ACCIDENTAL_COUNT)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
context "when size is #{TRY_COUNT}, values are defined with ratio (one: 11.1, two: 22.2, three: 33.3, four: 33.4)" do
|
29
|
+
let(:list) { Tekido.list(TRY_COUNT, one: 11.1, two: 22.2, three: 33.3, four: 33.4) }
|
30
|
+
it "returns array" do
|
31
|
+
expect(list).to be_an(Array)
|
32
|
+
end
|
33
|
+
it "returned array size is #{TRY_COUNT}" do
|
34
|
+
expect(list.size).to eq TRY_COUNT
|
35
|
+
end
|
36
|
+
it "returned array includes about 11.1% :one" do
|
37
|
+
expect(list.count { |item| item == :one }).to be_within(valid_count(11.1)).of(ACCIDENTAL_COUNT)
|
38
|
+
end
|
39
|
+
it "returned array includes about 22.2% :two" do
|
40
|
+
expect(list.count { |item| item == :two }).to be_within(valid_count(22.2)).of(ACCIDENTAL_COUNT)
|
41
|
+
end
|
42
|
+
it "returned array includes about 33.3% :three" do
|
43
|
+
expect(list.count { |item| item == :three }).to be_within(valid_count(33.3)).of(ACCIDENTAL_COUNT)
|
44
|
+
end
|
45
|
+
it "returned array includes about 33.4% :four" do
|
46
|
+
expect(list.count { |item| item == :four }).to be_within(valid_count(33.4)).of(ACCIDENTAL_COUNT)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
context "when size is #{TRY_COUNT}, values are defined with ratio (one: 10, two: 20, three: 30)" do
|
50
|
+
let(:list) { Tekido.list(TRY_COUNT, one: 10, two: 20, three: 30) }
|
51
|
+
it "returns array" do
|
52
|
+
expect(list).to be_an(Array)
|
53
|
+
end
|
54
|
+
it "returned array size is #{TRY_COUNT}" do
|
55
|
+
expect(list.size).to eq TRY_COUNT
|
56
|
+
end
|
57
|
+
it "returned array includes about 10% :one" do
|
58
|
+
expect(list.count { |item| item == :one }).to be_within(valid_count(10)).of(ACCIDENTAL_COUNT)
|
59
|
+
end
|
60
|
+
it "returned array includes about 20% :two" do
|
61
|
+
expect(list.count { |item| item == :two }).to be_within(valid_count(20)).of(ACCIDENTAL_COUNT)
|
62
|
+
end
|
63
|
+
it "returned array includes about 30% :three" do
|
64
|
+
expect(list.count { |item| item == :three }).to be_within(valid_count(30)).of(ACCIDENTAL_COUNT)
|
65
|
+
end
|
66
|
+
it "returned array includes about 40% nil" do
|
67
|
+
expect(list.count { |item| item.nil? }).to be_within(valid_count(40)).of(ACCIDENTAL_COUNT)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
context "when invalid value_defs " do
|
71
|
+
let(:list) { Tekido.list(TRY_COUNT, "aaaa") }
|
72
|
+
it "returns array" do
|
73
|
+
expect(list).to be_an(Array)
|
74
|
+
end
|
75
|
+
it "returned array is filled by nil" do
|
76
|
+
expect(list.any?).to eq false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe Tekido::Methods do
|
5
|
+
describe "boolean methods"do
|
6
|
+
describe ".yes?" do
|
7
|
+
context "with no argument" do
|
8
|
+
it "returns true with a probability of about 50 percent" do
|
9
|
+
i = 0
|
10
|
+
TRY_COUNT.times do
|
11
|
+
i += 1 if Tekido.yes?
|
12
|
+
end
|
13
|
+
expect(i).to be_within(TRY_COUNT / 2).of(ACCIDENTAL_COUNT)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context "with integer argument" do
|
17
|
+
it "returns true with a probability of about given percent" do
|
18
|
+
i = 0
|
19
|
+
TRY_COUNT.times do
|
20
|
+
i += 1 if Tekido.yes?(80)
|
21
|
+
end
|
22
|
+
expect(i).to be_within(valid_count(80)).of(ACCIDENTAL_COUNT)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
context "with invalid argument" do
|
26
|
+
it "bahaves in the same way of no argument" do
|
27
|
+
i = 0
|
28
|
+
TRY_COUNT.times do
|
29
|
+
i += 1 if Tekido.yes?("99")
|
30
|
+
end
|
31
|
+
expect(i).to be_within(TRY_COUNT / 2).of(ACCIDENTAL_COUNT)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "date"
|
4
|
+
|
5
|
+
describe Tekido::Methods do
|
6
|
+
describe "date methods" do
|
7
|
+
describe ".date" do
|
8
|
+
context "with no argument" do
|
9
|
+
it "returns Date" do
|
10
|
+
expect(Tekido.date).to be_a(Date)
|
11
|
+
end
|
12
|
+
it "at random uniformly" do
|
13
|
+
min, max = Date.new(1, 1, 1), Date.new(9999, 12, 31)
|
14
|
+
list = TRY_COUNT.times.map { Tekido.date }
|
15
|
+
expect(list.uniq.size).to be >= expected_count(max - min)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
context "with integer argument" do
|
19
|
+
let(:date) { Tekido.date(1999) }
|
20
|
+
it "returns Date" do
|
21
|
+
expect(date).to be_a(Date)
|
22
|
+
end
|
23
|
+
it "at random uniformly" do
|
24
|
+
min, max = Date.new(1999, 1, 1), Date.new(1999, 12, 31)
|
25
|
+
list = TRY_COUNT.times.map { Tekido.date(1999) }
|
26
|
+
expect(list.uniq.size).to be >= expected_count(max - min)
|
27
|
+
end
|
28
|
+
it "returned Date's year is 1999" do
|
29
|
+
expect(date.year).to eq 1999
|
30
|
+
end
|
31
|
+
end
|
32
|
+
context "with integer range argument" do
|
33
|
+
it "returns Date" do
|
34
|
+
expect(Tekido.date(1999..2010)).to be_a(Date)
|
35
|
+
end
|
36
|
+
it "at random uniformly" do
|
37
|
+
min, max = Date.new(1999, 1, 1), Date.new(2010, 12, 31)
|
38
|
+
list = TRY_COUNT.times.map { Tekido.date(1999..2010) }
|
39
|
+
expect(list.uniq.size).to be >= expected_count(max - min)
|
40
|
+
end
|
41
|
+
it "returned Date's year is included in argument" do
|
42
|
+
TRY_COUNT.times do
|
43
|
+
expect(1999..2010).to include(Tekido.date(1999..2010).year)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
context "with Date range argument" do
|
48
|
+
let(:min) { Date.new(1999, 2, 21) }
|
49
|
+
let(:max) { Date.new(2013, 10, 11)}
|
50
|
+
it "returns Date" do
|
51
|
+
expect(Tekido.date(min..max)).to be_a(Date)
|
52
|
+
end
|
53
|
+
it "at random uniformly" do
|
54
|
+
list = TRY_COUNT.times.map { Tekido.date(min..max) }
|
55
|
+
expect(list.uniq.size).to be >= expected_count(max - min)
|
56
|
+
end
|
57
|
+
it "returned Date is included in argument" do
|
58
|
+
TRY_COUNT.times do
|
59
|
+
expect(min..max).to cover(Tekido.date(min..max))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
context "with invalid argument" do
|
64
|
+
it "returns nil" do
|
65
|
+
expect(Tekido.date("2010")).to be_nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
describe ".birthday" do
|
70
|
+
context "with no argument" do
|
71
|
+
it "returns Date" do
|
72
|
+
expect(Tekido.birthday).to be_a(Date)
|
73
|
+
end
|
74
|
+
it "at random uniformly" do
|
75
|
+
min = (Date.today << 12 * 101) + 1
|
76
|
+
list = TRY_COUNT.times.map { Tekido.birthday }
|
77
|
+
expect(list.uniq.size).to be >= expected_count(Date.today - min)
|
78
|
+
end
|
79
|
+
it "returned Date satisfy that current age is more than 0 and less than 100" do
|
80
|
+
min = (Date.today << 12 * 101) + 1
|
81
|
+
TRY_COUNT.times do
|
82
|
+
expect(min..Date.today).to cover(Tekido.birthday)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
context "with integer argument" do
|
87
|
+
let(:age) { 28 }
|
88
|
+
it "returns Date" do
|
89
|
+
expect(Tekido.birthday(age)).to be_a(Date)
|
90
|
+
end
|
91
|
+
it "at random uniformly" do
|
92
|
+
min = (Date.today << 12 * (age + 1)) + 1
|
93
|
+
max = Date.today << 12 * age
|
94
|
+
list = TRY_COUNT.times.map { Tekido.birthday }
|
95
|
+
expect(list.uniq.size).to be >= expected_count(max - min)
|
96
|
+
end
|
97
|
+
it "given integer is age" do
|
98
|
+
min = (Date.today << 12 * (age + 1)) + 1
|
99
|
+
max = Date.today << 12 * age
|
100
|
+
TRY_COUNT.times do
|
101
|
+
expect(min..max).to cover(Tekido.birthday(age))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
context "with integer range argument" do
|
106
|
+
it "returns Date" do
|
107
|
+
expect(Tekido.birthday(20..25)).to be_a(Date)
|
108
|
+
end
|
109
|
+
it "at random uniformly" do
|
110
|
+
min = (Date.today << 12 * 26) + 1
|
111
|
+
max = Date.today << 12 * 20
|
112
|
+
list = TRY_COUNT.times.map { Tekido.birthday }
|
113
|
+
expect(list.uniq.size).to be >= expected_count(max - min)
|
114
|
+
end
|
115
|
+
it "returned Date satisfy that current age is included in argument" do
|
116
|
+
min = (Date.today << 12 * 26) + 1
|
117
|
+
max = Date.today << 12 * 20
|
118
|
+
TRY_COUNT.times do
|
119
|
+
expect(min..max).to cover(Tekido.birthday(20..25))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
context "with invalid argument" do
|
124
|
+
it "returns nil" do
|
125
|
+
expect(Tekido.birthday("30")).to be_nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|