textrazor 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/Rakefile +6 -0
- data/lib/textrazor.rb +23 -0
- data/lib/textrazor/client.rb +79 -0
- data/lib/textrazor/entity.rb +32 -0
- data/lib/textrazor/request.rb +34 -0
- data/lib/textrazor/response.rb +77 -0
- data/lib/textrazor/topic.rb +20 -0
- data/lib/textrazor/version.rb +3 -0
- data/lib/textrazor/word.rb +24 -0
- data/spec/lib/textrazor/client_spec.rb +181 -0
- data/spec/lib/textrazor/entity_spec.rb +45 -0
- data/spec/lib/textrazor/request_spec.rb +44 -0
- data/spec/lib/textrazor/response_spec.rb +167 -0
- data/spec/lib/textrazor/topic_spec.rb +25 -0
- data/spec/lib/textrazor/word_spec.rb +28 -0
- data/spec/lib/textrazor_spec.rb +38 -0
- data/spec/spec_helper.rb +10 -0
- data/textrazor.gemspec +28 -0
- metadata +159 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7bf3035d6e71f1f909d0369bc27cd46e582b9794
|
4
|
+
data.tar.gz: 8f403a7ef549ea2f740ceb3017d43ee2ddae4099
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f7cfcb4275bc41a291d0df2a05d69a75d85e2502f8471b74d1c6b1ebcebb52403bf90c9ef2c3011da6ae7dd30976bc36be50b0fc3f7a1d6734627c88d795c5c5
|
7
|
+
data.tar.gz: 3132e5fb601f066516aeaf6b25050a25482bd24b01cf9fcf838bc18acbc5e6dcf758f542f6d0faf5dcb0ec019f3043aede30674076672f34c252e9425671a574
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Anuj Dutta
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# TextRazor
|
2
|
+
|
3
|
+
This is a gem wrapper for TextRazor REST API reference.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'textrazor', :git => 'git://github.com/andhapp/textrazor.git'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or download the git repository and install it yourself as:
|
18
|
+
|
19
|
+
$ gem build textrazor.gemspec
|
20
|
+
$ gem install textrazor-[version].gem
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
### When the client is persisted across different requests
|
25
|
+
|
26
|
+
```
|
27
|
+
|
28
|
+
client = TextRazor::Client.new('api_key')
|
29
|
+
|
30
|
+
response = client.analyse('text to be analysed')
|
31
|
+
|
32
|
+
response.topics # Returns an array of TextRazor::Topic instances.
|
33
|
+
|
34
|
+
response.entities # Returns an array of TextRazor::Entity instances.
|
35
|
+
|
36
|
+
response.words # Returns an array of TextRazor::Word instances.
|
37
|
+
|
38
|
+
```
|
39
|
+
|
40
|
+
### One off requests
|
41
|
+
|
42
|
+
For making one off request to retrieve topics, entities or words you
|
43
|
+
can use the following handy method. A new client is instantiated and
|
44
|
+
discarded everytime you make this request.
|
45
|
+
|
46
|
+
```
|
47
|
+
TextRazor.topics('api_key', 'text')
|
48
|
+
|
49
|
+
TextRazor.entities('api_key', 'text')
|
50
|
+
|
51
|
+
TextRazor.words('api_key', 'text')
|
52
|
+
|
53
|
+
```
|
54
|
+
|
55
|
+
## Next steps
|
56
|
+
|
57
|
+
Only implemented this for topics, entities, and words. Also, implement
|
58
|
+
it for other information that we can retrieve from the public API.
|
59
|
+
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/textrazor.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "textrazor/version"
|
2
|
+
require "textrazor/client"
|
3
|
+
require "textrazor/request"
|
4
|
+
require "textrazor/response"
|
5
|
+
require "textrazor/topic"
|
6
|
+
require "textrazor/entity"
|
7
|
+
require "textrazor/word"
|
8
|
+
|
9
|
+
module TextRazor
|
10
|
+
|
11
|
+
def self.topics(api_key, text, options = {})
|
12
|
+
Client.topics(api_key, text, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.entities(api_key, text, options = {})
|
16
|
+
Client.entities(api_key, text, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.words(api_key, text, options = {})
|
20
|
+
Client.words(api_key, text, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module TextRazor
|
2
|
+
|
3
|
+
class Client
|
4
|
+
|
5
|
+
EmptyApiKey = Class.new(StandardError)
|
6
|
+
EmptyText = Class.new(StandardError)
|
7
|
+
TextTooLong = Class.new(StandardError)
|
8
|
+
|
9
|
+
DEFAULT_EXTRACTORS = ['entities', 'topics', 'words', 'phrases', 'dependency-trees',
|
10
|
+
'relations', 'entailments', 'senses']
|
11
|
+
|
12
|
+
REQUEST_OPTIONS = [:extractors, :cleanup_html, :language, :filter_dbpedia_types, :filter_freebase_types]
|
13
|
+
|
14
|
+
attr_reader :response, :api_key, :request_options
|
15
|
+
|
16
|
+
def initialize(api_key, options = {})
|
17
|
+
assign_api_key(api_key)
|
18
|
+
assign_request_options(options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def analyse(text)
|
22
|
+
assert_text(text)
|
23
|
+
options = {api_key: api_key}.merge(request_options)
|
24
|
+
|
25
|
+
Response.new(Request.post(text, options))
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.topics(api_key, text, options = {})
|
29
|
+
new(api_key, options.merge(extractors: ['topics'])).
|
30
|
+
analyse(text).
|
31
|
+
topics
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.entities(api_key, text, options = {})
|
35
|
+
new(api_key, options.merge(extractors: ['entities'])).
|
36
|
+
analyse(text).
|
37
|
+
entities
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.words(api_key, text, options = {})
|
41
|
+
new(api_key, options.merge(extractors: ['words'])).
|
42
|
+
analyse(text).
|
43
|
+
entities
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def assign_api_key(api_key)
|
49
|
+
if api_key.nil? || api_key.empty?
|
50
|
+
raise EmptyApiKey.new("API key is either nil or empty")
|
51
|
+
end
|
52
|
+
|
53
|
+
@api_key = api_key
|
54
|
+
end
|
55
|
+
|
56
|
+
def assign_request_options(options)
|
57
|
+
@request_options = { extractors: DEFAULT_EXTRACTORS }
|
58
|
+
REQUEST_OPTIONS.each do |key|
|
59
|
+
@request_options[key] = options[key] if options[key]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def assert_text(text)
|
64
|
+
if text.nil? || text.empty?
|
65
|
+
raise EmptyText.new("Text to be analysed is nil or empty")
|
66
|
+
end
|
67
|
+
|
68
|
+
if is_text_bigger_than_200_kb?(text)
|
69
|
+
raise TextTooLong.new("Text is more than 200kb")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def is_text_bigger_than_200_kb?(text)
|
74
|
+
text.bytesize/1024.0 > 200
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module TextRazor
|
2
|
+
|
3
|
+
class Entity
|
4
|
+
|
5
|
+
attr_reader :id, :type, :matching_tokens, :entity_id, :freebase_types, :confidence_score,
|
6
|
+
:wiki_link, :matched_text, :freebase_id, :relevance_score, :entity_english_id,
|
7
|
+
:starting_pos, :ending_pos
|
8
|
+
|
9
|
+
def initialize(params = {})
|
10
|
+
@type = []
|
11
|
+
params.each do |k, v|
|
12
|
+
instance_variable_set(:"@#{k}", v) if v && self.respond_to?(:"#{k}")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.create_from_hash(params)
|
17
|
+
params = Hash[params.map {|k, v| [underscore(k), v] }]
|
18
|
+
new(params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.underscore(text)
|
22
|
+
text.gsub(/::/, '/').
|
23
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
24
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
25
|
+
tr("-", "_").
|
26
|
+
downcase
|
27
|
+
end
|
28
|
+
private_class_method :underscore
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
|
3
|
+
module TextRazor
|
4
|
+
|
5
|
+
class Request
|
6
|
+
|
7
|
+
OPTIONS_MAPPING = {
|
8
|
+
extractors: 'extractors',
|
9
|
+
cleanup_html: 'cleanupHTML',
|
10
|
+
language: 'languageOverride',
|
11
|
+
filter_dbpedia_types: 'entities.filterDbpediaTypes',
|
12
|
+
filter_freebase_types: 'entities.filterFreebaseTypes'
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.post(text, options)
|
16
|
+
::RestClient.post "http://api.textrazor.com/", build_query(text, options), accept_encoding: 'gzip'
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def self.build_query(text, options)
|
22
|
+
query = {"text" => text, "apiKey" => options.delete(:api_key)}
|
23
|
+
|
24
|
+
options.each do |key, value|
|
25
|
+
value = value.join(",") if value.is_a?(Array)
|
26
|
+
query[OPTIONS_MAPPING[key]] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
query
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module TextRazor
|
4
|
+
|
5
|
+
class Response
|
6
|
+
|
7
|
+
BadRequest = Class.new(StandardError)
|
8
|
+
Unauthorised = Class.new(StandardError)
|
9
|
+
RequestEntityTooLong = Class.new(StandardError)
|
10
|
+
|
11
|
+
attr_reader :raw_response
|
12
|
+
|
13
|
+
def initialize(http_response)
|
14
|
+
code = http_response.code
|
15
|
+
body = http_response.body
|
16
|
+
|
17
|
+
raise BadRequest.new(body) if bad_request?(code)
|
18
|
+
raise Unauthorised.new(body) if unauthorised?(code)
|
19
|
+
raise RequestEntityTooLong.new(body) if request_entity_too_long?(code)
|
20
|
+
|
21
|
+
@raw_response = ::JSON.parse(body)["response"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def topics
|
25
|
+
raw_topics = raw_response["topics"]
|
26
|
+
return nil if raw_topics.nil?
|
27
|
+
|
28
|
+
@topics ||= begin
|
29
|
+
raw_topics.map do |topic_hash|
|
30
|
+
Topic.create_from_hash(topic_hash)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def entities
|
36
|
+
raw_entities = raw_response["entities"]
|
37
|
+
return nil if raw_entities.nil?
|
38
|
+
|
39
|
+
@entities ||= begin
|
40
|
+
raw_entities.map do |entity_hash|
|
41
|
+
Entity.create_from_hash(entity_hash)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def words
|
47
|
+
raw_sentences = raw_response["sentences"]
|
48
|
+
return nil if raw_sentences.nil?
|
49
|
+
|
50
|
+
@words ||= begin
|
51
|
+
words = []
|
52
|
+
raw_sentences.each do |sentence_hash|
|
53
|
+
sentence_hash["words"].each do |word_hash|
|
54
|
+
words << Word.create_from_hash(word_hash)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
words
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def bad_request?(code)
|
64
|
+
code == 400
|
65
|
+
end
|
66
|
+
|
67
|
+
def unauthorised?(code)
|
68
|
+
code == 401
|
69
|
+
end
|
70
|
+
|
71
|
+
def request_entity_too_long?(code)
|
72
|
+
code == 413
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module TextRazor
|
2
|
+
|
3
|
+
class Topic
|
4
|
+
|
5
|
+
attr_reader :id, :label, :wiki_link, :score
|
6
|
+
|
7
|
+
def initialize(id, label, wiki_link, score)
|
8
|
+
@id = id
|
9
|
+
@label = label
|
10
|
+
@wiki_link = wiki_link
|
11
|
+
@score = score
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.create_from_hash(params)
|
15
|
+
new(params["id"], params["label"], params["wikiLink"], params["score"])
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TextRazor
|
2
|
+
|
3
|
+
class Word
|
4
|
+
|
5
|
+
attr_reader :position, :starting_pos, :ending_pos, :stem,
|
6
|
+
:lemma, :token, :part_of_speech
|
7
|
+
|
8
|
+
def initialize(params)
|
9
|
+
@position = params["position"]
|
10
|
+
@starting_pos = params["startingPos"]
|
11
|
+
@ending_pos = params["endingPos"]
|
12
|
+
@stem = params["stem"]
|
13
|
+
@lemma = params["lemma"]
|
14
|
+
@token = params["token"]
|
15
|
+
@part_of_speech = params["partOfSpeech"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create_from_hash(params)
|
19
|
+
new(params)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module TextRazor
|
4
|
+
|
5
|
+
describe Client do
|
6
|
+
|
7
|
+
let(:api_key) { 'api_key' }
|
8
|
+
let(:client) { custom_options_client }
|
9
|
+
let(:nil_api_key_client) { Client.new(nil) }
|
10
|
+
let(:empty_api_key_client) { Client.new('') }
|
11
|
+
let(:custom_options_client) { Client.new(api_key, {extractors: %w(entities topics words),
|
12
|
+
cleanup_html: true, filter_dbpedia_types: %w(type1),
|
13
|
+
language: 'fre',
|
14
|
+
filter_freebase_types: %w(type2)}) }
|
15
|
+
let(:default_options_client) { Client.new(api_key) }
|
16
|
+
|
17
|
+
context "#initialize" do
|
18
|
+
|
19
|
+
context "valid parameters" do
|
20
|
+
|
21
|
+
it "should assign correct api_key, text and default options" do
|
22
|
+
expect(default_options_client.api_key).to eq(api_key)
|
23
|
+
expect(default_options_client.request_options).
|
24
|
+
to eq({extractors: %w(entities topics words phrases dependency-trees relations entailments senses)})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should assign correct api_key, text and passed in options" do
|
28
|
+
expect(custom_options_client.api_key).to eq(api_key)
|
29
|
+
expect(custom_options_client.request_options).
|
30
|
+
to eq({extractors: %w(entities topics words), cleanup_html: true, language: 'fre',
|
31
|
+
filter_dbpedia_types: %w(type1), filter_freebase_types: %w(type2)})
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
context "invalid parameters" do
|
37
|
+
|
38
|
+
context "api_key" do
|
39
|
+
|
40
|
+
context "is nil" do
|
41
|
+
|
42
|
+
it "should raise an exception" do
|
43
|
+
expect { nil_api_key_client }.
|
44
|
+
to raise_error(Client::EmptyApiKey)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
context "is empty" do
|
50
|
+
|
51
|
+
it "should raise an exception" do
|
52
|
+
expect { empty_api_key_client }.
|
53
|
+
to raise_error(Client::EmptyApiKey)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
context "#analyse" do
|
65
|
+
|
66
|
+
let(:very_long_text) { "L" * 201 * 1024 }
|
67
|
+
|
68
|
+
context "valid parameters" do
|
69
|
+
|
70
|
+
it "should make correct calls" do
|
71
|
+
request = Object.new
|
72
|
+
|
73
|
+
Request.should_receive(:post).
|
74
|
+
with('text', {api_key: 'api_key', extractors: %w(entities topics words), cleanup_html: true,
|
75
|
+
language: 'fre', filter_dbpedia_types: %w(type1), filter_freebase_types: %w(type2)}).
|
76
|
+
and_return(request)
|
77
|
+
|
78
|
+
Response.should_receive(:new).with(request)
|
79
|
+
|
80
|
+
client.analyse('text')
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
context "invalid parameters" do
|
86
|
+
|
87
|
+
context "text" do
|
88
|
+
|
89
|
+
context "is nil" do
|
90
|
+
|
91
|
+
it "should raise an exception" do
|
92
|
+
expect { client.analyse(nil) }.
|
93
|
+
to raise_error(Client::EmptyText)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
context "is empty" do
|
99
|
+
|
100
|
+
it "should raise an exception" do
|
101
|
+
expect { client.analyse('') }.
|
102
|
+
to raise_error(Client::EmptyText)
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
context "size is > 200kb" do
|
108
|
+
|
109
|
+
it "should raise an exception" do
|
110
|
+
expect { client.analyse(very_long_text) }.
|
111
|
+
to raise_error(Client::TextTooLong)
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
context ".topics" do
|
123
|
+
|
124
|
+
it "should make correct calls" do
|
125
|
+
client = OpenStruct.new
|
126
|
+
response = OpenStruct.new topics: ['topic1']
|
127
|
+
|
128
|
+
Client.should_receive(:new).
|
129
|
+
with(api_key, {extractors: ['topics']}).
|
130
|
+
and_return(client)
|
131
|
+
|
132
|
+
client.should_receive(:analyse).
|
133
|
+
with("text").
|
134
|
+
and_return(response)
|
135
|
+
|
136
|
+
Client.topics(api_key, 'text', {})
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
context ".entities" do
|
142
|
+
|
143
|
+
it "should make correct calls" do
|
144
|
+
client = OpenStruct.new
|
145
|
+
response = OpenStruct.new entities: ['Entity1']
|
146
|
+
|
147
|
+
Client.should_receive(:new).
|
148
|
+
with(api_key, {extractors: ['entities']}).
|
149
|
+
and_return(client)
|
150
|
+
|
151
|
+
client.should_receive(:analyse).
|
152
|
+
with("text").
|
153
|
+
and_return(response)
|
154
|
+
|
155
|
+
Client.entities(api_key, 'text', {})
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
context ".words" do
|
161
|
+
|
162
|
+
it "should make correct calls" do
|
163
|
+
client = OpenStruct.new
|
164
|
+
response = OpenStruct.new words: ['Word1']
|
165
|
+
|
166
|
+
Client.should_receive(:new).
|
167
|
+
with(api_key, {extractors: ['words']}).
|
168
|
+
and_return(client)
|
169
|
+
|
170
|
+
client.should_receive(:analyse).
|
171
|
+
with("text").
|
172
|
+
and_return(response)
|
173
|
+
|
174
|
+
Client.words(api_key, 'text', {})
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module TextRazor
|
4
|
+
|
5
|
+
describe Entity do
|
6
|
+
|
7
|
+
context "#create_from_hash" do
|
8
|
+
|
9
|
+
it "should create a new instance" do
|
10
|
+
entity_hash = {"id" => 1, "type" => ['Person'], "matchingTokens" => [1, 2], "entityId" => "Foreign minister",
|
11
|
+
"freebaseTypes" => ["government/government_office_or_title"],
|
12
|
+
"confidenceScore" => 0.897858, "wikiLink" => "http://en.wikipedia.org/wiki/Foreign_minister",
|
13
|
+
"matchedText" => "foreign ministers", "freebaseId" => "/m/01t_55", "relevanceScore" => 0.311479,
|
14
|
+
"entityEnglishId" => "Foreign minister", "startingPos" => 3, "endingPos" => 20}
|
15
|
+
|
16
|
+
entity = Entity.create_from_hash(entity_hash)
|
17
|
+
|
18
|
+
expect(entity.id).to eq(1)
|
19
|
+
expect(entity.type).to eq(['Person'])
|
20
|
+
expect(entity.matching_tokens).to eq([1,2])
|
21
|
+
expect(entity.entity_id).to eq("Foreign minister")
|
22
|
+
expect(entity.freebase_types).to eq(["government/government_office_or_title"])
|
23
|
+
expect(entity.confidence_score).to eq(0.897858)
|
24
|
+
expect(entity.wiki_link).to eq("http://en.wikipedia.org/wiki/Foreign_minister")
|
25
|
+
expect(entity.matched_text).to eq("foreign ministers")
|
26
|
+
expect(entity.freebase_id).to eq("/m/01t_55")
|
27
|
+
expect(entity.relevance_score).to eq(0.311479)
|
28
|
+
expect(entity.entity_english_id).to eq("Foreign minister")
|
29
|
+
expect(entity.starting_pos).to eq(3)
|
30
|
+
expect(entity.ending_pos).to eq(20)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should use sensible defaults" do
|
34
|
+
entity_hash = {"id" => 1, "startingPos" => 3, "endingPos" => 20}
|
35
|
+
|
36
|
+
entity = Entity.create_from_hash(entity_hash)
|
37
|
+
|
38
|
+
expect(entity.type).to eq([])
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module TextRazor
|
4
|
+
|
5
|
+
describe Request do
|
6
|
+
|
7
|
+
context ".post" do
|
8
|
+
|
9
|
+
context "default options" do
|
10
|
+
|
11
|
+
it "should make correct calls" do
|
12
|
+
options = {api_key: 'api_key', extractors: %w(entities topics words dependency-trees relations entailments)}
|
13
|
+
|
14
|
+
::RestClient.should_receive(:post).
|
15
|
+
with("http://api.textrazor.com/", { "text" => 'text', "apiKey" => 'api_key',
|
16
|
+
"extractors" => "entities,topics,words,dependency-trees,relations,entailments" }, accept_encoding: 'gzip')
|
17
|
+
|
18
|
+
Request.post('text', options)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
context "custom options" do
|
24
|
+
|
25
|
+
it "should make correct calls" do
|
26
|
+
options = {api_key: 'api_key', extractors: %w(entities topics words), cleanup_html: true,
|
27
|
+
language: 'fre', filter_dbpedia_types: %w(type1), filter_freebase_types: %w(type2)}
|
28
|
+
|
29
|
+
::RestClient.should_receive(:post).
|
30
|
+
with("http://api.textrazor.com/", { "text" => 'text', "apiKey" => 'api_key', "extractors" => "entities,topics,words",
|
31
|
+
"cleanupHTML" => true, "languageOverride" => 'fre', "entities.filterDbpediaTypes" => "type1",
|
32
|
+
"entities.filterFreebaseTypes" => "type2" },
|
33
|
+
accept_encoding: 'gzip')
|
34
|
+
|
35
|
+
Request.post('text', options)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module TextRazor
|
4
|
+
|
5
|
+
describe Response do
|
6
|
+
|
7
|
+
context "#initialize" do
|
8
|
+
|
9
|
+
context "when HTTP response code is 200" do
|
10
|
+
|
11
|
+
it "should create an instance of Response" do
|
12
|
+
body = "{\"response\":\"{}\"}"
|
13
|
+
http_response = ::OpenStruct.new code: 200, body: body
|
14
|
+
|
15
|
+
JSON.should_receive(:parse).
|
16
|
+
with(body).
|
17
|
+
and_return({"response"=>"{}"})
|
18
|
+
|
19
|
+
Response.new(http_response)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when HTTP response code is 400" do
|
25
|
+
|
26
|
+
it "should raise an exception" do
|
27
|
+
http_response = ::OpenStruct.new code: 400
|
28
|
+
|
29
|
+
expect{ Response.new(http_response) }.
|
30
|
+
to raise_error(Response::BadRequest)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when HTTP response code is 401" do
|
36
|
+
|
37
|
+
it "should raise an exception" do
|
38
|
+
http_response = ::OpenStruct.new code: 401
|
39
|
+
|
40
|
+
expect{ Response.new(http_response) }.
|
41
|
+
to raise_error(Response::Unauthorised)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when HTTP response code is 413" do
|
47
|
+
|
48
|
+
it "should raise an exception" do
|
49
|
+
http_response = ::OpenStruct.new code: 413
|
50
|
+
|
51
|
+
expect{ Response.new(http_response) }.
|
52
|
+
to raise_error(Response::RequestEntityTooLong)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context "#topics" do
|
60
|
+
|
61
|
+
context "if there are topics returned from api" do
|
62
|
+
|
63
|
+
it "should return topics" do
|
64
|
+
body = "\n {\"time\":\"0.013219\",\"response\":{\"language\":\"eng\",\"languageIsReliable\":true,\"topics\":[{\"id\":0,\"label\":\"Airlines \",\"wikiLink\":\"http://en.wikipedia.org/Category:Airlines_by_country\",\"score\":0.199069},{\"id\":1,\"label\":\"Companies \",\"wikiLink\":\"http://en.wikipedia.org/Category:Companies_by_year_of_establishment\",\"score\":0.136068}]}} \n"
|
65
|
+
|
66
|
+
http_response = ::OpenStruct.new code: 200, body: body
|
67
|
+
|
68
|
+
response = Response.new(http_response)
|
69
|
+
|
70
|
+
topics = response.topics
|
71
|
+
|
72
|
+
expect(topics).to_not be_nil
|
73
|
+
expect(topics.size).to eq(2)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
context "if there are no topics returned from api" do
|
79
|
+
|
80
|
+
it "should return nil" do
|
81
|
+
body = "{\"time\":\"0.013219\",\"response\":{\"language\":\"eng\",\"languageIsReliable\":true}}"
|
82
|
+
|
83
|
+
http_response = ::OpenStruct.new code: 200, body: body
|
84
|
+
|
85
|
+
response = Response.new(http_response)
|
86
|
+
|
87
|
+
expect(response.topics).to be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
context "#entities" do
|
95
|
+
|
96
|
+
context "if there are any entities returned" do
|
97
|
+
|
98
|
+
it "should return entities" do
|
99
|
+
body = "{\"time\":\"0.013219\",\"response\":{\"language\":\"eng\",\"languageIsReliable\":true,\"entities\":[{\"id\":0,\"matchingTokens\":[0],\"entityId\":\"European Union\",\"freebaseTypes\":[\"/award/award_winner\",\"/book/author\",\"/location/country\",\"/organization/organization_scope\",\"/book/book_subject\",\"/location/dated_location\",\"/people/ethnicity\",\"/projects/project_participant\",\"/location/statistical_region\",\"/organization/organization\",\"/organization/organization_member\",\"/government/governmental_jurisdiction\",\"/organization/membership_organization\",\"/internet/website_category\",\"/internet/website_owner\",\"business/employer\",\"/location/location\"],\"confidenceScore\":1.01581,\"wikiLink\":\"http://en.wikipedia.org/wiki/European_Union\",\"matchedText\":\"eu\",\"freebaseId\":\"/m/02jxk\",\"relevanceScore\":0.567223,\"entityEnglishId\":\"European Union\",\"startingPos\":0,\"endingPos\":2},{\"id\":1,\"matchingTokens\":[1,2],\"entityId\":\"Foreign minister\",\"freebaseTypes\":[\"government/government_office_or_title\"],\"confidenceScore\":0.897858,\"wikiLink\":\"http://en.wikipedia.org/wiki/Foreign_minister\",\"matchedText\":\"foreign ministers\",\"freebaseId\":\"/m/01t_55\",\"relevanceScore\":0.311479,\"entityEnglishId\":\"Foreign minister\",\"startingPos\":3,\"endingPos\":20}]}}"
|
100
|
+
|
101
|
+
http_response = ::OpenStruct.new code: 200, body: body
|
102
|
+
|
103
|
+
response = Response.new(http_response)
|
104
|
+
|
105
|
+
entities = response.entities
|
106
|
+
|
107
|
+
expect(entities).to_not be_nil
|
108
|
+
expect(entities.size).to eq(2)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
context "if there are no entities returned" do
|
114
|
+
|
115
|
+
it "should return nil" do
|
116
|
+
body = "{\"time\":\"0.013219\",\"response\":{\"language\":\"eng\",\"languageIsReliable\":true}}"
|
117
|
+
|
118
|
+
http_response = ::OpenStruct.new code: 200, body: body
|
119
|
+
|
120
|
+
response = Response.new(http_response)
|
121
|
+
|
122
|
+
expect(response.entities).to be_nil
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
context "#words" do
|
130
|
+
|
131
|
+
context "if there are any words returned" do
|
132
|
+
|
133
|
+
it "should return words" do
|
134
|
+
body = "{\"time\":\"0.013219\",\"response\":{\"language\":\"eng\",\"languageIsReliable\":true,\"sentences\":[{\"position\":1,\"words\":[{\"position\":0,\"startingPos\":0,\"endingPos\":3,\"stem\":\"the\",\"lemma\":\"the\",\"token\":\"The\",\"partOfSpeech\":\"DT\"},{\"position\":1,\"startingPos\":4,\"endingPos\":7,\"stem\":\"two\",\"lemma\":\"two\",\"token\":\"two\",\"partOfSpeech\":\"CD\"},{\"position\":2,\"startingPos\":8,\"endingPos\":11,\"stem\":\"men\",\"lemma\":\"man\",\"token\":\"men\",\"partOfSpeech\":\"NNS\"},{\"position\":3,\"startingPos\":12,\"endingPos\":19,\"stem\":\"accus\",\"lemma\":\"accuse\",\"token\":\"accused\",\"partOfSpeech\":\"VBN\"}]}]}}"
|
135
|
+
|
136
|
+
http_response = ::OpenStruct.new code: 200, body: body
|
137
|
+
|
138
|
+
response = Response.new(http_response)
|
139
|
+
|
140
|
+
words = response.words
|
141
|
+
|
142
|
+
expect(words).to_not be_nil
|
143
|
+
expect(words.size).to eq(4)
|
144
|
+
expect(words.first).to be_instance_of(Word)
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
context "if there are no words returned" do
|
150
|
+
|
151
|
+
it "should return nil" do
|
152
|
+
body = "{\"time\":\"0.013219\",\"response\":{\"language\":\"eng\",\"languageIsReliable\":true}}"
|
153
|
+
|
154
|
+
http_response = ::OpenStruct.new code: 200, body: body
|
155
|
+
|
156
|
+
response = Response.new(http_response)
|
157
|
+
|
158
|
+
expect(response.words).to be_nil
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module TextRazor
|
4
|
+
|
5
|
+
describe Topic do
|
6
|
+
|
7
|
+
context "#create_from_hash" do
|
8
|
+
|
9
|
+
it "should create a new instance" do
|
10
|
+
topic_hash = {"id" => 1, "label" => "Sports", "wikiLink" => "link_to_wiki",
|
11
|
+
"score" => 1.03589}
|
12
|
+
|
13
|
+
topic = Topic.create_from_hash(topic_hash)
|
14
|
+
|
15
|
+
expect(topic.id).to eq(1)
|
16
|
+
expect(topic.label).to eq("Sports")
|
17
|
+
expect(topic.wiki_link).to eq("link_to_wiki")
|
18
|
+
expect(topic.score).to eq(1.03589)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module TextRazor
|
4
|
+
|
5
|
+
describe Word do
|
6
|
+
|
7
|
+
context "#create_from_hash" do
|
8
|
+
|
9
|
+
it "should create a new instance" do
|
10
|
+
word_hash = {"position" => 0, "startingPos" => 0, "endingPos" => 3, "stem" => "the",
|
11
|
+
"lemma" => "the", "token" => "The", "partOfSpeech" => "DT"}
|
12
|
+
|
13
|
+
word = Word.create_from_hash(word_hash)
|
14
|
+
|
15
|
+
expect(word.position).to eq(0)
|
16
|
+
expect(word.starting_pos).to eq(0)
|
17
|
+
expect(word.ending_pos).to eq(3)
|
18
|
+
expect(word.stem).to eq("the")
|
19
|
+
expect(word.lemma).to eq("the")
|
20
|
+
expect(word.token).to eq("The")
|
21
|
+
expect(word.part_of_speech).to eq("DT")
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TextRazor do
|
4
|
+
|
5
|
+
context ".topics" do
|
6
|
+
|
7
|
+
it "should make correct calls" do
|
8
|
+
TextRazor::Client.should_receive(:topics).
|
9
|
+
with('api_key', 'text', {})
|
10
|
+
|
11
|
+
TextRazor.topics('api_key', 'text', {})
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
context ".entities" do
|
17
|
+
|
18
|
+
it "should make correct calls" do
|
19
|
+
TextRazor::Client.should_receive(:entities).
|
20
|
+
with('api_key', 'text', {})
|
21
|
+
|
22
|
+
TextRazor.entities('api_key', 'text', {})
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context ".words" do
|
28
|
+
|
29
|
+
it "should make correct calls" do
|
30
|
+
TextRazor::Client.should_receive(:words).
|
31
|
+
with('api_key', 'text', {})
|
32
|
+
|
33
|
+
TextRazor.words('api_key', 'text', {})
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/textrazor.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'textrazor/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "textrazor"
|
8
|
+
spec.version = TextRazor::VERSION
|
9
|
+
spec.authors = ["Anuj Dutta"]
|
10
|
+
spec.email = ["anuj@andhapp.com"]
|
11
|
+
spec.description = %q{Api wrapper for text razor}
|
12
|
+
spec.summary = %q{An api wrapper for text razor in ruby}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "rest-client"
|
22
|
+
spec.add_dependency "fast_open_struct"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_development_dependency "rspec-fire"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: textrazor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anuj Dutta
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fast_open_struct
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-fire
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Api wrapper for text razor
|
98
|
+
email:
|
99
|
+
- anuj@andhapp.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- lib/textrazor.rb
|
111
|
+
- lib/textrazor/client.rb
|
112
|
+
- lib/textrazor/entity.rb
|
113
|
+
- lib/textrazor/request.rb
|
114
|
+
- lib/textrazor/response.rb
|
115
|
+
- lib/textrazor/topic.rb
|
116
|
+
- lib/textrazor/version.rb
|
117
|
+
- lib/textrazor/word.rb
|
118
|
+
- spec/lib/textrazor/client_spec.rb
|
119
|
+
- spec/lib/textrazor/entity_spec.rb
|
120
|
+
- spec/lib/textrazor/request_spec.rb
|
121
|
+
- spec/lib/textrazor/response_spec.rb
|
122
|
+
- spec/lib/textrazor/topic_spec.rb
|
123
|
+
- spec/lib/textrazor/word_spec.rb
|
124
|
+
- spec/lib/textrazor_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
- textrazor.gemspec
|
127
|
+
homepage: ''
|
128
|
+
licenses:
|
129
|
+
- MIT
|
130
|
+
metadata: {}
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 2.2.2
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: An api wrapper for text razor in ruby
|
151
|
+
test_files:
|
152
|
+
- spec/lib/textrazor/client_spec.rb
|
153
|
+
- spec/lib/textrazor/entity_spec.rb
|
154
|
+
- spec/lib/textrazor/request_spec.rb
|
155
|
+
- spec/lib/textrazor/response_spec.rb
|
156
|
+
- spec/lib/textrazor/topic_spec.rb
|
157
|
+
- spec/lib/textrazor/word_spec.rb
|
158
|
+
- spec/lib/textrazor_spec.rb
|
159
|
+
- spec/spec_helper.rb
|