urban 0.0.12 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/README.rdoc +17 -4
- data/Rakefile +13 -1
- data/bin/urban +1 -1
- data/lib/urban/cli.rb +66 -7
- data/lib/urban/dictionary.rb +28 -40
- data/lib/urban/version.rb +1 -1
- data/lib/urban/web.rb +13 -0
- data/lib/urban.rb +2 -1
- data/test/data/impromptu.html +463 -0
- data/test/test_helper.rb +33 -0
- data/test/urban/cli_test.rb +101 -0
- data/test/urban/dictionary_test.rb +21 -0
- data/test/urban/web_test.rb +21 -0
- data/urban.gemspec +3 -2
- metadata +53 -52
- data/.rvmrc +0 -1
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -6,6 +6,10 @@ random definition from {Urban Dictionary}[http://www.urbandictionary.com].
|
|
6
6
|
* {Git}[http://github.com/tmiller/urban]
|
7
7
|
* {Bug Tracker}[http://github.com/tmiller/urban/issues]
|
8
8
|
|
9
|
+
== Requirements
|
10
|
+
|
11
|
+
* >= Ruby 1.9.2-180
|
12
|
+
|
9
13
|
== Installation
|
10
14
|
|
11
15
|
With Rubygems:
|
@@ -24,15 +28,24 @@ With git and local working copy
|
|
24
28
|
|
25
29
|
$ urban cookie monster
|
26
30
|
|
27
|
-
=== 2. Random
|
31
|
+
=== 2. Random definition
|
32
|
+
|
33
|
+
$ urban -r
|
34
|
+
|
35
|
+
=== 3. Print all definitons
|
36
|
+
|
37
|
+
$ urban -l cookie monster
|
28
38
|
|
29
|
-
|
39
|
+
=== 4. Print help and version
|
30
40
|
|
41
|
+
$ urban --help
|
42
|
+
$ urban --version
|
43
|
+
|
31
44
|
== To Do
|
32
45
|
|
33
|
-
* Write Tests
|
34
46
|
* Document with {YARD}[http://yardoc.org]
|
35
|
-
*
|
47
|
+
* Print better looking output
|
48
|
+
* Test problem words below with new parser
|
36
49
|
|
37
50
|
== Test words for formatting
|
38
51
|
|
data/Rakefile
CHANGED
@@ -1 +1,13 @@
|
|
1
|
-
require 'bundler/
|
1
|
+
require 'bundler/gem_helper'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
|
5
|
+
task :default => :test
|
6
|
+
|
7
|
+
require 'rake/testtask'
|
8
|
+
Rake::TestTask.new do |t|
|
9
|
+
t.libs << "test"
|
10
|
+
t.test_files = FileList['test/**/*_test.rb']
|
11
|
+
t.verbose = true
|
12
|
+
t.warning = true
|
13
|
+
end
|
data/bin/urban
CHANGED
data/lib/urban/cli.rb
CHANGED
@@ -1,14 +1,73 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
1
3
|
require 'urban/dictionary'
|
2
4
|
|
3
5
|
module Urban
|
6
|
+
class CLI
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
rescue
|
10
|
-
puts "ERROR: #{ARGV.join(' ')} not found!"
|
8
|
+
attr_accessor :dictionary
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@dictionary = Urban::Dictionary.new
|
11
12
|
end
|
12
|
-
end
|
13
13
|
|
14
|
+
def run(args = ARGV)
|
15
|
+
options = parse(args)
|
16
|
+
results = case
|
17
|
+
when options.exit then return
|
18
|
+
when options.random then dictionary.random
|
19
|
+
when !options.phrase.empty? then dictionary.search(options.phrase)
|
20
|
+
end
|
21
|
+
output_results(results, options.list)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def output_results(results, list)
|
27
|
+
puts "\n#{results.word.upcase}\n\n"
|
28
|
+
if list
|
29
|
+
results.definitions.each { |definition| puts "#{definition}\n\n" }
|
30
|
+
else
|
31
|
+
puts "#{results.definitions.first}\n\n"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse(args)
|
36
|
+
options = OpenStruct.new
|
37
|
+
options.random = false
|
38
|
+
options.list = false
|
39
|
+
options.phrase = ''
|
40
|
+
opts = OptionParser.new do |o|
|
41
|
+
o.banner = "Usage: urban [OPTION]... [PHRASE]"
|
42
|
+
o.separator "Search http://urbandictionary.com for definitions"
|
43
|
+
|
44
|
+
o.separator ''
|
45
|
+
o.on('-l', '--list', 'List all definitions') do
|
46
|
+
options.list = true
|
47
|
+
end
|
48
|
+
|
49
|
+
o.on('-r', '--random', 'Find random word on urban dictionary') do
|
50
|
+
options.random = true
|
51
|
+
end
|
52
|
+
|
53
|
+
o.on('-h', '--help', 'Show this message') do
|
54
|
+
options.exit = true
|
55
|
+
end
|
56
|
+
|
57
|
+
o.on('--version', 'Show version') do
|
58
|
+
puts "Urban #{Urban::VERSION} (c) Thomas Miller"
|
59
|
+
options.exit = true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
opts.parse!(args)
|
63
|
+
options.phrase = args.join(' ')
|
64
|
+
|
65
|
+
if (options.exit || !options.random && options.phrase.empty?)
|
66
|
+
puts opts
|
67
|
+
options.exit = true
|
68
|
+
end
|
69
|
+
|
70
|
+
options
|
71
|
+
end
|
72
|
+
end
|
14
73
|
end
|
data/lib/urban/dictionary.rb
CHANGED
@@ -1,53 +1,41 @@
|
|
1
|
-
require 'urban/version'
|
2
|
-
|
3
|
-
require 'open-uri'
|
4
1
|
require 'nokogiri'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'urban/version'
|
4
|
+
require 'urban/web'
|
5
5
|
|
6
6
|
module Urban
|
7
|
-
|
7
|
+
class Dictionary
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
def random
|
12
|
-
get_definition(query(:random))
|
13
|
-
end
|
9
|
+
attr_accessor :web_service
|
14
10
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def get_definition(document)
|
20
|
-
word = wordize(node_to_s(document.at_css('.word')))
|
21
|
-
definition = definitionize(node_to_s(document.at_css('.definition')))
|
22
|
-
return { word: word, definition: definition }
|
23
|
-
end
|
11
|
+
def initialize
|
12
|
+
@web_service = Urban::Web.new
|
13
|
+
end
|
24
14
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
15
|
+
def random
|
16
|
+
document = Nokogiri::HTML(@web_service.query(:random))
|
17
|
+
process(document)
|
18
|
+
end
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
when 'br'
|
35
|
-
node.previous.content = node.previous.content << "\n" if node.previous
|
36
|
-
node.remove
|
37
|
-
end
|
20
|
+
def search(phrase)
|
21
|
+
document = Nokogiri::HTML(@web_service.query(:define, phrase))
|
22
|
+
process(document)
|
38
23
|
end
|
39
|
-
return node_set.content.strip.gsub(/\r/, "\n")
|
40
|
-
end
|
41
24
|
|
42
|
-
|
43
|
-
return string.gsub(pattern, &:upcase).gsub(/\s{2,}/, ' ')
|
44
|
-
end
|
25
|
+
private
|
45
26
|
|
46
|
-
|
47
|
-
|
48
|
-
|
27
|
+
def process(document)
|
28
|
+
OpenStruct.new({
|
29
|
+
word: document.at_xpath('//td[@class="word"][1]').content.strip,
|
30
|
+
definitions: parse_definitions(document) })
|
31
|
+
end
|
49
32
|
|
50
|
-
|
51
|
-
|
33
|
+
def parse_definitions(document)
|
34
|
+
definitions = document.xpath('//td/div[@class="definition"]').map do |node|
|
35
|
+
node.xpath('//br').each { |br| br.replace(Nokogiri::XML::Text.new("\n", node.document)) };
|
36
|
+
node.content.strip
|
37
|
+
end
|
38
|
+
definitions || []
|
39
|
+
end
|
52
40
|
end
|
53
41
|
end
|
data/lib/urban/version.rb
CHANGED
data/lib/urban/web.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'urban/version'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
module Urban
|
5
|
+
class Web
|
6
|
+
URL = 'http://www.urbandictionary.com'
|
7
|
+
|
8
|
+
def query(type, word = nil)
|
9
|
+
query = "#{type.to_s}.php" << (word ? "?term=#{word}" : '')
|
10
|
+
open(URI::Parser.new.escape("#{URL}/#{query}"))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/urban.rb
CHANGED
@@ -0,0 +1,463 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html lang='en-US' xml:lang='en-US' xmlns='http://www.w3.org/1999/xhtml'>
|
3
|
+
<head><script>var NREUMQ=[];NREUMQ.push(["mark","firstbyte",new Date().getTime()]);(function(){var d=document;var e=d.createElement("script");e.type="text/javascript";e.async=true;e.src="https://d1ros97qkrwjf5.cloudfront.net/16/eum/rum.js";var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(e,s);})()</script>
|
4
|
+
<title>Urban Dictionary: impromptu</title>
|
5
|
+
<script type='text/javascript'>
|
6
|
+
//<![CDATA[
|
7
|
+
var MobileDetector={redirect:function(b,a){if(b&&b.match(/(iPhone|iPod|Android|webOS|Opera Mini|PlayStation Portable)/)){this.go(a)}},go:function(a){window.location=a}};
|
8
|
+
MobileDetector.redirect(navigator.userAgent, "/iphone/#define?term=impromptu");
|
9
|
+
//]]>
|
10
|
+
</script>
|
11
|
+
|
12
|
+
|
13
|
+
<!--[if (!IE)|(gte IE 8)]><!-->
|
14
|
+
<link href="http://static3.urbandictionary.com/assets/base-datauri.css?1314062438" media="screen" rel="stylesheet" type="text/css" />
|
15
|
+
<!--<![endif]-->
|
16
|
+
<!--[if lte IE 7]>
|
17
|
+
<link href="http://static3.urbandictionary.com/assets/base.css?1314062438" media="screen" rel="stylesheet" type="text/css" />
|
18
|
+
<![endif]-->
|
19
|
+
<link href="http://feeds.urbandictionary.com/UrbanWordOfTheDay" rel="alternate" title="Urban Word of the Day" type="application/rss+xml" />
|
20
|
+
<link href="http://static0.urbandictionary.com/favicon.ico?1314062439" rel="shortcut icon" /><link href="http://static0.urbandictionary.com/favicon.ico?1314062439" rel="icon" />
|
21
|
+
|
22
|
+
|
23
|
+
<link href='http://static2.urbandictionary.com/osd.xml?1314062439' rel='search' title='Urban Dictionary Search' type='application/opensearchdescription+xml' />
|
24
|
+
<meta content='Something that is made up on the spot and given little time to gather and present. Usually referring to speeches that are given only a few minutes ...' name='Description' />
|
25
|
+
<meta content='Something that is made up on the spot and given little time to gather and present. Usually referring to speeches that are given only a few minutes ...' property='og:description' />
|
26
|
+
<meta content='impromptu' property='og:title' />
|
27
|
+
<meta content="http://static0.urbandictionary.com/images/og_image.png?1314062439" property="og:image" />
|
28
|
+
<script type="text/javascript">
|
29
|
+
//<![CDATA[
|
30
|
+
var Record={setRecordingCookie:function(a){document.cookie="recording="+a},getRecordingCookie:function(){var a=document.cookie.match("recording=(true|false)");return a?(a[1]=="true"):null},start:function(a){if(Record.getRecordingCookie()===null){Record.setRecordingCookie(Math.random()<a/100)}if(Record.getRecordingCookie()){document.write(unescape("%3Cscript src='"+(("https:"==document.location.protocol)?"https":"http")+"://c.mouseflow.com/projects/38f33478-b73a-4335-a2df-b0f221197471.js' type='text/javascript'%3E%3C/script%3E"))}}};
|
31
|
+
//]]>
|
32
|
+
</script>
|
33
|
+
<script type='text/javascript'>
|
34
|
+
//<![CDATA[
|
35
|
+
Record.start(0.001);
|
36
|
+
//]]>
|
37
|
+
</script>
|
38
|
+
<meta content='Urban Dictionary' property='og:site_name' />
|
39
|
+
</head>
|
40
|
+
<body class='define_controller'>
|
41
|
+
<div id='header_background'>
|
42
|
+
<div id='header_width'>
|
43
|
+
<div id='header'>
|
44
|
+
<a href="/" id="logo_anchor"><img alt="" id="logo" src="http://static1.urbandictionary.com/images/logo-holiday.png?1314062439" /></a>
|
45
|
+
<div id='like_button'>
|
46
|
+
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Ffacebook.com%2Furbandictionary&send=false&layout=button_count&width=100&show_faces=false&action=like&colorscheme=light&font&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:21px;" allowTransparency="true"></iframe>
|
47
|
+
</div>
|
48
|
+
<div id='form'>
|
49
|
+
<form action="/define.php" method="get">
|
50
|
+
<table>
|
51
|
+
<tr>
|
52
|
+
<td></td>
|
53
|
+
<td class='look_up'>look up any word:</td>
|
54
|
+
</tr>
|
55
|
+
<tr>
|
56
|
+
<td>
|
57
|
+
<div id='autocompleter_spinner' style='display: none'></div>
|
58
|
+
</td>
|
59
|
+
<td><input id="term" name="term" tabindex="1" type="text" value="impromptu" /></td>
|
60
|
+
<td>
|
61
|
+
<input type='submit' value='search' />
|
62
|
+
</td>
|
63
|
+
</tr>
|
64
|
+
</table>
|
65
|
+
</form>
|
66
|
+
</div>
|
67
|
+
<div id='topnav'>
|
68
|
+
<a href="/">word of the day</a> <a class="active" href="/popular.php?character=A">dictionary</a> <a href="/thesaurus.php">thesaurus</a> <a href="/names.php">names</a> <a href="/video.list.php">media</a> <a href="/products.php">store</a> <a href="/add.php">add</a> <a href="/editor/staygo.php">edit</a> <a href="http://blog.urbandictionary.com/">blog</a>
|
69
|
+
</div>
|
70
|
+
</div>
|
71
|
+
</div>
|
72
|
+
</div>
|
73
|
+
<div class='autocomplete' id='term_list' style='display:none'></div>
|
74
|
+
|
75
|
+
<div id='outer'>
|
76
|
+
<div class='' id='whole'>
|
77
|
+
<div class='innernav' id='subnav'>
|
78
|
+
<a accesskey="1" href="/random.php" title="hot key + 1">random</a> <a href="/popular.php?character=A">A</a> <a href="/popular.php?character=B">B</a> <a href="/popular.php?character=C">C</a> <a href="/popular.php?character=D">D</a> <a href="/popular.php?character=E">E</a> <a href="/popular.php?character=F">F</a> <a href="/popular.php?character=G">G</a> <a href="/popular.php?character=H">H</a> <a class="active" href="/browse.php?word=impromptu">I</a> <a href="/popular.php?character=J">J</a> <a href="/popular.php?character=K">K</a> <a href="/popular.php?character=L">L</a> <a href="/popular.php?character=M">M</a> <a href="/popular.php?character=N">N</a> <a href="/popular.php?character=O">O</a> <a href="/popular.php?character=P">P</a> <a href="/popular.php?character=Q">Q</a> <a href="/popular.php?character=R">R</a> <a href="/popular.php?character=S">S</a> <a href="/popular.php?character=T">T</a> <a href="/popular.php?character=U">U</a> <a href="/popular.php?character=V">V</a> <a href="/popular.php?character=W">W</a> <a href="/popular.php?character=X">X</a> <a href="/popular.php?character=Y">Y</a> <a href="/popular.php?character=Z">Z</a> <a href="/browse.php?character=%2A">#</a> <a href="/yesterday.php?date=2011-08-28">new</a> <a href="/favorites.php">favorites</a>
|
79
|
+
</div>
|
80
|
+
<table cellpadding='0' cellspacing='0' id='tablist'>
|
81
|
+
<tr>
|
82
|
+
<td id='leftist'>
|
83
|
+
<div class='prev_next_buttons'>
|
84
|
+
<a href="#" id="prev_titles" onclick="nearby.go('prev'); return false;" onmouseout="$(this).down().src = "http://static0.urbandictionary.com/images/uparrow.gif?1314062439"" onmouseover="$(this).down().src = "http://static3.urbandictionary.com/images/uparrow_dark.gif?1314062439""><img src="http://static0.urbandictionary.com/images/uparrow.gif?1314062439" /></a>
|
85
|
+
<a href="#" id="next_titles" onclick="nearby.go('next'); return false;" onmouseout="$(this).down().src = "http://static3.urbandictionary.com/images/downarrow.gif?1314062439"" onmouseover="$(this).down().src = "http://static2.urbandictionary.com/images/downarrow_dark.gif?1314062439""><img src="http://static3.urbandictionary.com/images/downarrow.gif?1314062439" /></a>
|
86
|
+
</div>
|
87
|
+
<ul id='nearby_titles'>
|
88
|
+
<li><a href="/define.php?term=Imprimplicate" class="urbantip">Imprimplicate</a></li><li><a href="/define.php?term=imprint" class="urbantip">imprint</a></li><li><a href="/define.php?term=Imprinting" class="urbantip">Imprinting</a></li><li><a href="/define.php?term=imprints" class="urbantip">imprints</a></li><li><a href="/define.php?term=imprisionate" class="urbantip">imprisionate</a></li><li><a href="/define.php?term=Imprisoned%20in%20the%20elevator" class="urbantip">Imprisoned in the elevator</a></li><li><a href="/define.php?term=imprisonment" class="urbantip">imprisonment</a></li><li><a href="/define.php?term=Imprist" class="urbantip">Imprist</a></li><li><a href="/define.php?term=imprn" class="urbantip">imprn</a></li><li><a href="/define.php?term=improbement" class="urbantip">improbement</a></li><li><a href="/define.php?term=Improdiblass" class="urbantip">Improdiblass</a></li><li><a href="/define.php?term=improgae" class="urbantip">improgae</a></li><li><a href="/define.php?term=impromperaneous" class="urbantip">impromperaneous</a></li><li><a href="/define.php?term=Imprompoo" class="urbantip">Imprompoo</a></li><li><a href="/define.php?term=Impromptitude" class="urbantip">Impromptitude</a></li><li class="active">impromptu</li><li><a href="/define.php?term=Impromptu%20Ding%20Dong" class="urbantip">Impromptu Ding Dong</a></li><li><a href="/define.php?term=impromptu%20peanutbutter%20sandwich" class="urbantip">impromptu peanutbutter sandwich</a></li><li><a href="/define.php?term=Impromptu%20Protein%20Party" class="urbantip">Impromptu Protein Party</a></li><li><a href="/define.php?term=impromtu" class="urbantip">impromtu</a></li><li><a href="/define.php?term=impronathon" class="urbantip">impronathon</a></li><li><a href="/define.php?term=improovisation" class="urbantip">improovisation</a></li><li><a href="/define.php?term=impropaganda" class="urbantip">impropaganda</a></li><li><a href="/define.php?term=Improper%20bo%20I%20don%E2%80%99t%20tell%20thou" class="urbantip">Improper bo I don’t tell thou</a></li><li><a href="/define.php?term=improper%20dumpling" class="urbantip">improper dumpling</a></li><li><a href="/define.php?term=improper%20fraction" class="urbantip">improper fraction</a></li><li><a href="/define.php?term=Improperganda" class="urbantip">Improperganda</a></li><li><a href="/define.php?term=impropertuity" class="urbantip">impropertuity</a></li><li><a href="/define.php?term=improprietous" class="urbantip">improprietous</a></li><li><a href="/define.php?term=improps" class="urbantip">improps</a></li><li><a href="/define.php?term=Improstable" class="urbantip">Improstable</a></li><li><a href="/define.php?term=Improta%20Bush" class="urbantip">Improta Bush</a></li><li><a href="/define.php?term=improtantly" class="urbantip">improtantly</a></li><li><a href="/define.php?term=improtivation" class="urbantip">improtivation</a></li><li><a href="/define.php?term=improv" class="urbantip">improv</a></li><li><a href="/define.php?term=Improv%20Everywhere" class="urbantip">Improv Everywhere</a></li><li><a href="/define.php?term=improvasationalist" class="urbantip">improvasationalist</a></li><li><a href="/define.php?term=improveder" class="urbantip">improveder</a></li><li><a href="/define.php?term=improveise" class="urbantip">improveise</a></li><li><a href="/define.php?term=improver" class="urbantip">improver</a></li><li><a href="/define.php?term=improverished" class="urbantip">improverished</a></li>
|
89
|
+
</ul>
|
90
|
+
<script type='text/javascript'>
|
91
|
+
//<![CDATA[
|
92
|
+
window.onDomLoaded = window.onDomLoaded || [];
|
93
|
+
window.onDomLoaded.push(function() {
|
94
|
+
window.nearby = new Nearby(new NearbyView(), "Imprimplicate", "improverished");
|
95
|
+
});
|
96
|
+
//]]>
|
97
|
+
</script>
|
98
|
+
|
99
|
+
<div class='prev_next_buttons'>
|
100
|
+
<a href="#" id="prev_titles_bottom" onclick="nearby.go('prev'); return false;" onmouseout="$(this).down().src = "http://static0.urbandictionary.com/images/uparrow.gif?1314062439"" onmouseover="$(this).down().src = "http://static3.urbandictionary.com/images/uparrow_dark.gif?1314062439""><img src="http://static0.urbandictionary.com/images/uparrow.gif?1314062439" /></a>
|
101
|
+
<a href="#" id="next_titles_bottom" onclick="nearby.go('next'); return false;" onmouseout="$(this).down().src = "http://static3.urbandictionary.com/images/downarrow.gif?1314062439"" onmouseover="$(this).down().src = "http://static2.urbandictionary.com/images/downarrow_dark.gif?1314062439""><img src="http://static3.urbandictionary.com/images/downarrow.gif?1314062439" /></a>
|
102
|
+
</div>
|
103
|
+
|
104
|
+
</td>
|
105
|
+
<td>
|
106
|
+
<div id='content'><!-- google_ad_section_start --><style>
|
107
|
+
.related_words { padding: 9px; border: 1px solid #F9C365; margin-bottom: 12px; }
|
108
|
+
</style>
|
109
|
+
<div class='related_words text'>
|
110
|
+
<span id='tags'>
|
111
|
+
<b>
|
112
|
+
thesaurus for
|
113
|
+
<a href="/thesaurus.php?term=impromptu">impromptu</a>:
|
114
|
+
</b>
|
115
|
+
<br />
|
116
|
+
|
117
|
+
<a href="/define.php?term=speech" class="urbantip">speech</a>
|
118
|
+
|
119
|
+
<a href="/define.php?term=bitch" class="urbantip">bitch</a>
|
120
|
+
|
121
|
+
<a href="/define.php?term=ad-lib" class="urbantip">ad-lib</a>
|
122
|
+
|
123
|
+
<a href="/define.php?term=extemporaneous" class="urbantip">extemporaneous</a>
|
124
|
+
|
125
|
+
<a href="/define.php?term=party" class="urbantip">party</a>
|
126
|
+
<a href="/thesaurus.php?term=impromptu">more...</a>
|
127
|
+
</span>
|
128
|
+
</div>
|
129
|
+
|
130
|
+
<table id='entries'>
|
131
|
+
<tr>
|
132
|
+
<td class='index'>
|
133
|
+
<a href="http://impromptu.urbanup.com/266132">1.</a>
|
134
|
+
</td>
|
135
|
+
<td class='word'>
|
136
|
+
impromptu
|
137
|
+
</td>
|
138
|
+
<td class='tools' id='tools_266132'>
|
139
|
+
<span class='status'></span>
|
140
|
+
<span class='thumbs'></span>
|
141
|
+
</td>
|
142
|
+
</tr>
|
143
|
+
<tr>
|
144
|
+
<td></td>
|
145
|
+
<td class='text' colspan='2' id='entry_266132'>
|
146
|
+
<div class="definition">Something that is made up on the spot and given little time to gather and present. Usually referring to speeches that are given only a few minutes to prepare for. </div><div class="example">I had to write an impromptu speech about Anal Cancer in 3 minutes without using the word 'ass' 'anus' 'shit' or 'hair'.</div>
|
147
|
+
<div class="zazzle_links"><a href="/products.php?term=impromptu&defid=266132"><span class="zazzle_link_text">buy impromptu mugs & shirts</span></a></div>
|
148
|
+
<div class='greenery'>
|
149
|
+
by <a href="/author.php?author=Bastardized+Bottomburp" class="author urbantip">Bastardized Bottomburp</a>
|
150
|
+
<span class='date'>
|
151
|
+
Sep 26, 2003
|
152
|
+
</span>
|
153
|
+
<a href="#" id="share_this_266132" onclick="emailer.toggle($("share_this_266132"), "http://impromptu.urbanup.com/266132", "Entry", 266132, "http://twitter.com/share?text=impromptu%20-%20Something%20that%20is%20made%20up%20on%20the%20spot%20and%20given%20little%20time%20to%20gather%20and%20present.%20U...\u0026url=http%3A%2F%2Furbanup.com%2F266132\u0026via=urbandictionary"); return false;">share this</a>
|
154
|
+
<a href="/video.php?defid=266132&word=impromptu">add a video</a>
|
155
|
+
</div>
|
156
|
+
</td>
|
157
|
+
</tr>
|
158
|
+
|
159
|
+
<tr>
|
160
|
+
<td class='index'>
|
161
|
+
<a href="http://impromptu.urbanup.com/313210">2.</a>
|
162
|
+
</td>
|
163
|
+
<td class='word'>
|
164
|
+
impromptu
|
165
|
+
</td>
|
166
|
+
<td class='tools' id='tools_313210'>
|
167
|
+
<span class='status'></span>
|
168
|
+
<span class='thumbs'></span>
|
169
|
+
</td>
|
170
|
+
</tr>
|
171
|
+
<tr>
|
172
|
+
<td></td>
|
173
|
+
<td class='text' colspan='2' id='entry_313210'>
|
174
|
+
<div class="definition">On the spot</div><div class="example">When my chik walked in on me with my mistress, I had to make up an impromptu excuse for why my purple headed yogurt slinger was in her tuna taco.</div>
|
175
|
+
<div class="zazzle_links"><a href="/products.php?term=impromptu&defid=313210"><span class="zazzle_link_text">buy impromptu mugs & shirts</span></a></div>
|
176
|
+
<div class='greenery'>
|
177
|
+
by <a href="/author.php?author=Vigilante+DB" class="author urbantip">Vigilante DB</a>
|
178
|
+
<span class='date'>
|
179
|
+
Oct 25, 2003
|
180
|
+
</span>
|
181
|
+
<a href="#" id="share_this_313210" onclick="emailer.toggle($("share_this_313210"), "http://impromptu.urbanup.com/313210", "Entry", 313210, "http://twitter.com/share?text=impromptu%20-%20On%20the%20spot\u0026url=http%3A%2F%2Furbanup.com%2F313210\u0026via=urbandictionary"); return false;">share this</a>
|
182
|
+
<a href="/video.php?defid=313210&word=impromptu">add a video</a>
|
183
|
+
</div>
|
184
|
+
</td>
|
185
|
+
</tr>
|
186
|
+
|
187
|
+
<tr>
|
188
|
+
<td class='index'>
|
189
|
+
<a href="http://impromptu.urbanup.com/263663">3.</a>
|
190
|
+
</td>
|
191
|
+
<td class='word'>
|
192
|
+
impromptu
|
193
|
+
</td>
|
194
|
+
<td class='tools' id='tools_263663'>
|
195
|
+
<span class='status'></span>
|
196
|
+
<span class='thumbs'></span>
|
197
|
+
</td>
|
198
|
+
</tr>
|
199
|
+
<tr>
|
200
|
+
<td></td>
|
201
|
+
<td class='text' colspan='2' id='entry_263663'>
|
202
|
+
<div class="definition">Something that is made up on the spot. Can also mean a speech that was made with little or no preparation.</div><div class="example">The drug dealer had to come up with an impromptu excuse to his boss for losing the shipment of crack to the police.</div>
|
203
|
+
<div class="zazzle_links"><a href="/products.php?term=impromptu&defid=263663"><span class="zazzle_link_text">buy impromptu mugs & shirts</span></a></div>
|
204
|
+
<div class='greenery'>
|
205
|
+
by <a href="/author.php?author=AYB" class="author urbantip">AYB</a>
|
206
|
+
<span class='date'>
|
207
|
+
Sep 24, 2003
|
208
|
+
</span>
|
209
|
+
<a href="#" id="share_this_263663" onclick="emailer.toggle($("share_this_263663"), "http://impromptu.urbanup.com/263663", "Entry", 263663, "http://twitter.com/share?text=impromptu%20-%20Something%20that%20is%20made%20up%20on%20the%20spot.%20Can%20also%20mean%20a%20speech%20that%20was%20made%20with%20lit...\u0026url=http%3A%2F%2Furbanup.com%2F263663\u0026via=urbandictionary"); return false;">share this</a>
|
210
|
+
<a href="/video.php?defid=263663&word=impromptu">add a video</a>
|
211
|
+
</div>
|
212
|
+
</td>
|
213
|
+
</tr>
|
214
|
+
|
215
|
+
<tr>
|
216
|
+
<td colspan='3' style='padding: 10px 0 30px 0'>
|
217
|
+
<div style='width: 300px; margin: 0 auto'>
|
218
|
+
<script type="text/javascript">
|
219
|
+
//<![CDATA[
|
220
|
+
var googletag = googletag || {};
|
221
|
+
googletag.cmd = googletag.cmd || [];
|
222
|
+
googletag.cmd.push(function() {
|
223
|
+
googletag.defineUnit('/1031683/ca-pub-4733233155277872/HP_ATF_300x250', [300, 250], 'dfp_homepage_medium_rectangle').addService(googletag.pubads());
|
224
|
+
googletag.defineUnit('/1031683/ca-pub-4733233155277872/HP_BTF_300x250', [300, 250], 'dfp_homepage_medium_rectangle_below').addService(googletag.pubads());
|
225
|
+
googletag.defineUnit('/1031683/ca-pub-4733233155277872/ROS_BTF_728x90', [728, 90], 'dfp_every_page_leaderboard').addService(googletag.pubads());
|
226
|
+
googletag.defineUnit('/1031683/ca-pub-4733233155277872/ROS_Right_160x60', [160, 600], 'dfp_skyscraper').addService(googletag.pubads());
|
227
|
+
googletag.defineUnit('/1031683/ca-pub-4733233155277872/Define_300x250', [300, 250], 'dfp_define_rectangle').addService(googletag.pubads());
|
228
|
+
googletag.defineUnit('/1031683/ca-pub-4733233155277872/ROS_500x250', [475, 250], 'dfp_define_double_rectangle').addService(googletag.pubads());
|
229
|
+
|
230
|
+
googletag.pubads().set("alternate_ad_url", "http://www.urbandictionary.com/google_alternate_ad.html");
|
231
|
+
googletag.pubads().setTargeting("safe_word", "false");
|
232
|
+
|
233
|
+
googletag.pubads().enableSingleRequest();
|
234
|
+
googletag.enableServices();
|
235
|
+
});
|
236
|
+
|
237
|
+
(function() {
|
238
|
+
var gads = document.createElement('script');
|
239
|
+
gads.async = true;
|
240
|
+
gads.type = 'text/javascript';
|
241
|
+
gads.src = "http://www.googletagservices.com/tag/js/gpt.js";
|
242
|
+
var node = document.getElementsByTagName('script')[0];
|
243
|
+
node.parentNode.insertBefore(gads, node);
|
244
|
+
})();
|
245
|
+
|
246
|
+
//]]>
|
247
|
+
</script><div id="dfp_define_rectangle" style="width: 300px; height: 250px"><script type="text/javascript">
|
248
|
+
//<![CDATA[
|
249
|
+
googletag.cmd.push(function() { googletag.display('dfp_define_rectangle'); });
|
250
|
+
//]]>
|
251
|
+
</script></div>
|
252
|
+
</div>
|
253
|
+
</td>
|
254
|
+
</tr>
|
255
|
+
|
256
|
+
</table>
|
257
|
+
<div id='paginator'>
|
258
|
+
|
259
|
+
</div>
|
260
|
+
<!-- google_ad_section_end --><div id='email_pane' style='display: none'>
|
261
|
+
<form action='javascript:void(0)' onsubmit='emailer.sendEmail(); return false'>
|
262
|
+
<table cellpadding='0' cellspacing='0'>
|
263
|
+
<tr>
|
264
|
+
<th>
|
265
|
+
<label for='permalink'>permalink:</label>
|
266
|
+
</th>
|
267
|
+
<td>
|
268
|
+
<input id='permalink' name='permalink' onclick='this.focus(); this.select()' type='text' />
|
269
|
+
<input id='shared_id' name='share[shared_id]' type='hidden' />
|
270
|
+
<input id='shared_type' name='share[shared_type]' type='hidden' value='Entry' />
|
271
|
+
</td>
|
272
|
+
</tr>
|
273
|
+
<tr>
|
274
|
+
<td></td>
|
275
|
+
<td>
|
276
|
+
Share on
|
277
|
+
<span id='share_links'></span>
|
278
|
+
</td>
|
279
|
+
</tr>
|
280
|
+
<tr id='sendtoafriend'>
|
281
|
+
<td></td>
|
282
|
+
<td>
|
283
|
+
<label for='yours'>Send to a friend</label>
|
284
|
+
</td>
|
285
|
+
</tr>
|
286
|
+
<tr>
|
287
|
+
<th>
|
288
|
+
<label for='yours'>your email:</label>
|
289
|
+
</th>
|
290
|
+
<td>
|
291
|
+
<input id='yours' name='share[yours]' type='text' />
|
292
|
+
</td>
|
293
|
+
</tr>
|
294
|
+
<tr>
|
295
|
+
<th>
|
296
|
+
<label for='theirs'>their email:</label>
|
297
|
+
</th>
|
298
|
+
<td>
|
299
|
+
<input id='theirs' name='share[theirs]' type='text' />
|
300
|
+
</td>
|
301
|
+
</tr>
|
302
|
+
<tr>
|
303
|
+
<th>
|
304
|
+
<label for='comment'>comment:</label>
|
305
|
+
</th>
|
306
|
+
<td>
|
307
|
+
<textarea id="comment" name="share[comment]" rows="3"></textarea>
|
308
|
+
</td>
|
309
|
+
</tr>
|
310
|
+
<tr>
|
311
|
+
<td></td>
|
312
|
+
<td>
|
313
|
+
<input id='subscribe' name='subscribe' type='checkbox' />
|
314
|
+
<label for='subscribe'> send me the word of the day (it's free)</label>
|
315
|
+
</td>
|
316
|
+
</tr>
|
317
|
+
<tr id='submit'>
|
318
|
+
<td></td>
|
319
|
+
<td>
|
320
|
+
<table>
|
321
|
+
<tr>
|
322
|
+
<td>
|
323
|
+
<input type='submit' value='Send message' />
|
324
|
+
</td>
|
325
|
+
<td id='status'></td>
|
326
|
+
</tr>
|
327
|
+
</table>
|
328
|
+
</td>
|
329
|
+
</tr>
|
330
|
+
</table>
|
331
|
+
</form>
|
332
|
+
</div>
|
333
|
+
|
334
|
+
</div>
|
335
|
+
</td>
|
336
|
+
<td id='rightist'>
|
337
|
+
<div id="dfp_skyscraper" style="width: 160px; height: 600px"><script type="text/javascript">
|
338
|
+
//<![CDATA[
|
339
|
+
googletag.cmd.push(function() { googletag.display('dfp_skyscraper'); });
|
340
|
+
//]]>
|
341
|
+
</script></div>
|
342
|
+
</td>
|
343
|
+
</tr>
|
344
|
+
</table>
|
345
|
+
|
346
|
+
<div id='bottomad'>
|
347
|
+
<div id="dfp_every_page_leaderboard" style="width: 728px; height: 90px; margin: 0 auto"><script type="text/javascript">
|
348
|
+
//<![CDATA[
|
349
|
+
googletag.cmd.push(function() { googletag.display('dfp_every_page_leaderboard'); });
|
350
|
+
//]]>
|
351
|
+
</script></div>
|
352
|
+
</div>
|
353
|
+
</div>
|
354
|
+
<div id='copyright'>
|
355
|
+
<a href="/">Urban Dictionary</a>
|
356
|
+
<span id='years'>
|
357
|
+
©1999-2011
|
358
|
+
</span>
|
359
|
+
<a href='/tos.php'>terms of service</a>
|
360
|
+
<a href='/privacy.php'>privacy</a>
|
361
|
+
<a href='/feedback.php'>feedback</a>
|
362
|
+
<a href='/editor/remove.php'>remove</a>
|
363
|
+
<a href='/ads.php'>advertise</a>
|
364
|
+
<a href='/poweredby.php'>technology</a>
|
365
|
+
<a href='http://jobs.urbandictionary.com/'>jobs</a>
|
366
|
+
<a href="/live_support.php" id="live_support" onclick="popAndFocus("/live_support.php", "live support"); return false;" style="display: none">live support</a>
|
367
|
+
</div>
|
368
|
+
|
369
|
+
<table class='offsite'>
|
370
|
+
<tr>
|
371
|
+
<td>
|
372
|
+
<table class='facebook'>
|
373
|
+
<tr>
|
374
|
+
<td>
|
375
|
+
<a href="http://feeds.urbandictionary.com/UrbanWordOfTheDay" onclick="urchinTracker("/outgoing/http_feeds_urbandictionary_com_UrbanWordOfTheDay")"><div class="rss_image"></div></a>
|
376
|
+
</td>
|
377
|
+
<td>
|
378
|
+
<a href="http://feeds.urbandictionary.com/UrbanWordOfTheDay" onclick="urchinTracker("/outgoing/http_feeds_urbandictionary_com_UrbanWordOfTheDay")">add via <b>rss</b></a>
|
379
|
+
<br />
|
380
|
+
<a href="http://www.google.com/calendar/render?cid=http%3A%2F%2Fwww.urbandictionary.com%2Fdaily.ics" onclick="urchinTracker("/outgoing/http_www_google_com_calendar_render_cid_http_A_F_Fwww_urbandictionary_com_Fdaily_ics")">or <b>google calendar</b></a>
|
381
|
+
</td>
|
382
|
+
</tr>
|
383
|
+
</table>
|
384
|
+
</td>
|
385
|
+
<td>
|
386
|
+
<table class='facebook'>
|
387
|
+
<tr>
|
388
|
+
<td>
|
389
|
+
<a href="http://www.facebook.com/profile.php?id=6295613171" onclick="urchinTracker("/outgoing/http_www_facebook_com_profile_php_id")"><div class="facebook_image"></div></a>
|
390
|
+
</td>
|
391
|
+
<td>
|
392
|
+
<a href="http://www.facebook.com/profile.php?id=6295613171" onclick="urchinTracker("/outgoing/http_www_facebook_com_profile_php_id")">add <b>urban dictionary</b><br/>on <b>facebook</b></a>
|
393
|
+
</td>
|
394
|
+
</tr>
|
395
|
+
</table>
|
396
|
+
</td>
|
397
|
+
<td>
|
398
|
+
<table class='facebook'>
|
399
|
+
<tr>
|
400
|
+
<td>
|
401
|
+
<div class='iphone_image'></div>
|
402
|
+
</td>
|
403
|
+
<td>
|
404
|
+
search ud
|
405
|
+
<br />
|
406
|
+
<a href="http://iphone.urbandictionary.com/" onclick="urchinTracker("/outgoing/http_iphone_urbandictionary_com")">from your <b>phone</b></a>
|
407
|
+
<br />
|
408
|
+
<a href="/sms.php" onclick="urchinTracker("/outgoing/sms_php")">or via <b>txt</b></a>
|
409
|
+
</td>
|
410
|
+
</tr>
|
411
|
+
</table>
|
412
|
+
</td>
|
413
|
+
<td>
|
414
|
+
<table class='facebook'>
|
415
|
+
<tr>
|
416
|
+
<td>
|
417
|
+
<a href="http://twitter.com/urbandaily/" onclick="urchinTracker("/outgoing/http_twitter_com_urbandaily")"><div class="twitter_image"></div></a>
|
418
|
+
</td>
|
419
|
+
<td>
|
420
|
+
<a href="http://twitter.com/urbandaily/" onclick="urchinTracker("/outgoing/http_twitter_com_urbandaily")"><b>follow urbandaily</b><br/>on twitter</a>
|
421
|
+
</td>
|
422
|
+
</tr>
|
423
|
+
</table>
|
424
|
+
</td>
|
425
|
+
</tr>
|
426
|
+
</table>
|
427
|
+
|
428
|
+
</div>
|
429
|
+
<script src="http://static2.urbandictionary.com/assets/base.js?1314062438" type="text/javascript"></script>
|
430
|
+
<script type='text/javascript'>
|
431
|
+
//<![CDATA[
|
432
|
+
var host_env = new HostEnv(document.location.hostname);
|
433
|
+
Uncacheable.instance.load([266132,313210,263663], host_env.uncacheableUrl());
|
434
|
+
//]]>
|
435
|
+
</script>
|
436
|
+
|
437
|
+
|
438
|
+
|
439
|
+
<script type="text/javascript">
|
440
|
+
|
441
|
+
var _gaq = _gaq || [];
|
442
|
+
_gaq.push(['_setAccount', "UA-31805-1"]);
|
443
|
+
_gaq.push(['_trackPageview']);
|
444
|
+
|
445
|
+
(function() {
|
446
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
447
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
448
|
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
449
|
+
})();
|
450
|
+
|
451
|
+
</script>
|
452
|
+
|
453
|
+
<!-- Start Quantcast tag -->
|
454
|
+
<script type="text/javascript" src="http://edge.quantserve.com/quant.js"></script>
|
455
|
+
<script type="text/javascript">
|
456
|
+
_qacct="p-77H27_lnOeCCI";quantserve();</script>
|
457
|
+
<noscript>
|
458
|
+
<img src="http://pixel.quantserve.com/pixel/p-77H27_lnOeCCI.gif" style="display: none" height="1" width="1" alt=""/></noscript>
|
459
|
+
<!-- End Quantcast tag -->
|
460
|
+
|
461
|
+
|
462
|
+
<script type="text/javascript" charset="utf-8">NREUMQ.push(["nrf2","beacon-1.newrelic.com","77b5945d2d",131063,"cFoIQEcMXQ5TSh4FB1VcCFEaCl8GU0A=",1,41])</script></body>
|
463
|
+
</html>
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'urban'
|
5
|
+
require 'urban/cli'
|
6
|
+
|
7
|
+
TEST_PHRASE = OpenStruct.new({
|
8
|
+
word: 'impromptu',
|
9
|
+
definitions: [
|
10
|
+
'Something that is made up on the spot and given little time to gather and present. Usually referring to speeches that are given only a few minutes to prepare for.',
|
11
|
+
'On the spot',
|
12
|
+
'Something that is made up on the spot. Can also mean a speech that was made with little or no preparation.'
|
13
|
+
]})
|
14
|
+
|
15
|
+
def load_file(filename)
|
16
|
+
IO.read(File.expand_path("../data/#{filename}", __FILE__))
|
17
|
+
end
|
18
|
+
|
19
|
+
['refute', 'assert'].each do |action|
|
20
|
+
eval <<-EOM
|
21
|
+
def #{action}_cli_prints(matches, &block)
|
22
|
+
out, err = capture_io(&block)
|
23
|
+
[*matches].each { |match| #{action}_match(match, out) }
|
24
|
+
end
|
25
|
+
EOM
|
26
|
+
end
|
27
|
+
|
28
|
+
module Stub
|
29
|
+
def stub(name, &block)
|
30
|
+
self.class.send(:remove_method, name) if respond_to?(name)
|
31
|
+
self.class.send(:define_method, name, &block)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CLITest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@program = Urban::CLI.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_parse_prints_help
|
10
|
+
expectations = [
|
11
|
+
/Usage: urban \[OPTION\]\.\.\. \[PHRASE\]/,
|
12
|
+
/Search http:\/\/urbandictionary\.com for definitions/,
|
13
|
+
/-l, --list\s*List all definitions/,
|
14
|
+
/-r, --random\s*Find random word on urban dictionary/,
|
15
|
+
/-h, --help\s*Show this message/,
|
16
|
+
/-version\s*Show version/
|
17
|
+
]
|
18
|
+
assert_cli_prints(expectations) { @program.run(["-h"]) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_parse_prints_version_info
|
22
|
+
args = ['-v']
|
23
|
+
assert_cli_prints(/^Urban \d+\.\d+\.\d+ \(c\) Thomas Miller$/) { @program.run(args) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_no_args_prints_help
|
27
|
+
args = []
|
28
|
+
assert_cli_prints(/Usage: urban \[OPTION\]\.\.\. \[PHRASE\]/) { @program.run(args) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_no_args_with_list_option_prints_help
|
32
|
+
args = ['-l']
|
33
|
+
assert_cli_prints(/Usage: urban \[OPTION\]\.\.\. \[PHRASE\]/) { @program.run(args) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_parse_returns_random
|
37
|
+
capture_io do
|
38
|
+
actual = @program.send(:parse, ['-r'])
|
39
|
+
assert(actual.random, 'Args -r; Expected true, returned false')
|
40
|
+
actual = @program.send(:parse, ['--random'])
|
41
|
+
assert(actual.random, 'Args --random Expected true, returned false')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_parse_returns_list
|
46
|
+
capture_io do
|
47
|
+
actual = @program.send(:parse, ['-l'])
|
48
|
+
assert(actual.list, 'Args: -l; Expected true, returned false')
|
49
|
+
actual = @program.send(:parse, ['--list'])
|
50
|
+
assert(actual.list, 'Args: --list; Expected true, returned false')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_parse_returns_phrase
|
55
|
+
capture_io do
|
56
|
+
actual = @program.send(:parse, ['Cookie', 'monster'])
|
57
|
+
assert_equal('Cookie monster', actual.phrase)
|
58
|
+
actual = @program.send(:parse, ['Cookie monster'])
|
59
|
+
assert_equal('Cookie monster', actual.phrase)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class CLIDefinintionOutputTest < CLITest
|
64
|
+
def setup
|
65
|
+
@dictionary = MiniTest::Mock.new
|
66
|
+
super
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_cli_prints_random_definition
|
70
|
+
args = ['-r']
|
71
|
+
expected = [ "#{TEST_PHRASE.word.upcase}", TEST_PHRASE.definitions.first ]
|
72
|
+
@program.dictionary = @dictionary.expect(:random, TEST_PHRASE)
|
73
|
+
assert_cli_prints(expected) { @program.run(args) }
|
74
|
+
@dictionary.verify
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_cli_prints_random_definition_list
|
78
|
+
args = ['-rl']
|
79
|
+
expected = [ "#{TEST_PHRASE.word.upcase}", *TEST_PHRASE.definitions ]
|
80
|
+
@program.dictionary = @dictionary.expect(:random, TEST_PHRASE)
|
81
|
+
assert_cli_prints(expected) { @program.run(args) }
|
82
|
+
@dictionary.verify
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_cli_prints_definition
|
86
|
+
args = ['impromptu']
|
87
|
+
expected = [ "#{TEST_PHRASE.word.upcase}", TEST_PHRASE.definitions.first ]
|
88
|
+
@program.dictionary = @dictionary.expect(:search, TEST_PHRASE, ['impromptu'])
|
89
|
+
assert_cli_prints(expected) { @program.run(['impromptu']) }
|
90
|
+
@dictionary.verify
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_cli_prints_definition_list
|
94
|
+
args = ['-l', 'impromptu']
|
95
|
+
expected = [ "#{TEST_PHRASE.word.upcase}", *TEST_PHRASE.definitions ]
|
96
|
+
@program.dictionary = @dictionary.expect(:search, TEST_PHRASE, ['impromptu'])
|
97
|
+
assert_cli_prints(expected) { @program.run(args) }
|
98
|
+
@dictionary.verify
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DictionaryTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@web_service = MiniTest::Mock.new
|
7
|
+
@dictionary = Urban::Dictionary.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_dictionary_calls_random
|
11
|
+
@dictionary.web_service = @web_service.expect(:query, load_file('impromptu.html') ,[:random])
|
12
|
+
assert_equal(TEST_PHRASE, @dictionary.random)
|
13
|
+
@web_service.verify
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_dictionary_calls_define
|
17
|
+
@dictionary.web_service = @web_service.expect(:query, load_file('impromptu.html'), [:define, 'impromptu'])
|
18
|
+
assert_equal(TEST_PHRASE, @dictionary.search('impromptu'))
|
19
|
+
@web_service.verify
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class WebTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@web_service = (Urban::Web.new).extend Stub
|
7
|
+
@web_service.stub(:open) { |arg| return arg; }
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_web_sends_request_to_random
|
11
|
+
expected = 'http://www.urbandictionary.com/random.php'
|
12
|
+
actual = @web_service.query(:random)
|
13
|
+
assert_equal(expected, actual)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_web_sends_request_to_define_with_phrase
|
17
|
+
expected = 'http://www.urbandictionary.com/define.php?term=Cookie%20monster'
|
18
|
+
actual = @web_service.query(:define, 'Cookie monster')
|
19
|
+
assert_equal(expected, actual)
|
20
|
+
end
|
21
|
+
end
|
data/urban.gemspec
CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Urban::VERSION
|
8
8
|
s.authors = ['Thomas Miller']
|
9
9
|
s.email = ['jackerran@gmail.com']
|
10
|
+
s.licenses = ['MIT']
|
10
11
|
s.homepage = 'https://github.com/tmiller/urban'
|
11
12
|
s.summary = %q{A command line tool that interfaces with Urban Dictionary.}
|
12
13
|
s.description = %q{Urban is a command line tool that allows you to look up definitions
|
@@ -19,6 +20,6 @@ Gem::Specification.new do |s|
|
|
19
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
21
|
s.require_paths = ['lib']
|
21
22
|
|
22
|
-
s.add_dependency 'nokogiri'
|
23
|
-
s.add_development_dependency '
|
23
|
+
s.add_dependency 'nokogiri', '>= 1.5.0'
|
24
|
+
s.add_development_dependency 'rake', '>= 0.8.7'
|
24
25
|
end
|
metadata
CHANGED
@@ -1,54 +1,48 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: urban
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.0.12
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Thomas Miller
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-09-02 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
17
15
|
name: nokogiri
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &2153564560 !ruby/object:Gem::Requirement
|
20
17
|
none: false
|
21
|
-
requirements:
|
22
|
-
- -
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version:
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.5.0
|
25
22
|
type: :runtime
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: ruby-debug19
|
29
23
|
prerelease: false
|
30
|
-
|
24
|
+
version_requirements: *2153564560
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &2153564060 !ruby/object:Gem::Requirement
|
31
28
|
none: false
|
32
|
-
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version:
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.8.7
|
36
33
|
type: :development
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
email:
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2153564060
|
36
|
+
description: ! "Urban is a command line tool that allows you to look up definitions\n
|
37
|
+
\ or pull a random definition from Urban Dictionary."
|
38
|
+
email:
|
42
39
|
- jackerran@gmail.com
|
43
|
-
executables:
|
40
|
+
executables:
|
44
41
|
- urban
|
45
42
|
extensions: []
|
46
|
-
|
47
43
|
extra_rdoc_files: []
|
48
|
-
|
49
|
-
files:
|
44
|
+
files:
|
50
45
|
- .gitignore
|
51
|
-
- .rvmrc
|
52
46
|
- Gemfile
|
53
47
|
- LICENSE
|
54
48
|
- README.rdoc
|
@@ -58,34 +52,41 @@ files:
|
|
58
52
|
- lib/urban/cli.rb
|
59
53
|
- lib/urban/dictionary.rb
|
60
54
|
- lib/urban/version.rb
|
55
|
+
- lib/urban/web.rb
|
56
|
+
- test/data/impromptu.html
|
57
|
+
- test/test_helper.rb
|
58
|
+
- test/urban/cli_test.rb
|
59
|
+
- test/urban/dictionary_test.rb
|
60
|
+
- test/urban/web_test.rb
|
61
61
|
- urban.gemspec
|
62
|
-
has_rdoc: true
|
63
62
|
homepage: https://github.com/tmiller/urban
|
64
|
-
licenses:
|
65
|
-
|
63
|
+
licenses:
|
64
|
+
- MIT
|
66
65
|
post_install_message:
|
67
66
|
rdoc_options: []
|
68
|
-
|
69
|
-
require_paths:
|
67
|
+
require_paths:
|
70
68
|
- lib
|
71
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
70
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version:
|
77
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
76
|
none: false
|
79
|
-
requirements:
|
80
|
-
- -
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version:
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
83
81
|
requirements: []
|
84
|
-
|
85
82
|
rubyforge_project: urban
|
86
|
-
rubygems_version: 1.6
|
83
|
+
rubygems_version: 1.8.6
|
87
84
|
signing_key:
|
88
85
|
specification_version: 3
|
89
86
|
summary: A command line tool that interfaces with Urban Dictionary.
|
90
|
-
test_files:
|
91
|
-
|
87
|
+
test_files:
|
88
|
+
- test/data/impromptu.html
|
89
|
+
- test/test_helper.rb
|
90
|
+
- test/urban/cli_test.rb
|
91
|
+
- test/urban/dictionary_test.rb
|
92
|
+
- test/urban/web_test.rb
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm --create use "ruby-1.9.2-p180@urban"
|