{"body":"use Test;\nclass Test::Fuzz {\n\tclass Fuzzer {\n\t\thas\t\t\t\t$.name;\n\t\thas \t\t\t@.data;\n\t\thas Supply\t\t$.get-data;\n\t\thas Block\t\t$.func;\n\t\thas \t\t\t$.returns;\n\t\thas Callable\t$.test;\n\n\t\tmethod run() is hidden-from-backtrace {\n\t\t\tsubtest {\n\t\t\t\treact {\n\t\t\t\t\twhenever $.get-data -> @data {\n\t\t\t\t\t\tsay \"data: {@data}\";\n\t\t\t\t\t\tmy $return = $.func.(|@data);\n\t\t\t\t\t\t$return.exception.throw if $return ~~ Failure;\n\t\t\t\t\t\tCATCH {\n\t\t\t\t\t\t\tdefault {\n\t\t\t\t\t\t\t\tlives-ok {\n\t\t\t\t\t\t\t\t\t.throw\n\t\t\t\t\t\t\t\t}, \"{ $.name }({ @data.map({.defined ?? $_ !! \"({ $_.^name })\"}).join(\", \") })\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif $!test.defined and not $!test($return) {\n\t\t\t\t\t\t\tflunk \"{ $.name }({ @data.join(\", \") })\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpass \"{ $.name }({ @data.join(\", \") })\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, $.name\n\t\t}\n\t}\n\n\tmy Iterable %generator;\n\n\tmulti fuzz-generator(::Type) is export is rw {\n\t\t%generator{Type.^name};\n\t}\n\n\tmulti fuzz-generator(Str \\type) is export is rw {\n\t\t%generator{type};\n\t}\n\n\tfuzz-generator(\"Str\") = gather {\n\t\ttake \"\";\n\t\ttake \"a\";\n\t\ttake \"a\" x 9999999;\n\t\ttake \"áéíóú\";\n\t\ttake \"\\n\";\n\t\ttake \"\\r\";\n\t\ttake \"\\t\";\n\t\ttake \"\\r\\n\";\n\t\ttake \"\\r\\t\\n\";\n\t\tloop {\n\t\t\ttake (0.chr .. 0xc3bf.chr).roll((^999999).pick).join\n\t\t}\n\t};\n\n\tfuzz-generator(\"UInt\") = gather {\n\t\ttake 0;\n\t\ttake 1;\n\t\ttake 3;\n\t\ttake 9999999999;\n\t\ttake $_ for (^10000000000).roll(*)\n\t};\n\n\tfuzz-generator(\"Int\")\t= gather {\n\t\tfor @( %generator<UInt> ).grep({.defined}) -> $int {\n\t\t\ttake -$int;\n\t\t}\n\t};\n\n\tmy Fuzzer @fuzzers;\n\n\tsub fuzz(Routine $func, Int() :$counter = 100, Callable :$test, :@generators is copy) is export {\n\t\tif @generators {\n\t\t\t@generators .= map: { $^type || $^type.^name };\n\t\t} else {\n\t\t\t@generators = $func.signature.params.map({:type(.type.^name ~ .modifier), :constraint(.constraints)})\n\t\t}\n\t\tmy $get-data = Supply.zip(|@generators.map(-> (:$type, :$constraint) {\n\t\t\tmy $sup = $?CLASS.generate($type, $constraint, $counter);\n\t\t\t$sup.tap: &say;\n\t\t\t$sup\n\t\t}));\n\n\t\tmy $name\t= $func.name;\n\t\tmy $returns\t= $func.signature.returns;\n\n\t\t@fuzzers.push(Fuzzer.new(:$name, :$func, :$get-data, :$returns, :$test))\n\t}\n\n\tmulti trait_mod:<is> (Routine $func, :%fuzzed!) is export {\n\t\tfuzz($func, |%fuzzed);\n\t}\n\n\tmulti trait_mod:<is> (Routine $func, :$fuzzed!) is export {\n\t\tfuzz($func);\n\t}\n\n\tmulti method generate(Test::Fuzz:U: Str \\type, Mu $constraints, Int() \\size = 100) {\n\t\tmy @ret;\n\t\tmy $type = type ~~ /^^\n\t\t\t$<type>\t= (\\w+)\n\t\t\t[\n\t\t\t\t':'\n\t\t\t\t$<def>\t= (<[UD]>)\n\t\t\t]?\n\t\t$$/;\n\t\tmy %types := set |::.values.grep(! *.defined), |%?RESOURCES<classes>.IO.lines.map: {::($_)};\n\t\tmy @types = %types.keys.grep: ::(~$type<type>);\n\t\t@ret = @types if not $type<def>.defined or ~$type<def> eq \"U\";\n\t\tmy $supplier = Supplier.new;\n\t\tfor @types -> $sub {\n\t\t\tdo if %generator{$sub.^name}:exists {\n\t\t\t\tstart {\n\t\t\t\t\tmy $c = 0;\n\t\t\t\t\tfor @( %generator{$sub.^name} ) -> $item {\n\t\t\t\t\t\tlast if $c++ > size²;\n\t\t\t\t\t\t#say \"{$item} ~~ {~$type<type>} ~~ $constraints\";\n\t\t\t\t\t\tnext unless $item ~~ ::(~$type<type>) and $item ~~ $constraints;\n\t\t\t\t\t\t#say $item;\n\t\t\t\t\t\t$supplier.emit: $item\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t   \tif not @ret {\n\t\t\tdie \"Generator for '{type}' does not exists\"\n\t\t}\n\t\t$supplier.Supply\n\t}\n\n\tmulti method generate(Test::Fuzz:U: ::Type, Int() \\size) {\n\t\t$.generate(Type.^name, size);\n\t}\n\n\tmethod run-tests(Test::Fuzz:U:) {\n\t\tfor @fuzzers -> $fuzz {\n\t\t\t$fuzz.run;\n\t\t}\n\t}\n}","name":"","extension":"txt","url":"https://www.irccloud.com/pastebin/IOFVFmBT","modified":1481333042,"id":"IOFVFmBT","size":3272,"lines":144,"own_paste":false,"theme":"","date":1481333042}