michel-randexp 0.1.4

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.
@@ -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