michel-randexp 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,114 @@
1
+ class Randexp
2
+ class Reducer
3
+ def self.reduce(sexp, quantity = nil)
4
+ send(sexp.first, sexp[1..-1], quantity)
5
+ end
6
+
7
+ class << self
8
+ alias_method :[], :reduce
9
+ end
10
+
11
+ def self.quantify(sexp, old_quantity)
12
+ reduce(*sexp)
13
+ end
14
+
15
+ def self.random(sexpish, quantity)
16
+ case s = sexpish.first
17
+ when :w then char(quantity)
18
+ when :s then whitespace(quantity)
19
+ when :d then digit(quantity)
20
+ when :"." then any(quantity)
21
+ else randgen(s, quantity)
22
+ end
23
+ end
24
+
25
+ def self.literal(cell, quantity = nil)
26
+ case quantity
27
+ when :'?' then ([''] + cell).pick * ''
28
+ when :+, :'+?' then raise "Sorry, \"#{cell * ''}+\" is too vague, try setting a range: \"#{cell * ''}{1,3}\""
29
+ when :*, :'*?' then raise "Sorry, \"#{cell * ''}*\" is too vague, try setting a range: \"#{cell * ''}{0,3}\""
30
+ when Range then quantity.pick.of { cell * '' } * ''
31
+ when Integer then quantity.of { cell * '' } * ''
32
+ when nil then cell * ''
33
+ end
34
+ end
35
+
36
+ def self.intersection(cell, quantity)
37
+ case quantity
38
+ when :'?' then ['', cell.map {|s| reduce(s)}.pick].pick
39
+ when :+, :'+?' then raise "Sorry, \"((...)|(...))+\" is too vague, try setting a range: \"((...)|(...)){1, 3}\""
40
+ when :*, :'*?' then raise "Sorry, \"((...)|(...))*\" is too vague, try setting a range: \"((...)|(...)){0, 3}\""
41
+ when Range then quantity.pick.of { cell.map {|s| reduce(s)}.pick } * ''
42
+ when Integer then quantity.of { cell.map {|s| reduce(s)}.pick } * ''
43
+ when nil then cell.map {|s| reduce(s)}.pick
44
+ end
45
+ end
46
+
47
+ def self.union(cell, quantity)
48
+ case quantity
49
+ when :'?' then ['', cell.map {|s| reduce(s)} * ''].pick
50
+ when :+, :'+?' then raise "Sorry, \"(...)+\" is too vague, try setting a range: \"(...){1, 3}\""
51
+ when :*, :'*?' then raise "Sorry, \"(...)*\" is too vague, try setting a range: \"(...){0, 3}\""
52
+ when Range then quantity.pick.of { cell.map {|s| reduce(s)} * '' } * ''
53
+ when Integer then quantity.of { cell.map {|s| reduce(s)} * '' } * ''
54
+ when nil then cell.map {|s| reduce(s)} * ''
55
+ end
56
+ end
57
+
58
+ def self.char(quantity)
59
+ case quantity
60
+ when :'?' then ['', Randgen.char].pick
61
+ when :+, :'+?' then Randgen.word
62
+ when :*, :'*?' then ['', Randgen.word].pick
63
+ when Range then Randgen.word(:length => quantity.pick)
64
+ when 1, nil then Randgen.char
65
+ when Integer then Randgen.word(:length => quantity)
66
+ end
67
+ end
68
+
69
+ def self.any(quantity)
70
+ case quantity
71
+ when :'?' then ['', Randgen.any].pick
72
+ when :+, :'+?' then Randgen.any
73
+ when :*, :'*?' then ['', Randgen.any].pick
74
+ when Range then Randgen.any(:length => quantity.pick)
75
+ when 1, nil then Randgen.any
76
+ when Integer then Randgen.any(:length => quantity)
77
+ end
78
+ end
79
+
80
+ def self.whitespace(quantity)
81
+ case quantity
82
+ when :'?' then ['', Randgen.whitespace].pick
83
+ when :+, :'+?' then raise "Sorry, \"\\s+\" is too vague, try setting a range: \"\\s{1, 5}\""
84
+ when :*, :'*?' then raise "Sorry, \"\\s*\" is too vague, try setting a range: \"\\s{0, 5}\""
85
+ when Range then quantity.pick.of { Randgen.whitespace } * ''
86
+ when Integer then quantity.of { Randgen.whitespace } * ''
87
+ when nil then Randgen.whitespace
88
+ end
89
+ end
90
+
91
+ def self.digit(quantity)
92
+ case quantity
93
+ when :'?' then ['', Randgen.digit].pick
94
+ when :+, :'+?' then raise "Sorry, \"\\d+\" is too vague, try setting a range: \"\\d{1, 5}\""
95
+ when :*, :'*?' then raise "Sorry, \"\\d*\" is too vague, try setting a range: \"\\d{0, 5}\""
96
+ when Range then quantity.pick.of { Randgen.digit } * ''
97
+ when Integer then quantity.of { Randgen.digit } * ''
98
+ when nil then Randgen.digit
99
+ end
100
+ end
101
+
102
+ def self.randgen(args, quantity)
103
+ method_name = *args
104
+ case quantity
105
+ when :'?' then ['', Randgen.send(method_name, :length => 1)].pick
106
+ when :+, :'+?' then Randgen.send(method_name)
107
+ when :*, :'*?' then ['', Randgen.send(method_name)].pick
108
+ when Range then Randgen.send(method_name, :length => quantity.pick)
109
+ when 1, nil then Randgen.send(method_name)
110
+ when Integer then Randgen.send(method_name, :length => quantity)
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,23 @@
1
+ class RealName
2
+
3
+ def self.load_female_first_names
4
+ dir = File.dirname(__FILE__)
5
+ if File.exists?("#{dir}/../../../wordlists/female_names")
6
+ File.read("#{dir}/../../../wordlists/female_names").split
7
+ else
8
+ raise "words file not found"
9
+ end
10
+ end
11
+
12
+ def self.female_first_names(options = {})
13
+ if options.has_key?(:length)
14
+ female_first_names_by_length[options[:length]]
15
+ else
16
+ @@female_first_names ||= load_female_first_names
17
+ end
18
+ end
19
+
20
+ def self.female_first_names_by_length
21
+ @@female_first_names_by_length ||= female_first_names.inject({}) {|h, w| (h[w.size] ||= []) << w; h }
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ class RealName
2
+
3
+ def self.load_male_first_names
4
+ dir = File.dirname(__FILE__)
5
+ if File.exists?("#{dir}/../../../wordlists/male_names")
6
+ File.read("#{dir}/../../../wordlists/male_names").split
7
+ else
8
+ raise "words file not found"
9
+ end
10
+ end
11
+
12
+ def self.male_first_names(options = {})
13
+ if options.has_key?(:length)
14
+ male_first_names_by_length[options[:length]]
15
+ else
16
+ @@male_first_names ||= load_male_first_names
17
+ end
18
+ end
19
+
20
+ def self.male_first_names_by_length
21
+ @@male_first_names_by_length ||= male_first_names.inject({}) {|h, w| (h[w.size] ||= []) << w; h }
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ class RealName
2
+ def self.load_surnames
3
+ dir = File.dirname(__FILE__)
4
+ if File.exists?("#{dir}/../../../wordlists/surnames")
5
+ File.read("#{dir}/../../../wordlists/surnames").split
6
+ else
7
+ raise "words file not found"
8
+ end
9
+ end
10
+
11
+ def self.surnames(options = {})
12
+ if options.has_key?(:length)
13
+ surnames_by_length[options[:length]]
14
+ else
15
+ @@surnames ||= load_surnames
16
+ end
17
+ end
18
+
19
+ def self.surnames_by_length
20
+ @@surnames_by_length ||= surnames.inject({}) {|h, w| (h[w.size] ||= []) << w; h }
21
+ end
22
+
23
+ def self.first_names(options)
24
+ case options[:gender].to_s
25
+ when /^male/i
26
+ male_first_names(options)
27
+ when /^female/i
28
+ female_first_names(options)
29
+ else
30
+ [male_first_names(options), female_first_names(options)].pick
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,204 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "#{'*' * 80}\nRegression Specs:" do
4
+ it "/abcd/ => 'abcd'" do
5
+ 100.times do
6
+ /abcd/.gen.should == 'abcd'
7
+ end
8
+ end
9
+
10
+ it "/(abcd)|(defg)/ => ['abcd', 'defg']" do
11
+ 100.times do
12
+ ['abcd', 'defg'].should include(/(abcd)|(defg)/.gen)
13
+ end
14
+ end
15
+
16
+ it "/(abcd)|(defg)|(hijk)/ => ['abcd', 'defg', 'hijk']" do
17
+ 100.times do
18
+ ['abcd', 'defg', 'hijk'].should include(/(abcd)|(defg)|(hijk)/.gen)
19
+ end
20
+ end
21
+
22
+ it "/((abcd)|(defg))|(hijk)/ => ['abcd', 'defg', 'hijk']" do
23
+ 100.times do
24
+ ['abcd', 'defg', 'hijk'].should include(/((abcd)|(defg))|(hijk)/.gen)
25
+ end
26
+ end
27
+
28
+ it "/(abcd)|((defg)|(hijk))/ => ['abcd', 'defg', 'hijk']" do
29
+ 100.times do
30
+ ['abcd', 'defg', 'hijk'].should include(/(abcd)|((defg)|(hijk))/.gen)
31
+ end
32
+ end
33
+
34
+ it "/(abc)def(ghi)/ => 'abcdefghi'" do
35
+ 100.times do
36
+ /(abc)def(ghi)/.gen.should == 'abcdefghi'
37
+ end
38
+ end
39
+
40
+ it "/(((abc)))/ => 'abc'" do
41
+ 100.times do
42
+ /(((abc)))/.gen.should == 'abc'
43
+ end
44
+ end
45
+
46
+ it "/ab(c(def))/ => 'abcdef'" do
47
+ 100.times do
48
+ /ab(c(def))/.gen.should == 'abcdef'
49
+ end
50
+ end
51
+
52
+ it "/(\\w+)/ => /\\w+/" do
53
+ 100.times do
54
+ /(\w+)/.gen.should =~ /\w+/
55
+ end
56
+ end
57
+
58
+ it "/\\w+ \\w+/ => /\\w+\\s\\w+/" do
59
+ 100.times do
60
+ /\w+ \w+/.gen.should =~ /\w+\s\w+/
61
+ end
62
+ end
63
+
64
+ it "/\\w*/ => /(\\w+)|/" do
65
+ 100.times do
66
+ /\w*/.gen.should =~ /(\w+)|/
67
+ end
68
+ end
69
+
70
+ it "/\\w{2,5}/ => /\\w{2,5}/" do
71
+ 100.times do
72
+ /\w{2,5}/.gen.should =~ /\w{2,5}/
73
+ end
74
+ end
75
+
76
+ it "/\\w{1}/ => /\\w/" do
77
+ 100.times do
78
+ /\w{1}/.gen.should =~ /\w/
79
+ end
80
+ end
81
+
82
+ it "/\\w{4}/ => /\\w{4}/" do
83
+ 100.times do
84
+ /\w{4}/.gen.should =~ /\w{4}/
85
+ end
86
+ end
87
+
88
+ it "/[:word:]/ => /\\w+/" do
89
+ 100.times do
90
+ /[:word:]/.gen.should =~ /\w+/
91
+ end
92
+ end
93
+
94
+ it "/[:bool:]/ => /true|false/" do
95
+ /[:bool:]/.gen.should =~ /true|false/
96
+ end
97
+
98
+ it "/[:sentence:]/ => /(\w+ )*/" do
99
+ 100.times do
100
+ /[:sentence:]/.gen.should =~ /(\w+ )*/
101
+ end
102
+ end
103
+
104
+ it "/[:paragraph:]/ => /( (\w+ )*\.)*/" do
105
+ 100.times do
106
+ /[:paragraph:]/.gen.should =~ /(\w+ )*/
107
+ end
108
+ end
109
+
110
+ it "/(abc|def){1,2}/ => ['abc', 'def', 'abcabc', 'abcdef', 'defabc', 'defdef']" do
111
+ 100.times do
112
+ ['abc', 'def', 'abcabc', 'abcdef', 'defabc', 'defdef'].should include(/(abc|def){1,2}/.gen)
113
+ end
114
+ end
115
+
116
+ it "/abc(def)?hij/ => /abc(def)?hij/" do
117
+ 100.times do
118
+ /abc(def)?hij/.gen.should =~ /abc(def)?hij/
119
+ end
120
+ end
121
+
122
+ it "/ab(c(def))?h/ => /ab(c(def))?h/" do
123
+ 100.times do
124
+ /ab(c(def))?h/.gen.should =~ /ab(c(def))?h/
125
+ end
126
+ end
127
+
128
+ it "/(\\d{3}-)?\\d{3}-\\d{4}/ => /(\\d{3}-)?\\d{3}-\\d{4}/" do
129
+ 100.times do
130
+ /(\d{3}-)?\d{3}-\d{4}/.gen.should =~ /(\d{3}-)?\d{3}-\d{4}/
131
+ end
132
+ end
133
+
134
+ it "/[:phone_number:]/ => /(\\d{3}-)?\\d{3}-\\d{4}/" do
135
+ 100.times do
136
+ /[:phone_number:]/.gen.should =~ /(\d{3}-)?\d{3}-\d{4}/
137
+ end
138
+ end
139
+
140
+ it "/[:phone_number:]{7}/ => /\\d{3}-\\d{4}/" do
141
+ 100.times do
142
+ /[:phone_number:]{7}/.gen.should =~ /\d{3}-\d{4}/
143
+ end
144
+ end
145
+
146
+ it "/[:phone_number:]{10}/ => /\\d{3}-\\d{3}-\\d{4}/" do
147
+ 100.times do
148
+ /[:phone_number:]{10}/.gen.should =~ /\d{3}-\d{3}-\d{4}/
149
+ end
150
+ end
151
+
152
+ it "/\\w+@\\w+\\.(com|org|net)/ => /\\w+@\\w+\\.(com|org|net)/.gen" do
153
+ 100.times do
154
+ /\w+@\w+\.(com|org|net)/.gen.should =~ /\w+@\w+\.(com|org|net)/
155
+ end
156
+ end
157
+
158
+ it "/\\$\\d{2,3}\\.\\d{2}/ => /\\$\\d{2,3}\\.\\d{2}/" do
159
+ 100.times do
160
+ /\$\d{2,3}\.\d{2}/.gen.should =~ /\$\d{2,3}\.\d{2}/
161
+ end
162
+ end
163
+
164
+ it "/[:first_name:]/ => /\\w+/" do
165
+ 100.times do
166
+ /[:first_name:]/.gen.should =~ /\w+/
167
+ end
168
+ end
169
+
170
+ it "/[:last_name:]/ => /\\w+/" do
171
+ /[:last_name:]/.gen.should =~ /\w+/
172
+ end
173
+
174
+ it "/[:name:]/ => /\\w+ \\w+/" do
175
+ /[:name:]/.gen.should =~ /\w+ \w+/
176
+ end
177
+
178
+ it "/[:last_name:]{5,10}/ => /\\w{5,10}/" do
179
+ /[:last_name:]{5,10}/.gen.should =~ /\w{5,10}/
180
+ end
181
+
182
+ it "/[:first_name:]{5,10}/ => /\\w{5,10}/" do
183
+ /[:first_name:]{5,10}/.gen.should =~ /\w{5,10}/
184
+ end
185
+
186
+ it "/./ => /./" do
187
+ 100.times do
188
+ /./.gen.should =~ /./
189
+ end
190
+ end
191
+
192
+ it "/.\\./ => /.\\./" do
193
+ 100.times do
194
+ /.\./.gen =~ /.\./
195
+ end
196
+ end
197
+
198
+ it "/.{10}@.{1,9999}/ => /.{10}@.{1,9999}/" do
199
+ 10.times do
200
+ /.{10}@.{1,9999}/.gen =~ /.{10}@.{1,9999}/
201
+ end
202
+ end
203
+
204
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
4
+
5
+ require 'randexp'
6
+
7
+ Spec::Runner.configure do |config|
8
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Regexp do
4
+ describe "#gen" do
5
+ it "should always return a string" do
6
+ /abcd/.gen.class.should == String
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Randexp::Parser do
4
+ describe ".parse" do
5
+ it "should return a sexp for a non-empty string" do
6
+ Randexp::Parser.parse("abc").should be_instance_of(Array)
7
+ end
8
+
9
+ it "should return nil for an empty string" do
10
+ Randexp::Parser.parse("").should be_nil
11
+ end
12
+
13
+ it "should alias :[] to :parse" do
14
+ Randexp::Parser[""].should be_nil
15
+ end
16
+ end
17
+
18
+ describe ".quantify" do
19
+ it "should return a :quantify sexp" do
20
+ Randexp::Parser.quantify([:literal, 'a'], :*)[0].should == :quantify
21
+ end
22
+
23
+ it "should push the quantify symbol on the end of the sexp" do
24
+ Randexp::Parser.quantify([:literal, 'a'], :*).last.should == :*
25
+ end
26
+
27
+ it "should push the argument sexp to the first entry of the :quantify sexp" do
28
+ Randexp::Parser.quantify([:literal, 'a'], :*)[1].should == [:literal, 'a']
29
+ end
30
+ end
31
+
32
+ describe ".union" do
33
+ it "should return the union of the right-hand side if the left-hand side is nil" do
34
+ Randexp::Parser.union(nil, [:literal, 'a']).should == Randexp::Parser.union([:literal, 'a'])
35
+ end
36
+
37
+ it "should return the left-hand side if the right hand side is not present" do
38
+ Randexp::Parser.union([:literal, 'a']).should == [:literal, 'a']
39
+ end
40
+
41
+ it "should append the right-hand side(s) to the left-hand side if the left-hand side is a union sexp" do
42
+ Randexp::Parser.union([:union, [:literal, 'a'], [:literal, 'b']], [:literal, 'c']).should == [:union, [:literal, 'a'], [:literal, 'b'], [:literal, 'c']]
43
+ end
44
+
45
+ it "should return a :union sexp between the left-hand and right-hand sexp's" do
46
+ Randexp::Parser.union([:literal, 'a'], [:literal, 'b']).should == [:union, [:literal, 'a'], [:literal, 'b']]
47
+ end
48
+ end
49
+
50
+ describe ".intersection" do
51
+ it "should prepend the left-hand side onto the right-hand side :intersection sexp if the right-hand side is an :intersection sexp" do
52
+ Randexp::Parser.intersection([:literal, 'a'], [:intersection, [:literal, 'b'], [:literal, 'c']]).should == [:intersection, [:literal, 'a'], [:literal, 'b'], [:literal, 'c']]
53
+ end
54
+
55
+ it "should create an :intersection sexp between the left-hand and right-hand sexp's" do
56
+ Randexp::Parser.intersection([:literal, 'a'], [:literal, 'b']).should == [:intersection, [:literal, 'a'], [:literal, 'b']]
57
+ end
58
+ end
59
+
60
+ describe ".random" do
61
+ it "should return a :random sexp" do
62
+ Randexp::Parser.random('w').should be_instance_of(Array)
63
+ Randexp::Parser.random('w').first.should == :random
64
+ end
65
+
66
+ it "should convert the char parameter to a symbol" do
67
+ Randexp::Parser.random('w').last.should == :w
68
+ end
69
+ end
70
+
71
+ describe ".literal" do
72
+ it "should return a literal sexp" do
73
+ Randexp::Parser.literal('a').should be_instance_of(Array)
74
+ Randexp::Parser.literal('a').first.should == :literal
75
+ end
76
+ end
77
+ end