urban 0.0.12 → 0.1.0
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.
- 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"
|