diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..6096483 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,5 @@ +== 0.1.0 "Very Beta" 2008-07-08 +* Initial version of randexp! +* Has support for very simple regular expressions. +* Randgen has limited methods. +* Dictionary is reading from the local words file. \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..746d03e --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 Ben Burkert + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..0ac3eaf --- /dev/null +++ b/README @@ -0,0 +1,83 @@ +randexp + by Ben Burkert + http://github.com/benburkert/randexp + +== DESCRIPTION: + +andexp makes it easy to generate random string from most regular expressions. + +== REQUIREMENTS: + +* none! + +== INSTALL: + + $ gem sources -a http://gems.github.com/ (you only need to do this once) + $ gem install benburkert-randexp + +== USAGE: + +randexp adds the #generate (or #gen, for short) method to the Regexp class, +which generates a 'random' string that will match your regular expression. + + /abc|def/.gen + # => "def" + +== Valid Regexp's + +randexp can only generate matching string from simple regular expression. +Except for a few circumstances, wildcards are generally not allowed in the +regular expression. is pretty domain specific, so trying to guess when to +terminate a random pattern would produce unhelpful data: + + >> /Aa{3}h*!/.gen + # => RuntimeError: Sorry, "h*" is too vague, try setting a range: "h{0,3}" + >> /Aa{3}h{3,15}!/.gen + => "Aaaahhhhh!" + + >> /(never gonna (give you up|let you down), )*/.gen + => RuntimeError: Sorry, "(...)*" is too vague, try setting a range: "(...){0, 3}" + >> /(never gonna (give you up|let you down), ){3,5}/.gen + => "never gonna give you up, never gonna let you down, never gonna give you up, never gonna give you up, " + +The exception being word characters (\w), which generate a random word from the Dictionary class. + + >> /\w+/.gen + => "groveling" + += Primitives & Complex matches + +The single character matchers supported are words(\w), whitespace(\s), and digits(\d). + + >> /\d{50}/.gen + => "50315410741096763188525493528315906035878741451037" + +When a multiplicity constraint is placed on a word character, a word with the valid length is generated. + + >> /\w{10}/.gen # a word with 10 letters + => "Chaucerism" + + >> /\w{5,15}/.gen + => "cabalistic" + +Complex matchers use the [:...:] syntax within the regular expression. + + >> /[:sentence:]/.gen + => "Nonhearer demetricize toppiece filicic possessedness rhodizite zoomagnetism earwigginess steady" + +Complex matchers can also be added by extending the Randgen class. + + class Randgen + def self.serial_number(options = {}) + /XX\d{4}-\w-\d{5}/.gen + end + end + + >> /[:serial_number:]/.gen + => "XX3770-M-33114" + += Dictionary + +The Dictionary loads the local users' words file, allowing randomly generated words to be chosen from +thousands of entries to the words file. Words are mapped by their length to allow words to be randomly +chosen based on size. \ No newline at end of file diff --git a/README.textile b/README.textile new file mode 100644 index 0000000..9aac11a --- /dev/null +++ b/README.textile @@ -0,0 +1,107 @@ +h1. randexp +bq. by Ben Burkert +bq. http://github.com/benburkert/randexp + +h2. DESCRIPTION: + +andexp makes it easy to generate random string from most regular expressions. + +h2. REQUIREMENTS: + +* none! + +h2. INSTALL: + + $ gem sources -a http://gems.github.com/ (you only need to do this once) + $ gem install benburkert-randexp + +h2. USAGE: + +randexp adds the #generate (or #gen, for short) method to the Regexp class, +which generates a 'random' string that will match your regular expression. + + /abc|def/.gen + # => "def" + +h2. Valid Regexp's + +randexp can only generate matching string from simple regular expression. +Except for a few circumstances, wildcards are generally not allowed in the +regular expression. is pretty domain specific, so trying to guess when to +terminate a random pattern would produce unhelpful data: + +
+
+  >> /Aa{3}h*!/.gen
+      # => RuntimeError: Sorry, "h*" is too vague, try setting a range: "h{0,3}"
+  >> /Aa{3}h{3,15}!/.gen
+      => "Aaaahhhhh!"
+
+  >> /(never gonna (give you up|let you down), )*/.gen
+      => RuntimeError: Sorry, "(...)*" is too vague, try setting a range: "(...){0, 3}"
+  >> /(never gonna (give you up|let you down), ){3,5}/.gen
+      => "never gonna give you up, never gonna let you down, never gonna give you up, never gonna give you up, "
+
+
+ +The exception being word characters (\w), which generate a random word from the Dictionary class. + +
+
+  >> /\w+/.gen
+      => "groveling"
+
+
+ +h3. Primitives & Complex matches + +The single character matchers supported are words(\w), whitespace(\s), and digits(\d). + +
+
+  >> /\d{50}/.gen
+      => "50315410741096763188525493528315906035878741451037"
+
+
+ +When a multiplicity constraint is placed on a word character, a word with the valid length is generated. + +
+
+  >> /\w{10}/.gen  # a word with 10 letters
+      => "Chaucerism"
+
+  >> /\w{5,15}/.gen
+      => "cabalistic"
+  
+  
+ +Complex matchers use the [:...:] syntax within the regular expression. + +
+
+  >> /[:sentence:]/.gen
+      => "Nonhearer demetricize toppiece filicic possessedness rhodizite zoomagnetism earwigginess steady"
+
+
+ +Complex matchers can also be added by extending the Randgen class. + +
+
+  class Randgen
+    def self.serial_number(options = {})
+      /XX\d{4}-\w-\d{5}/.gen
+    end
+  end
+
+  >> /[:serial_number:]/.gen
+      => "XX3770-M-33114"
+
+
+ +h3. Dictionary + +The Dictionary loads the local users' words file, allowing randomly generated words to be chosen from +thousands of entries to the words file. Words are mapped by their length to allow words to be randomly +chosen based on size. \ No newline at end of file diff --git a/Rakefile b/Rakefile index e0c081e..1dcd8ac 100644 --- a/Rakefile +++ b/Rakefile @@ -7,32 +7,6 @@ require 'rake/rdoctask' require "spec" require "spec/rake/spectask" -DIR = File.dirname(__FILE__) -NAME = 'randexp' -SUMMARY =<<-EOS -Library for generating random strings. -EOS -GEM_VERSION = "0.1.0" - -spec = Gem::Specification.new do |s| - s.name = NAME - s.summary = SUMMARY - - s.version = GEM_VERSION - s.platform = Gem::Platform::RUBY - - s.has_rdoc = true - - s.require_path = "lib" - s.files = %w(Rakefile) + Dir["lib/**/*"] -end - -Rake::GemPackageTask.new(spec) do |package| - package.gem_spec = spec - package.need_zip = true - package.need_tar = true -end - ############################################################################## # rSpec & rcov ############################################################################## diff --git a/lib/randexp.rb b/lib/randexp.rb index 84ac919..6f8c5dc 100644 --- a/lib/randexp.rb +++ b/lib/randexp.rb @@ -1,6 +1,4 @@ class Randexp - VERSION = "0.1.0" - attr_accessor :sexp def initialize(source) diff --git a/lib/randexp/parser.rb b/lib/randexp/parser.rb index b330db9..db4c507 100644 --- a/lib/randexp/parser.rb +++ b/lib/randexp/parser.rb @@ -17,6 +17,12 @@ def self.parse(source) when /(.*)\\([wsdc])\{(\d+)\,(\d+)\}$/ then union(parse($1), quantify(random($2), ($3.to_i)..($4.to_i))) when /(.*)\\([wsdc])\{(\d+)\}$/ then union(parse($1), quantify(random($2), $3.to_i)) when /(.*)\\([wsdc])$/ then union(parse($1), random($2)) + when /\((.*)\)(\*|\*\?|\+|\+\?|\?)$/ then quantify(parse($1), $2.to_sym) + when /\((.*)\)\{(\d+)\,(\d+)\}$/ then quantify(parse($1), ($2.to_i)..($3.to_i)) + when /\((.*)\)\{(\d+)\}$/ then quantify(parse($1), $3.to_i) + when /(.*)(.|\s)(\*|\*\?|\+|\+\?|\?)$/ then union(parse($1), quantify(literal($2), $3.to_sym)) + when /(.*)(.|\s)\{(\d+)\,(\d+)\}$/ then union(parse($1), quantify(literal($2), ($3.to_i)..($4.to_i))) + when /(.*)(.|\s)\{(\d+)\}$/ then union(parse($1), quantify(literal($2), $3.to_i)) when /(.*)(.|\s)$/ then union(parse($1), literal($2)) else nil end diff --git a/lib/randexp/reducer.rb b/lib/randexp/reducer.rb index 987daeb..d9839a4 100644 --- a/lib/randexp/reducer.rb +++ b/lib/randexp/reducer.rb @@ -26,8 +26,8 @@ def self.literal(cell, quantity = nil) when :'?' then ([''] + cell).pick * '' when :+, :'+?' then raise "Sorry, \"#{cell * ''}+\" is too vague, try setting a range: \"#{cell * ''}{1,3}\"" when :*, :'*?' then raise "Sorry, \"#{cell * ''}*\" is too vague, try setting a range: \"#{cell * ''}{0,3}\"" - when Range then quant.pick.of { cell * '' } * '' - when Integer then quant.of { cell * '' } * '' + when Range then quantity.pick.of { cell * '' } * '' + when Integer then quantity.of { cell * '' } * '' when nil then cell * '' end end diff --git a/lib/randgen.rb b/lib/randgen.rb index ccacf7f..6d59a49 100644 --- a/lib/randgen.rb +++ b/lib/randgen.rb @@ -2,31 +2,31 @@ class Randgen WORDS_PER_SENTENCE = 3..20 SENTENCES_PER_PARAGRAPH = 3..8 - def self.bool + def self.bool(options = {}) ['true', 'false'].pick end - def self.lchar + def self.lchar(options = {}) ('a'..'z').to_a.pick end - def self.uchar + def self.uchar(options = {}) ('A'..'Z').to_a.pick end - def self.char + def self.char(options = {}) [lchar, uchar].pick end - def self.whitespace + def self.whitespace(options = {}) ["\t", "\n", "\r", "\f"].pick end - def self.digit + def self.digit(options = {}) ('0'..'9').to_a.pick end - def self.alpha_numeric + def self.alpha_numeric(options = {}) [char, digit].pick end diff --git a/randexp.gemspec b/randexp.gemspec new file mode 100644 index 0000000..95dd389 --- /dev/null +++ b/randexp.gemspec @@ -0,0 +1,16 @@ +Gem::Specification.new do |s| + s.name = "randexp" + s.version = "0.1.0" + s.date = "2008-07-08" + s.summary = "Library for generating random strings" + s.email = "ben@benburkert.com" + s.homepage = "http://github.com/benburkert/randexp" + s.description = "randexp makes it easy to generate random string from most regular expressions." + s.has_rdoc = true + s.authors = ["Ben Burkert"] + s.files = %w(Rakefile CHANGELOG LICENSE README) + Dir["lib/**/*"] + s.test_files = Dir["spec/**/*"] + s.rdoc_options = ["--main", "README"] + s.extra_rdoc_files = ["CHANGELOG", "README"] + s.require_path = "lib" +end \ No newline at end of file