wlapi 0.8.1 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +2 -2
- data/{CHANGELOG → CHANGELOG.rdoc} +14 -4
- data/{LICENSE → LICENSE.rdoc} +0 -0
- data/{README → README.rdoc} +28 -3
- data/lib/wlapi/api.rb +120 -49
- data/lib/wlapi/error.rb +16 -0
- data/lib/wlapi/version.rb +1 -1
- data/test/test_api.rb +205 -163
- metadata +16 -57
data/.yardopts
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
== COMPLETED
|
2
|
+
=== 0.8.3
|
3
|
+
Implemented a simple error handling strategy, it is possible to intercept
|
4
|
+
the <tt>WLAPI::Error</tt> which covers all error types.
|
5
|
+
|
6
|
+
Added error for inconvinient user argumets.
|
7
|
+
|
8
|
+
Added new tests and refactored old tests.
|
2
9
|
=== 0.8.1
|
3
10
|
Moved to dependency management via Bundler.
|
4
11
|
=== 0.8.0
|
@@ -15,11 +22,14 @@ Initial release of the lib.
|
|
15
22
|
|
16
23
|
|
17
24
|
== PLANNED
|
18
|
-
=== 0.8.
|
25
|
+
=== 0.8.4
|
26
|
+
Test the lib against mri, rbx, jruby, win rubies.
|
27
|
+
=== 0.8.5
|
19
28
|
Introduce +nokogiri+ for parsing responses.
|
20
|
-
|
21
|
-
=== 0.8.
|
22
|
-
|
29
|
+
=== 0.8.6
|
30
|
+
=== 0.8.7
|
31
|
+
=== 0.8.8
|
32
|
+
=== 0.8.9
|
23
33
|
=== 0.9.0
|
24
34
|
=== 1.0.0
|
25
35
|
|
data/{LICENSE → LICENSE.rdoc}
RENAMED
File without changes
|
data/{README → README.rdoc}
RENAMED
@@ -1,8 +1,10 @@
|
|
1
1
|
= WLAPI
|
2
2
|
|
3
3
|
* {RubyGems}[http://rubygems.org/gems/wlapi]
|
4
|
-
* Developers {Homepage}[http://
|
5
|
-
* {WLAPI Project Page}[http://
|
4
|
+
* Developers {Homepage}[http://bu.chsta.be/]
|
5
|
+
* {WLAPI Project Page}[http://bu.chsta.be/projects/wlapi/]
|
6
|
+
* {Source Code}[https://github.com/arbox/wlapi]
|
7
|
+
* {Bug Tracker}[https://github.com/arbox/wlapi/issues]
|
6
8
|
|
7
9
|
== DESCRIPTION
|
8
10
|
WLAPI is a programmatic API for web services provided by the project
|
@@ -22,7 +24,6 @@ You can use the following search methods:
|
|
22
24
|
* domain;
|
23
25
|
* experimental_synonyms;
|
24
26
|
* frequencies;
|
25
|
-
* intersection;
|
26
27
|
* left_collocation_finder;
|
27
28
|
* left_neighbours;
|
28
29
|
* right_collocation_finder;
|
@@ -33,6 +34,8 @@ You can use the following search methods:
|
|
33
34
|
* thesaurus;
|
34
35
|
* wordforms.
|
35
36
|
|
37
|
+
There are three additional services by Wortschatz Leipzig: Kreuzworträtsel, MARS and Kookurrenzschnitt. They will not be implemented.
|
38
|
+
|
36
39
|
== INSTALLATION
|
37
40
|
WLAPI is provided as a .gem package. Simply install it via
|
38
41
|
{RubyGems}[http://rubygems.org/gems/wlapi].
|
@@ -66,6 +69,28 @@ credentials and instantiate an authenticated client:
|
|
66
69
|
See documentation in the WLAPI::API class for details
|
67
70
|
on particular search methods.
|
68
71
|
|
72
|
+
== EXCEPTION HIERARCHY
|
73
|
+
While using WLAPI you can face following errors:
|
74
|
+
* <tt>WLAPI::UserError</tt>;
|
75
|
+
* <tt>WLAPI::ExternalError</tt>.
|
76
|
+
|
77
|
+
The errors here are presented in the order they may occur
|
78
|
+
during WLAPI's work.
|
79
|
+
|
80
|
+
First WLAPI checks the user input and throws a <tt>WLAPI::UserError</tt>
|
81
|
+
if the arguments are not appropriate.
|
82
|
+
|
83
|
+
Then it fetches a response from a remote server, it can result
|
84
|
+
in a <tt>WLAPI::ExternalError</tt>. In most cases it will be a simple wrapper
|
85
|
+
around other errors, e.g. <tt>Savon::SOAP::Fault</tt>.
|
86
|
+
|
87
|
+
All of them are subcalsses of <tt>YANAPI::Error</tt> which is in turn a subclass
|
88
|
+
of the standard +RuntimeError+.
|
89
|
+
|
90
|
+
If you want to intercept any and every exception thrown by YANAPI simply rescue
|
91
|
+
<tt>YANAPI::Error</tt>.
|
92
|
+
|
93
|
+
|
69
94
|
== SUPPORT
|
70
95
|
If you have question, bug reports or any suggestions, please drop me an email :)
|
71
96
|
Any help is deeply appreciated!
|
data/lib/wlapi/api.rb
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
# 2010-, Andrei Beliankou
|
3
3
|
|
4
4
|
# :title: Ruby based API for Wortschatz Leipzig web services
|
5
|
-
# :main: README
|
5
|
+
# :main: README.rdoc
|
6
6
|
|
7
7
|
require 'savon'
|
8
|
+
require 'wlapi/error'
|
8
9
|
|
9
10
|
# REXML is fast enough for our task.
|
10
11
|
require 'rexml/document'
|
@@ -81,17 +82,21 @@ module WLAPI
|
|
81
82
|
# in the corpus. The higher the class, the rarer the word:
|
82
83
|
# api.frequencies("Autos") => ["40614", "9"]
|
83
84
|
def frequencies(word)
|
85
|
+
check_params(word)
|
86
|
+
|
84
87
|
arg1 = ['Wort', word]
|
85
88
|
answer = query(@cl_Frequencies, arg1)
|
86
89
|
|
87
90
|
get_answer(answer)
|
88
91
|
end
|
89
92
|
|
90
|
-
# Gets the baseform (whatever it is :) not lemma).
|
93
|
+
# Gets the baseform (whatever it is :), not lemma).
|
91
94
|
# Returns the lemmatized (base) form of the input word
|
92
95
|
# and the POS tag in an array:
|
93
96
|
# api.baseform("Auto") => ["Auto", "N"]
|
94
97
|
def baseform(word)
|
98
|
+
check_params(word)
|
99
|
+
|
95
100
|
arg1 = ['Wort', word]
|
96
101
|
answer = query(@cl_Baseform, arg1)
|
97
102
|
|
@@ -104,6 +109,8 @@ module WLAPI
|
|
104
109
|
# Is it a good name? all names are in English, but here..
|
105
110
|
# let's call it domain, not sachgebiet
|
106
111
|
def domain(word)
|
112
|
+
check_params(word)
|
113
|
+
|
107
114
|
arg1 = ['Wort', word]
|
108
115
|
answer = query(@cl_Sachgebiet, arg1)
|
109
116
|
|
@@ -116,6 +123,8 @@ module WLAPI
|
|
116
123
|
# Returns all other word forms of the same lemma for a given word form.
|
117
124
|
# api.wordforms("Auto") => ["Auto", "Autos"]
|
118
125
|
def wordforms(word, limit = 10)
|
126
|
+
check_params(word, limit)
|
127
|
+
|
119
128
|
# note, it is the only service which requires 'Word', not 'Wort'
|
120
129
|
arg1 = ['Word', word]
|
121
130
|
arg2 = ['Limit', limit]
|
@@ -129,6 +138,8 @@ module WLAPI
|
|
129
138
|
# and thus returns more synonyms:
|
130
139
|
# api.thesaurus("Auto") => ["Auto", "Bahn", "Wagen", "Zug", "Schiff", ...]
|
131
140
|
def thesaurus(word, limit = 10)
|
141
|
+
check_params(word, limit)
|
142
|
+
|
132
143
|
arg1 = ['Wort', word]
|
133
144
|
arg2 = ['Limit', limit]
|
134
145
|
answer = query(@cl_Thesaurus, arg1, arg2)
|
@@ -140,6 +151,8 @@ module WLAPI
|
|
140
151
|
# Returns synonyms of the input word. In other words, this is a thesaurus.
|
141
152
|
# api.synonyms("Auto") => ["Kraftwagen", "Automobil", "Benzinkutsche", ...]
|
142
153
|
def synonyms(word, limit = 10)
|
154
|
+
check_params(word, limit)
|
155
|
+
|
143
156
|
arg1 = ['Wort', word]
|
144
157
|
arg2 = ['Limit', limit]
|
145
158
|
answer = query(@cl_Synonyms, arg1, arg2)
|
@@ -157,6 +170,8 @@ module WLAPI
|
|
157
170
|
#--
|
158
171
|
# ok, but results should be filtered
|
159
172
|
def sentences(word, limit = 10)
|
173
|
+
check_params(word, limit)
|
174
|
+
|
160
175
|
arg1 = ['Wort', word]
|
161
176
|
arg2 = ['Limit', limit]
|
162
177
|
answer = query(@cl_Sentences, arg1, arg2)
|
@@ -170,6 +185,8 @@ module WLAPI
|
|
170
185
|
#--
|
171
186
|
# ok, but results should be filtered
|
172
187
|
def left_neighbours(word, limit = 10)
|
188
|
+
check_params(word, limit)
|
189
|
+
|
173
190
|
arg1 = ['Wort', word]
|
174
191
|
arg2 = ['Limit', limit]
|
175
192
|
answer = query(@cl_LeftNeighbours, arg1, arg2)
|
@@ -183,6 +200,8 @@ module WLAPI
|
|
183
200
|
#--
|
184
201
|
# ok, but results should be filtered
|
185
202
|
def right_neighbours(word, limit = 10)
|
203
|
+
check_params(word, limit)
|
204
|
+
|
186
205
|
arg1 = ['Wort', word]
|
187
206
|
arg2 = ['Limit', limit]
|
188
207
|
answer = query(@cl_RightNeighbours, arg1, arg2)
|
@@ -199,6 +218,8 @@ module WLAPI
|
|
199
218
|
# may take a long time.
|
200
219
|
# api.similarity("Auto") => ["Auto", "Wagen", "26", ...]
|
201
220
|
def similarity(word, limit = 10)
|
221
|
+
check_params(word, limit)
|
222
|
+
|
202
223
|
arg1 = ['Wort', word]
|
203
224
|
arg2 = ['Limit', limit]
|
204
225
|
answer = query(@cl_Similarity, arg1, arg2)
|
@@ -210,6 +231,8 @@ module WLAPI
|
|
210
231
|
#--
|
211
232
|
# don't know, if we have to include this service...
|
212
233
|
def experimental_synonyms(word, limit = 10)
|
234
|
+
check_params(word, limit)
|
235
|
+
|
213
236
|
arg1 = ['Wort', word]
|
214
237
|
arg2 = ['Limit', limit]
|
215
238
|
answer = query(@cl_ExperimentalSynonyms, arg1, arg2)
|
@@ -229,6 +252,8 @@ module WLAPI
|
|
229
252
|
# api.right_collocation_finder("Auto", "V", 10) =>
|
230
253
|
# ["Auto", "abfackeln", "V", ...]
|
231
254
|
def right_collocation_finder(word, pos, limit = 10)
|
255
|
+
check_params(word, pos, limit)
|
256
|
+
|
232
257
|
arg1 = ['Wort', word]
|
233
258
|
arg2 = ['Wortart', pos]
|
234
259
|
arg3 = ['Limit', limit]
|
@@ -246,6 +271,8 @@ module WLAPI
|
|
246
271
|
# api.left_collocation_finder("Stuhl", "A", 10) =>
|
247
272
|
# ["apostolisch", "A", "Stuhl", ...]
|
248
273
|
def left_collocation_finder(word, pos, limit = 10)
|
274
|
+
check_params(word, pos, limit)
|
275
|
+
|
249
276
|
arg1 = ['Wort', word]
|
250
277
|
arg2 = ['Wortart', pos]
|
251
278
|
arg3 = ['Limit', limit]
|
@@ -256,23 +283,31 @@ module WLAPI
|
|
256
283
|
|
257
284
|
# Returns statistically significant co-occurrences of the input word.
|
258
285
|
def cooccurrences(word, sign, limit = 10)
|
286
|
+
check_params(word, sign, limit)
|
287
|
+
|
259
288
|
arg1 = ['Wort', word]
|
260
289
|
arg2 = ['Mindestsignifikanz', sign]
|
261
290
|
arg3 = ['Limit', limit]
|
262
|
-
|
291
|
+
answer = query(@cl_Cooccurrences, arg1, arg2, arg3)
|
292
|
+
|
293
|
+
get_answer(answer)
|
263
294
|
end
|
264
295
|
|
265
296
|
# Returns statistically significant co-occurrences of the input word.
|
266
|
-
# However, it searches in the unrestricted version of the co-occurrences
|
267
|
-
# as in the Cooccurrences services,
|
297
|
+
# However, it searches in the unrestricted version of the co-occurrences
|
298
|
+
# table as in the Cooccurrences services,
|
268
299
|
# which means significantly longer wait times.
|
269
300
|
def cooccurrences_all(word, sign, limit = 10)
|
301
|
+
check_params(word, sign, limit)
|
302
|
+
|
270
303
|
arg1 = ['Wort', word]
|
271
304
|
arg2 = ['Mindestsignifikanz', sign]
|
272
305
|
arg3 = ['Limit', limit]
|
273
|
-
|
306
|
+
answer = query(@cl_CooccurrencesAll, arg1, arg2, arg3)
|
307
|
+
|
308
|
+
get_answer(answer)
|
274
309
|
end
|
275
|
-
|
310
|
+
|
276
311
|
# Returns the intersection of the co-occurrences of the two given words.
|
277
312
|
# The result set is ordered according to the sum of the significances
|
278
313
|
# in descending order. Note that due to the join involved,
|
@@ -281,13 +316,15 @@ module WLAPI
|
|
281
316
|
# let's call it intersection, not kookurrenzschnitt
|
282
317
|
# is being used INTERN, we need additional credentials
|
283
318
|
def intersection(word1, word2, limit = 10)
|
319
|
+
check_params(word1, word2, limit)
|
320
|
+
|
284
321
|
arg1 = ['Wort 1', word1]
|
285
322
|
arg2 = ['Wort 2', word2]
|
286
323
|
arg3 = ['Limit', limit]
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
324
|
+
answer = query(@cl_Kookurrenzschnitt, arg1, arg2, arg3)
|
325
|
+
|
326
|
+
get_answer(answer)
|
327
|
+
end
|
291
328
|
private
|
292
329
|
|
293
330
|
# Main query method, it invokes the soap engine.
|
@@ -296,48 +333,53 @@ module WLAPI
|
|
296
333
|
# with keys and values for the soap query.
|
297
334
|
def query(cl, *args)
|
298
335
|
# WSDL is disabled since calling the server for wsdl can last too long.
|
299
|
-
resp = cl.request(:urn, :execute) do |soap|
|
300
|
-
|
301
|
-
# Every service has a different namespace.
|
302
|
-
soap.namespaces['xmlns:urn'] = cl.wsdl.namespace
|
303
|
-
|
304
|
-
soap.namespaces['xmlns:dat'] =
|
305
|
-
"http://datatypes.webservice.wortschatz.uni_leipzig.de"
|
306
336
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
337
|
+
begin
|
338
|
+
resp = cl.request(:urn, :execute) do |soap|
|
339
|
+
|
340
|
+
# Every service has a different namespace.
|
341
|
+
soap.namespaces['xmlns:urn'] = cl.wsdl.namespace
|
342
|
+
|
343
|
+
soap.namespaces['xmlns:dat'] =
|
344
|
+
"http://datatypes.webservice.wortschatz.uni_leipzig.de"
|
345
|
+
|
346
|
+
v = []
|
347
|
+
body = {
|
348
|
+
'urn:objRequestParameters' => {
|
349
|
+
'urn:corpus' => 'de',
|
350
|
+
'urn:parameters' => {
|
351
|
+
'urn:dataVectors' => v
|
352
|
+
}
|
313
353
|
}
|
314
354
|
}
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
355
|
+
|
356
|
+
# Setting the first argument (usually 'Wort').
|
357
|
+
v << {'dat:dataRow'=>[
|
358
|
+
args[0][0],
|
359
|
+
args[0][1]
|
360
|
+
]
|
361
|
+
} if args[0]
|
362
|
+
# Setting the second argument (usually 'Limit').
|
363
|
+
v << {'dat:dataRow'=>[
|
364
|
+
args[1][0],
|
365
|
+
args[1][1]
|
366
|
+
]
|
367
|
+
} if args[1]
|
368
|
+
# Setting the third argument (no common value)
|
369
|
+
v << {'dat:dataRow'=>[
|
370
|
+
args[2][0],
|
371
|
+
args[2][1]
|
372
|
+
]
|
373
|
+
} if args[2]
|
374
|
+
|
375
|
+
soap.body = body
|
376
|
+
warn(soap.to_xml) if $DEBUG
|
377
|
+
|
378
|
+
end
|
379
|
+
rescue => e
|
380
|
+
fail(WLAPI::ExternalError, e)
|
339
381
|
end
|
340
|
-
|
382
|
+
|
341
383
|
doc = Document.new(resp.to_xml)
|
342
384
|
warn(doc) if $DEBUG
|
343
385
|
|
@@ -360,5 +402,34 @@ module WLAPI
|
|
360
402
|
result.any? ? result : nil
|
361
403
|
end
|
362
404
|
|
405
|
+
def check_params(*args)
|
406
|
+
m = caller(1).first.match(/^.+`(.*)'$/)[1]
|
407
|
+
num_of_args = self.method(m.to_sym).arity
|
408
|
+
messages = []
|
409
|
+
|
410
|
+
# Arity can be negativ => .abs.
|
411
|
+
case num_of_args.abs
|
412
|
+
when 1
|
413
|
+
messages << msg(args[0], m, 'String') unless args[0].is_a?(String)
|
414
|
+
when 2
|
415
|
+
messages << msg(args[0], m, 'String') unless args[0].is_a?(String)
|
416
|
+
messages << msg(args[1], m, 'Numeric') unless args[1].is_a?(Fixnum)
|
417
|
+
when 3
|
418
|
+
messages << msg(args[0], m, 'String') unless args[0].is_a?(String)
|
419
|
+
unless args[1].is_a?(String) || args[1].is_a?(Fixnum)
|
420
|
+
messages << msg(args[1], m, 'String or Numeric')
|
421
|
+
end
|
422
|
+
messages << msg(args[2], m, 'Numeric') unless args[2].is_a?(Fixnum)
|
423
|
+
end
|
424
|
+
|
425
|
+
if messages.any?
|
426
|
+
fail WLAPI::UserError, messages.join("\n")
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def msg(arg, meth, cls)
|
431
|
+
"Argument <#{arg}> for the method <#{meth}> should be a <#{cls}>, " +
|
432
|
+
"not <#{arg.class}>!"
|
433
|
+
end
|
363
434
|
end # class
|
364
435
|
end # module
|
data/lib/wlapi/error.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module WLAPI
|
2
|
+
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
class ExternalError < Error
|
6
|
+
def initialize(e)
|
7
|
+
msg = "Some external error occured:\n"
|
8
|
+
msg << "#{e.class}: #{e.message}"
|
9
|
+
|
10
|
+
super(msg)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class UserError < Error; end
|
15
|
+
|
16
|
+
end
|
data/lib/wlapi/version.rb
CHANGED
data/test/test_api.rb
CHANGED
@@ -1,11 +1,49 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require 'test/unit'
|
3
|
-
require 'fakeweb'
|
4
3
|
require 'wlapi'
|
5
4
|
|
6
5
|
|
7
6
|
class TestApi < Test::Unit::TestCase
|
8
7
|
|
8
|
+
METHODS = [:baseform,
|
9
|
+
:domain,
|
10
|
+
:wordforms,
|
11
|
+
:thesaurus,
|
12
|
+
:synonyms,
|
13
|
+
:sentences,
|
14
|
+
:left_neighbours,
|
15
|
+
:right_neighbours,
|
16
|
+
:similarity,
|
17
|
+
:experimental_synonyms,
|
18
|
+
:right_collocation_finder,
|
19
|
+
:left_collocation_finder,
|
20
|
+
:cooccurrences,
|
21
|
+
:cooccurrences_all,
|
22
|
+
:intersection,
|
23
|
+
:frequencies
|
24
|
+
]
|
25
|
+
|
26
|
+
ONE_PAR = [:frequencies,
|
27
|
+
:baseform,
|
28
|
+
:domain
|
29
|
+
]
|
30
|
+
|
31
|
+
THREE_PAR = [:right_collocation_finder,
|
32
|
+
:left_collocation_finder,
|
33
|
+
:cooccurrences,
|
34
|
+
:cooccurrences_all,
|
35
|
+
:intersection
|
36
|
+
]
|
37
|
+
|
38
|
+
TWO_PAR = [:wordforms,
|
39
|
+
:thesaurus,
|
40
|
+
:synonyms,
|
41
|
+
:sentences,
|
42
|
+
:left_neighbours,
|
43
|
+
:right_neighbours,
|
44
|
+
:similarity,
|
45
|
+
:experimental_synonyms
|
46
|
+
]
|
9
47
|
def setup
|
10
48
|
@api = WLAPI::API.new
|
11
49
|
@word = 'Stuhl'
|
@@ -14,232 +52,236 @@ class TestApi < Test::Unit::TestCase
|
|
14
52
|
def teardown
|
15
53
|
end
|
16
54
|
|
17
|
-
#
|
55
|
+
# Test constants.
|
18
56
|
def test_constants
|
19
57
|
assert(WLAPI::VERSION.is_a?(String))
|
20
58
|
assert_equal(false, WLAPI::VERSION.empty?)
|
21
59
|
end
|
22
|
-
=begin
|
23
|
-
# It should generate a valid soap request for some input.
|
24
|
-
def test_soap_generation
|
25
|
-
file = 'test/data/soap_request.txt'
|
26
|
-
soap = File.read(file)
|
27
|
-
|
28
|
-
url = 'http://wortschatz.uni-leipzig.de/axis/services/Thesaurus'
|
29
|
-
FakeWeb.register_uri(:post, url, :response => http_resp)
|
30
60
|
|
31
|
-
|
32
|
-
|
33
|
-
assert_equal(expected_api_answer, actual_api_answer)
|
61
|
+
def test_availability_of_pulic_methods
|
62
|
+
METHODS.each { |m| assert_respond_to(@api, m) }
|
34
63
|
end
|
35
|
-
|
36
|
-
|
37
|
-
def test_frequencies
|
38
|
-
assert_respond_to(@api, :frequencies)
|
64
|
+
|
65
|
+
def test_for_absent_arguments
|
39
66
|
assert_raise(ArgumentError) do
|
40
|
-
@api.
|
67
|
+
METHODS.each { |m| @api.send(m) }
|
41
68
|
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_for_redundant_arguments
|
72
|
+
|
42
73
|
assert_raise(ArgumentError) do
|
43
|
-
@api.
|
74
|
+
ONE_PAR.each { |m| @api.send(m, 'a', 2) }
|
44
75
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
76
|
+
|
77
|
+
assert_raise(ArgumentError) do
|
78
|
+
TWO_PAR.each { |m| @api.send(m, 'a', 2, 3) }
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
assert_raise(ArgumentError) do
|
83
|
+
THREE_PAR.each { |m| @api.send(m, 'a', 'a', 3, 4) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_argument_semantics
|
88
|
+
assert_raise(WLAPI::UserError) do
|
89
|
+
ONE_PAR.each { |m| @api.send(m, 1) }
|
90
|
+
end
|
91
|
+
=begin
|
92
|
+
assert_raise(WLAPI::UserError) do
|
93
|
+
TWO_PAR.each { |m| @api.send(m, 'Haus', 1) }
|
94
|
+
end
|
95
|
+
=end
|
96
|
+
assert_raise(WLAPI::UserError) do
|
97
|
+
THREE_PAR.each { |m| @api.send(m, 3, 3.5, 'a') }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
# One parameter.
|
101
|
+
def test_frequencies
|
102
|
+
response = @api.frequencies('Haus')
|
103
|
+
check_response(response)
|
104
|
+
|
49
105
|
assert_equal(2, response.size)
|
50
106
|
assert_match(/\d+/, response[0])
|
51
107
|
assert_match(/\d+/, response[1])
|
108
|
+
assert_equal(["122072", "7"], response)
|
52
109
|
end
|
53
110
|
|
54
111
|
def test_baseform
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
assert_raise(ArgumentError) do
|
60
|
-
@api.baseform
|
61
|
-
end
|
62
|
-
response = @api.baseform(@word)
|
63
|
-
assert_not_nil(response)
|
64
|
-
assert_instance_of(Array, response)
|
65
|
-
assert(!response.empty?)
|
112
|
+
response = @api.baseform('Autos')
|
113
|
+
check_response(response)
|
114
|
+
|
66
115
|
assert_equal(2, response.size)
|
67
116
|
assert_match(/\w+/, response[0])
|
68
117
|
assert_match(/[AVN]/, response[1])
|
118
|
+
assert_equal(["Auto", "N"], response)
|
69
119
|
end
|
70
120
|
|
71
121
|
def test_domain
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
122
|
+
response = @api.domain('Buch')
|
123
|
+
check_response(response)
|
124
|
+
|
125
|
+
expected_response = ["Sprachwissenschaft",
|
126
|
+
"Nachname",
|
127
|
+
"Stadt",
|
128
|
+
"Buchkunde/Buchhandel",
|
129
|
+
"Motive",
|
130
|
+
"Literarische/Motive/Stoffe/Gestalten",
|
131
|
+
"Buchkunde/Buchhandel",
|
132
|
+
"Papierherstellung/Graphische/Technik",
|
133
|
+
"Buchkunde/Buchhandel",
|
134
|
+
"Bücher",
|
135
|
+
"Ort in D"
|
136
|
+
]
|
137
|
+
assert_equal(expected_response, response)
|
138
|
+
# We cannot predict the minimal structure of the response.
|
84
139
|
end
|
85
140
|
|
86
141
|
# two parameters
|
87
142
|
def test_wordforms
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
143
|
+
response = @api.wordforms('Buch')
|
144
|
+
check_response(response)
|
145
|
+
|
146
|
+
expected_response = ["Buch",
|
147
|
+
"Bücher",
|
148
|
+
"Büchern",
|
149
|
+
"Buches",
|
150
|
+
"Buchs",
|
151
|
+
"Bucher"
|
152
|
+
]
|
153
|
+
assert_equal(expected_response, response)
|
99
154
|
end
|
100
155
|
|
101
156
|
def test_thesaurus
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
response = @api.thesaurus(@word)
|
110
|
-
assert_not_nil(response)
|
111
|
-
assert_instance_of(Array, response)
|
112
|
-
assert(!response.empty?)
|
157
|
+
response = @api.thesaurus('Buch')
|
158
|
+
check_response(response)
|
159
|
+
|
160
|
+
expected_response = ["Buch", "Titel", "Werk", "Zeitung", "Band",
|
161
|
+
"Literatur", "Zeitschrift", "Bruch", "Lektüre",
|
162
|
+
"Schrift"]
|
163
|
+
assert_equal(expected_response, response)
|
113
164
|
end
|
114
165
|
|
115
166
|
def test_synonyms
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
@api.synonyms(1, 2, 3)
|
122
|
-
end
|
123
|
-
response = @api.synonyms(@word)
|
124
|
-
assert_not_nil(response)
|
125
|
-
assert_instance_of(Array, response)
|
126
|
-
assert(!response.empty?)
|
167
|
+
response = @api.synonyms('Brot')
|
168
|
+
check_response(response)
|
169
|
+
|
170
|
+
expected_response = ["Laib", "Brotlaib", "Laib", "Schnitte", "Stulle"]
|
171
|
+
assert_equal(expected_response, response)
|
127
172
|
end
|
128
173
|
|
129
174
|
def test_sentences
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
@api.sentences(1, 2, 3)
|
136
|
-
end
|
137
|
-
response = @api.sentences(@word)
|
138
|
-
assert_not_nil(response)
|
139
|
-
assert_instance_of(Array, response)
|
140
|
-
assert(!response.empty?)
|
175
|
+
response = @api.sentences('Klasse', 1)
|
176
|
+
check_response(response)
|
177
|
+
expected_response = ["40829928",
|
178
|
+
"Bei den Grünen war ich wohl im Urteil der politisch korrekten Klasse bei den Richtigen, auch wenn ich in ihren Augen das Falsche sagte."]
|
179
|
+
assert_equal(expected_response, response)
|
141
180
|
end
|
142
181
|
|
143
182
|
def test_left_neighbours
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
151
|
-
response = @api.left_neighbours(@word)
|
152
|
-
assert_not_nil(response)
|
153
|
-
assert_instance_of(Array, response)
|
154
|
-
assert(!response.empty?)
|
183
|
+
response = @api.left_neighbours('Stuhl', 2)
|
184
|
+
check_response(response)
|
185
|
+
|
186
|
+
expected_response = ["elektrischen", "Stuhl", "626",
|
187
|
+
"seinem", "Stuhl", "592"]
|
188
|
+
assert_equal(expected_response, response)
|
155
189
|
end
|
156
190
|
|
157
191
|
def test_right_neighbours
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
end
|
165
|
-
response = @api.right_neighbours(@word)
|
166
|
-
assert_not_nil(response)
|
167
|
-
assert_instance_of(Array, response)
|
168
|
-
assert(!response.empty?)
|
192
|
+
response = @api.right_neighbours('Stuhl', 2)
|
193
|
+
check_response(response)
|
194
|
+
|
195
|
+
expected_response = ["Stuhl", "räumen", "189",
|
196
|
+
"Stuhl", "hin und her", "130"]
|
197
|
+
assert_equal(expected_response, response)
|
169
198
|
end
|
170
199
|
|
171
200
|
def test_similarity
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
response = @api.similarity(@word)
|
180
|
-
assert_not_nil(response)
|
181
|
-
assert_instance_of(Array, response)
|
182
|
-
assert(!response.empty?)
|
201
|
+
response = @api.similarity('Stuhl', 3)
|
202
|
+
check_response(response)
|
203
|
+
|
204
|
+
expected_response = ["Stuhl", "Sessel", "26",
|
205
|
+
"Stuhl", "Lehnstuhl", "24",
|
206
|
+
"Stuhl", "Sofa", "21"]
|
207
|
+
assert_equal(expected_response, response)
|
183
208
|
end
|
184
209
|
|
185
210
|
def test_experimental_synonyms
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
211
|
+
response = @api.experimental_synonyms('Stuhl')
|
212
|
+
check_response(response)
|
213
|
+
|
214
|
+
expected_response = ["Einrichtungsgegenstand", "v",
|
215
|
+
"Bett", "v",
|
216
|
+
"Lampe", "v",
|
217
|
+
"Tisch", "v",
|
218
|
+
"Schrank", "v",
|
219
|
+
"Teppich", "v",
|
220
|
+
"Gebrauchsmöbel", "v",
|
221
|
+
"Möbelstück", "v",
|
222
|
+
"Bank", "v",
|
223
|
+
"Bord", "v"
|
224
|
+
]
|
225
|
+
assert_equal(expected_response, response)
|
197
226
|
end
|
198
227
|
|
199
228
|
# three parameters
|
200
229
|
def test_right_collocation_finder
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
assert_not_nil(response)
|
210
|
-
assert_instance_of(Array, response)
|
211
|
-
assert(!response.empty?)
|
230
|
+
response = @api.right_collocation_finder('Stuhl', 'V', 3)
|
231
|
+
check_response(response)
|
232
|
+
|
233
|
+
expected_response = ["Stuhl", "aufmöbeln", "V",
|
234
|
+
"Stuhl", "aufreihen", "V",
|
235
|
+
"Stuhl", "aufspringen", "V"
|
236
|
+
]
|
237
|
+
assert_equal(expected_response, response)
|
212
238
|
end
|
213
239
|
|
214
240
|
def test_left_collocation_finder
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
response = @api.left_collocation_finder(@word, 'A')
|
223
|
-
assert_not_nil(response)
|
224
|
-
assert_instance_of(Array, response)
|
225
|
-
assert(!response.empty?)
|
241
|
+
response = @api.left_collocation_finder('Stuhl', 'A', 3)
|
242
|
+
check_response(response)
|
243
|
+
expected_response = ["Hl", "A", "Stuhl",
|
244
|
+
"abwaschbar", "A", "Stuhl",
|
245
|
+
"alle", "A", "Stuhl"
|
246
|
+
]
|
247
|
+
assert_equal(expected_response, response)
|
226
248
|
end
|
227
249
|
|
228
250
|
def test_cooccurrences
|
229
|
-
|
230
|
-
|
231
|
-
|
251
|
+
response = @api.cooccurrences('Haus', 10000)
|
252
|
+
check_response(response)
|
253
|
+
expected_response = ["Haus", "das", "11747"]
|
254
|
+
|
255
|
+
assert_equal(expected_response, response)
|
232
256
|
end
|
233
257
|
|
234
258
|
def test_cooccurrences_all
|
235
|
-
|
236
|
-
@api.cooccurrences_all(
|
259
|
+
begin
|
260
|
+
@api.cooccurrences_all('Haus', 10000)
|
261
|
+
rescue RuntimeError => e
|
262
|
+
assert_match(/You're not allowed to access this service./, e.message)
|
237
263
|
end
|
264
|
+
# Not possible to test without access credential.
|
238
265
|
end
|
239
266
|
|
240
267
|
def test_intersection
|
241
|
-
|
242
|
-
@api.intersection(
|
268
|
+
begin
|
269
|
+
@api.intersection('Haus', 'Brot', 1)
|
270
|
+
rescue RuntimeError => e
|
271
|
+
assert_match(/You're not allowed to access this service./, e.message)
|
243
272
|
end
|
273
|
+
# Not possible to test without access credentials.
|
274
|
+
end
|
275
|
+
|
276
|
+
|
277
|
+
################## HELPER METHODS ###############################################
|
278
|
+
def check_input(*args)
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
def check_response(response)
|
283
|
+
assert_not_nil(response)
|
284
|
+
assert_instance_of(Array, response)
|
285
|
+
assert(response.any?)
|
244
286
|
end
|
245
287
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wlapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 57
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 3
|
10
|
+
version: 0.8.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andrei Beliankou
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-12-16 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: savon
|
@@ -64,7 +64,7 @@ dependencies:
|
|
64
64
|
type: :development
|
65
65
|
version_requirements: *id003
|
66
66
|
- !ruby/object:Gem::Dependency
|
67
|
-
name:
|
67
|
+
name: yard
|
68
68
|
prerelease: false
|
69
69
|
requirement: &id004 !ruby/object:Gem::Requirement
|
70
70
|
none: false
|
@@ -78,7 +78,7 @@ dependencies:
|
|
78
78
|
type: :development
|
79
79
|
version_requirements: *id004
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
|
-
name:
|
81
|
+
name: rake
|
82
82
|
prerelease: false
|
83
83
|
requirement: &id005 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
@@ -91,48 +91,6 @@ dependencies:
|
|
91
91
|
version: "0"
|
92
92
|
type: :development
|
93
93
|
version_requirements: *id005
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
name: fakeweb
|
96
|
-
prerelease: false
|
97
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
|
-
requirements:
|
100
|
-
- - ">="
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
hash: 3
|
103
|
-
segments:
|
104
|
-
- 0
|
105
|
-
version: "0"
|
106
|
-
type: :development
|
107
|
-
version_requirements: *id006
|
108
|
-
- !ruby/object:Gem::Dependency
|
109
|
-
name: rake
|
110
|
-
prerelease: false
|
111
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
112
|
-
none: false
|
113
|
-
requirements:
|
114
|
-
- - ">="
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
hash: 3
|
117
|
-
segments:
|
118
|
-
- 0
|
119
|
-
version: "0"
|
120
|
-
type: :development
|
121
|
-
version_requirements: *id007
|
122
|
-
- !ruby/object:Gem::Dependency
|
123
|
-
name: ruby-debug
|
124
|
-
prerelease: false
|
125
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
126
|
-
none: false
|
127
|
-
requirements:
|
128
|
-
- - ">="
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
hash: 3
|
131
|
-
segments:
|
132
|
-
- 0
|
133
|
-
version: "0"
|
134
|
-
type: :development
|
135
|
-
version_requirements: *id008
|
136
94
|
description: WLAPI is a programmatic API for web services provided by the project Wortschatz, University of Leipzig. These services are a great source of linguistic knowledge for morphological, syntactic and semantic analysis of German both for traditional and Computational Linguistics (CL). Use this API to gain data on word frequencies, left and right neighbours, collocations and semantic similarity. Check it out if you are interested in Natural Language Processing (NLP) and Human Language Technology (HLT).
|
137
95
|
email: a.belenkow@uni-trier.de
|
138
96
|
executables: []
|
@@ -140,16 +98,17 @@ executables: []
|
|
140
98
|
extensions: []
|
141
99
|
|
142
100
|
extra_rdoc_files:
|
143
|
-
- README
|
144
|
-
- LICENSE
|
145
|
-
- CHANGELOG
|
101
|
+
- README.rdoc
|
102
|
+
- LICENSE.rdoc
|
103
|
+
- CHANGELOG.rdoc
|
146
104
|
files:
|
105
|
+
- lib/wlapi/error.rb
|
147
106
|
- lib/wlapi/version.rb
|
148
107
|
- lib/wlapi/api.rb
|
149
108
|
- lib/wlapi.rb
|
150
|
-
- README
|
151
|
-
- LICENSE
|
152
|
-
- CHANGELOG
|
109
|
+
- README.rdoc
|
110
|
+
- LICENSE.rdoc
|
111
|
+
- CHANGELOG.rdoc
|
153
112
|
- .yardopts
|
154
113
|
- test/test_api.rb
|
155
114
|
- test/data/soap_request.txt
|
@@ -159,7 +118,7 @@ licenses: []
|
|
159
118
|
post_install_message:
|
160
119
|
rdoc_options:
|
161
120
|
- -m
|
162
|
-
- README
|
121
|
+
- README.rdoc
|
163
122
|
require_paths:
|
164
123
|
- lib
|
165
124
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -184,8 +143,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
143
|
version: "0"
|
185
144
|
requirements: []
|
186
145
|
|
187
|
-
rubyforge_project:
|
188
|
-
rubygems_version: 1.8.
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 1.8.10
|
189
148
|
signing_key:
|
190
149
|
specification_version: 3
|
191
150
|
summary: WLAPI is a programmatic API for web services provided by the project Wortschatz, University of Leipzig. Use different linguistic services such as synonym and collocation search.
|