diff --git a/README.md b/README.md index dd8ae14425..134ddb18a1 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Contents - [Faker::LordOfTheRings](doc/lord_of_the_rings.md) - [Faker::LoremPixel](doc/lorem_pixel.md) - [Faker::Lorem](doc/lorem.md) + - [Faker::Lovecraft](doc/lovecraft.md) - [Faker::Markdown](doc/markdown.md) - [Faker::Matz](doc/matz.md) - [Faker::Music](doc/music.md) diff --git a/doc/lovecraft.md b/doc/lovecraft.md new file mode 100644 index 0000000000..5ba369f7ef --- /dev/null +++ b/doc/lovecraft.md @@ -0,0 +1,36 @@ +# Faker::Lovecraft + +```ruby +Faker::Lovecraft.fhtagn(3) #=> "Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn. Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn. Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn" + +Faker::Lovecraft.deity #=> "Shub-Niggurath" + +Faker::Lovecraft.tome #=> "Book of Eibon" + +Faker::Lovecraft.location #=> "Kingsport" + +Faker::Lovecraft.word #=> "furtive" + +# Optional arguments: word_count=4, random_words_to_add=6 +Faker::Lovecraft.sentence #=> "Furtive antiquarian squamous dank cat loathsome amorphous lurk." +Faker::Lovecraft.sentence(3) #=> "Daemoniac antediluvian fainted squamous comprehension gambrel nameless singular." +Faker::Lovecraft.sentence(3, 1) #=> "Amorphous indescribable tenebrous." + +# Optional arguments: num=3, spaces_allowed = false +Faker::Lovecraft.words #=> ["manuscript", "abnormal", "singular"] +Faker::Lovecraft.words(2) #=> ["daemoniac", "cat"] +Faker::Lovecraft.words(2, true) #=> ["lurk", "charnel"] + +# Optional arguments: sentence_count=3 +Faker::Lovecraft.sentences #=> ["Nameless loathsome decadent gambrel.", "Ululate swarthy immemorial cat madness gibbous unmentionable unnamable.", "Decadent antediluvian non-euclidean tentacles amorphous tenebrous."] +Faker::Lovecraft.sentences(2) #=> ["Antediluvian amorphous unmentionable singular accursed squamous immemorial.", "Gambrel daemoniac gibbous stygian shunned ululate iridescence abnormal."] + +# Optional arguments: sentence_count=3, random_sentences_to_add=3 +Faker::Lovecraft.paragraph #=> "Squamous nameless daemoniac fungus ululate. Cyclopean stygian decadent loathsome manuscript tenebrous. Foetid abnormal stench. Dank non-euclidean comprehension eldritch. Charnel singular shunned lurk effulgence fungus." +Faker::Lovecraft.paragraph(2) #=> "Decadent lurk tenebrous loathsome furtive spectral amorphous gibbous. Gambrel eldritch daemoniac cat madness comprehension stygian effulgence." +Faker::Lovecraft.paragraph(2, 1) #=> "Stench cyclopean fainted antiquarian nameless. Antiquarian ululate tenebrous non-euclidean effulgence." + +# Optional arguments: paragraph_count=3 +Faker::Lovecraft.paragraphs #=> ["Noisome daemoniac gibbous abnormal antediluvian. Unutterable fungus accursed stench noisome lurk madness indescribable. Antiquarian fungus gibbering lurk dank fainted. Hideous loathsome manuscript daemoniac lurk charnel foetid.", "Non-euclidean immemorial indescribable accursed furtive. Dank unnamable cyclopean tenebrous stench immemorial. Eldritch abnormal gibbering tenebrous. Singular accursed lurk.", "Charnel antediluvian unnamable cat blasphemous comprehension tenebrous. Nameless accursed amorphous unnamable stench. Squamous unnamable mortal accursed manuscript spectral gambrel amorphous. Shunned stygian charnel unutterable. Tenebrous ululate lurk amorphous unnamable."] +Faker::Lovecraft.paragraphs(2) #=> ["Hideous amorphous manuscript antediluvian non-euclidean cat eldritch foetid. Stench squamous manuscript amorphous gibbering fainted gibbous. Accursed loathsome blasphemous iridescence antediluvian abnormal ululate manuscript. Singular manuscript gibbering decadent accursed indescribable.", "Tenebrous unnamable comprehension antediluvian lurk. Lurk spectral noisome gibbering. Furtive manuscript madness tenebrous daemoniac."] +``` diff --git a/lib/faker/lovecraft.rb b/lib/faker/lovecraft.rb new file mode 100644 index 0000000000..f23f417f55 --- /dev/null +++ b/lib/faker/lovecraft.rb @@ -0,0 +1,73 @@ +module Faker + class Lovecraft < Base + class << self + def location + fetch('lovecraft.location') + end + + def fhtagn(number_of = 1) + number_of.times.collect { fetch('lovecraft.fhtagn') }.join(". ") + end + + def deity + fetch('lovecraft.deity') + end + + def tome + fetch('lovecraft.tome') + end + + def sentence(word_count = 4, random_words_to_add = 6) + words(word_count + rand(random_words_to_add.to_i).to_i, true).join(' ').capitalize + '.' + end + + def word + random_word = sample(translate('faker.lovecraft.words')) + random_word.match(/\s/) ? word : random_word + end + + def words(num = 3, spaces_allowed = false) + resolved_num = resolve(num) + word_list = translate('faker.lovecraft.words') + word_list = word_list * ((resolved_num / word_list.length) + 1) + + return shuffle(word_list)[0, resolved_num] if spaces_allowed + words = shuffle(word_list)[0, resolved_num] + words.each_with_index { |w, i| words[i] = word if w.match(/\s/) } + end + + + def sentences(sentence_count = 3) + [].tap do |sentences| + 1.upto(resolve(sentence_count)) do + sentences << sentence(3) + end + end + end + + def paragraph(sentence_count = 3, random_sentences_to_add = 3) + sentences(resolve(sentence_count) + rand(random_sentences_to_add.to_i).to_i).join(' ') + end + + def paragraphs(paragraph_count = 3) + [].tap do |paragraphs| + 1.upto(resolve(paragraph_count)) do + paragraphs << paragraph(3) + end + end + end + + private + + # If an array or range is passed, a random value will be selected. + # All other values are simply returned. + def resolve(value) + case value + when Array then sample(value) + when Range then rand value + else value + end + end + end + end +end diff --git a/lib/locales/en.yml b/lib/locales/en.yml index 8188c416bd..9c9863b1e0 100755 --- a/lib/locales/en.yml +++ b/lib/locales/en.yml @@ -776,3 +776,9 @@ en: ] species: ["Algolian Suntiger", "Arcturan MegaDonkey", "Arcturan Megagrasshopper", "Azgoths of Kria", "Babel Fish", "Belcerebon", "Boghog", "Cow", "Damogran Frond Crested Eagle", "Dentrassis", "Dolphins", "Flaybooz", "Golgafrinchan", "Grebulon", "Grebulons", "Hingefreel", "Hooloovoo", "Human", "Jatravartid", "Mattress", "Mice", "Mouse", "Nanites", "Perfectly Normal Beast", "Ravenous Bugblatter Beast of Traal", "Sarkopsi", "Shaltanac", "Silastic Armorfiends", "Silver Tongued Devils", "Vl'Hurg", "Vogon"] starships: ["Billion Year Bunker", "Bistromath", "Golgafrinchan Ark Fleet Ship B", "Heart of Gold", "Krikkit One", "RW6", "Starship Titanic", "Tanngrisnir", "Vogon Constructor Fleet"] + lovecraft: + fhtagn: ["Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn"] + deity: ["Azathoth", "Cthulhu", "Dagon", "Hastur", "Nyarlathotep", "Shub-Niggurath", "Tsathoggua", "Yog-Sothoth"] + location: ["Arkham", "Dunwich", "Innsmouth", "Kadath", "Kingsport", "Leng", "Miskatonic", "R’lyeh", "Yuggoth", "Irem"] + tome: ["Necronomicon", "Pnakotic Manuscripts", "De Vermis Mysteriis", "Book of Eibon", "Eltdown Shards"] + words: ["abnormal", "accursed", "amorphous", "antediluvian", "antiquarian", "blasphemous", "cat", "charnel", "comprehension", "cyclopean", "dank", "decadent", "daemoniac", "effulgence", "eldritch", "fainted", "foetid", "fungus", "furtive", "gambrel", "gibbous", "gibbering", "hideous", "immemorial", "indescribable", "iridescence", "loathsome", "lurk", "madness", "manuscript", "mortal", "nameless", "noisome", "non-euclidean", "shunned", "singular", "spectral", "squamous", "stench", "stygian", "swarthy", "tenebrous", "tentacles", "ululate", "unmentionable", "unnamable", "unutterable"] diff --git a/test/test_faker_lovecraft.rb b/test/test_faker_lovecraft.rb new file mode 100644 index 0000000000..010b9972cc --- /dev/null +++ b/test/test_faker_lovecraft.rb @@ -0,0 +1,83 @@ +require File.dirname(__FILE__) + '/test_helper.rb' + +class TestFakerLovecraft < Test::Unit::TestCase + + def setup + @tester = Faker::Lovecraft + @wordlist = I18n.translate('faker.lovecraft.words') + end + + # Words delivered by this request should be on the wordlist. + def test_words + @words = @tester.words(1000) + @words.each { |w| assert @wordlist.include?(w) } + end + + # Words should not return any word with spaces + def test_words_without_spaces + @words = @tester.words(1000) + @words.each { |w| assert !w.match(/\s/) } + end + + # Faker::Lovecraft.word generates random word from wordlist + def test_word + 1000.times { assert @wordlist.include?(@tester.word) } + end + + # Word should not return any word with spaces + def test_word_without_spaces + 1000.times { assert !@tester.word.match(/\s/) } + end + + def test_exact_count_param + assert(@tester.words(2).length == 2) + assert(@tester.sentences(2).length == 2) + assert(@tester.paragraphs(2).length == 2) + end + + def test_range_count_param + ws = @tester.words(2..5) + ss = @tester.sentences(2..5) + ps = @tester.paragraphs(2..5) + + assert(2 <= ws.length && ws.length <= 5) + assert(2 <= ss.length && ss.length <= 5) + assert(2 <= ps.length && ps.length <= 5) + end + + def test_array_count_param + ws = @tester.words([1,4]) + ss = @tester.sentences([1,4]) + ps = @tester.paragraphs([1,4]) + + assert(ws.length == 1 || ws.length == 4) + assert(ss.length == 1 || ss.length == 4) + assert(ps.length == 1 || ps.length == 4) + end + + def test_words_with_large_count_params + exact = @tester.words(500) + range = @tester.words(250..500) + array = @tester.words([250, 500]) + + assert(exact.length == 500) + assert(250 <= range.length && range.length <= 500) + assert(array.length == 250 || array.length == 500) + end + + def test_tome + assert @tester.tome.match(/\w/) + end + + def test_location + assert @tester.location.match(/\w/) + end + + def test_deity + assert @tester.deity.match(/\w/) + end + + def test_fhtagn + assert @tester.fhtagn.match(/\w/) + end +end