yspell 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.
- checksums.yaml +15 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +68 -0
- data/Rakefile +7 -0
- data/bin/yspell +8 -0
- data/lib/y_spell/cli/application.rb +108 -0
- data/lib/y_spell/cli/presenter.rb +75 -0
- data/lib/y_spell/client.rb +28 -0
- data/lib/y_spell/error.rb +9 -0
- data/lib/y_spell/spell_error.rb +50 -0
- data/lib/y_spell/version.rb +3 -0
- data/lib/y_spell.rb +8 -0
- data/spec/fixtures/english.html +10 -0
- data/spec/fixtures/english.txt +7 -0
- data/spec/fixtures/russian.txt +22 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/spell_checker/cli/application_spec.rb +38 -0
- data/spec/spell_checker/client_spec.rb +50 -0
- data/spec/spell_checker/spell_error_spec.rb +21 -0
- data/spec/support/web_helpers.rb +11 -0
- data/yspell.gemspec +28 -0
- data/yspell.iml +14 -0
- metadata +162 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZjlhOTUzYjM1Y2IyZDA5YmYyNmE2ODU3YmYwZTgyMzYzZmJkOWM4MQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YjY4ZjJlMDJiOTgyMjY2MDI2YTY2YThhODY3ZWFkNzUyZjdlOWY3Mw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MTRiYzNkYmExNTA4Y2MwOWMyOGU3Y2QwNTE2MjhiYjUzZTdkZmU1NjUzZmFl
|
10
|
+
OGE5NGU1NzZhNjIxMTcxNjBkMjc5ZDg3ZmUzZWI2YmNkOWEwY2NiNDlmMzhk
|
11
|
+
ZDY1Y2VhNTdhNDZmMjEwOWRkYWMyNmU5OWIzZjVkNmViMzk4OTU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MDVhMWJjYTIxNmFmNWQyYTRjNjYzNzQwZDhmYjgyMjk1ZjZjMzBiNzc4Zjkx
|
14
|
+
MDZhMDY2NGJkYTU3NWM1MDJmMzJhNzg2MzcxYzdjMmI3MTNkZmQ1OTAxM2Ex
|
15
|
+
YTljNTMxNWVkZjZlM2EwNzkwMWU1OTY3ODM4YzgxNmRiZmY3NzM=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 a.sabirov
|
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,68 @@
|
|
1
|
+
WIP
|
2
|
+
|
3
|
+
# YSpell
|
4
|
+
|
5
|
+
Spell checker library and command-line tool. It uses Yandex Speller API (http://api.yandex.ru/speller/doc/dg/concepts/speller-overview.xml).
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'yspell', 'git' => 'github.com:asabirov/yspell.git'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install yspell
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
As ruby library
|
25
|
+
|
26
|
+
require 'yspell'
|
27
|
+
|
28
|
+
client = YSpell::Client.new
|
29
|
+
client.check('some text for check')
|
30
|
+
|
31
|
+
|
32
|
+
As command line tool
|
33
|
+
|
34
|
+
Usage: yspell TEXT [OPTIONS]
|
35
|
+
Options
|
36
|
+
--file FILE path to file
|
37
|
+
-l, --language LANG separated list of languages
|
38
|
+
Available: ru, en or uk (default is "ru, en")
|
39
|
+
-f, --format FORMAT file format (html or plain)
|
40
|
+
-m, --mode MODE Yandex Spell mode
|
41
|
+
for more information, see http://api.yandex.ru/speller/doc/dg/reference/speller-options.xml
|
42
|
+
-s, --suggestions POSITION show suggestions after errors
|
43
|
+
inline, after_text, none
|
44
|
+
-v, --verbose Run verbosely
|
45
|
+
-h, --help help
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
## Options
|
50
|
+
|
51
|
+
Use options when calling check method:
|
52
|
+
|
53
|
+
client.check('some text for check', options)
|
54
|
+
|
55
|
+
|
56
|
+
| Key | Description |
|
57
|
+
| ------- |-------------|
|
58
|
+
| lang | List of languages. Supported ru, en, uk (default is "ru,en")|
|
59
|
+
| options | Value from 0 to 5, for more information, see http://api.yandex.ru/speller/doc/dg/reference/speller-options.xml |
|
60
|
+
| format | Format of text. Supported plain and html (default is plain) |
|
61
|
+
|
62
|
+
## Contributing
|
63
|
+
|
64
|
+
1. Fork it ( http://github.com/asabirov/yspell/fork )
|
65
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
66
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
67
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
68
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/yspell
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'optparse'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'y_spell/cli/presenter'
|
5
|
+
|
6
|
+
module YSpell
|
7
|
+
module CLI
|
8
|
+
class Application
|
9
|
+
def initialize(out = STDOUT, err = STDERR)
|
10
|
+
@client = Client.new
|
11
|
+
@out = out
|
12
|
+
@err = err
|
13
|
+
@verbose = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(argv)
|
17
|
+
options = parse_options(argv)
|
18
|
+
|
19
|
+
return if !options.file && !argv[0]
|
20
|
+
|
21
|
+
text = find_text(argv, options)
|
22
|
+
|
23
|
+
if text.empty?
|
24
|
+
presenter.error "Text is empty"
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
presenter.info "Options: #{options}"
|
29
|
+
|
30
|
+
errors = @client.check(text,
|
31
|
+
:lang => options.language,
|
32
|
+
:format => options.format,
|
33
|
+
:options => options.mode
|
34
|
+
)
|
35
|
+
|
36
|
+
presenter.draw(text, errors, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def presenter
|
42
|
+
@presenter ||= Presenter.new(@out, @err)
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_options(argv)
|
46
|
+
options = {}
|
47
|
+
opt_parser = OptionParser.new do |opt|
|
48
|
+
opt.banner = 'Usage: spell-check TEXT [OPTIONS]'
|
49
|
+
opt.separator 'Options'
|
50
|
+
options = OpenStruct.new
|
51
|
+
options.suggestions = :inline
|
52
|
+
|
53
|
+
opt.on('-f FILE','--file FILE', String, 'path to file') do |file|
|
54
|
+
options.file = file
|
55
|
+
end
|
56
|
+
|
57
|
+
opt.on('-l LANG','--language LANG', [:ru, :uk, :en], 'separated list of languages', 'Available: ru, en or uk (default is "ru, en")') do |language|
|
58
|
+
options.language = language
|
59
|
+
end
|
60
|
+
|
61
|
+
opt.on('-f FORMAT','--format FORMAT', String, 'file format (html or plain)') do |format|
|
62
|
+
options.format = format
|
63
|
+
end
|
64
|
+
|
65
|
+
opt.on('-m MODE', '--mode MODE', String, 'Yandex Spell mode', 'for more information, see http://api.yandex.ru/speller/doc/dg/reference/speller-options.xml') do |mode|
|
66
|
+
options.mode = mode
|
67
|
+
end
|
68
|
+
|
69
|
+
opt.on('-s','--suggestions POSITION', [:inline, :after, :none], 'show suggestions after errors', 'inline, after_text, none') do |mode|
|
70
|
+
options.suggestions = true
|
71
|
+
end
|
72
|
+
|
73
|
+
opt.on('-v', '--verbose', 'Run verbosely') do |v|
|
74
|
+
@verbose = true
|
75
|
+
options.verbose = v
|
76
|
+
end
|
77
|
+
|
78
|
+
opt.on_tail('-h','--help','help') do
|
79
|
+
presenter.puts opt_parser
|
80
|
+
return
|
81
|
+
end
|
82
|
+
|
83
|
+
options
|
84
|
+
end
|
85
|
+
|
86
|
+
opt_parser.parse!(argv)
|
87
|
+
|
88
|
+
if !options.file && !argv[0]
|
89
|
+
presenter.puts opt_parser
|
90
|
+
end
|
91
|
+
|
92
|
+
options
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_text(argv, options)
|
96
|
+
if options.file
|
97
|
+
if File.exists?(options.file)
|
98
|
+
File.read(options.file)
|
99
|
+
else
|
100
|
+
presenter.error "File \"#{file}\" does not exists"
|
101
|
+
end
|
102
|
+
else
|
103
|
+
argv[0]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'rainbow'
|
3
|
+
|
4
|
+
module YSpell
|
5
|
+
module CLI
|
6
|
+
class Presenter
|
7
|
+
require 'rainbow/ext/string'
|
8
|
+
|
9
|
+
def initialize(out, err)
|
10
|
+
@out = out
|
11
|
+
@err = err
|
12
|
+
@verbose = false
|
13
|
+
end
|
14
|
+
|
15
|
+
def draw(text, spell_errors, options)
|
16
|
+
@verbose = options.verbose
|
17
|
+
|
18
|
+
if spell_errors.empty?
|
19
|
+
@out.puts text
|
20
|
+
@out.puts
|
21
|
+
@out.puts "It seems ok!".color(:green)
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
highlight_errors(text, spell_errors, options)
|
26
|
+
|
27
|
+
if options.suggestions == :after
|
28
|
+
print_suggestions(spell_errors)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def puts(text)
|
33
|
+
@out.puts text
|
34
|
+
end
|
35
|
+
|
36
|
+
def error(text)
|
37
|
+
@err.puts text.color(:red)
|
38
|
+
end
|
39
|
+
|
40
|
+
def info(msg)
|
41
|
+
@out.puts(msg) if @verbose
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def highlight_errors(text, errors, options)
|
47
|
+
row = 0
|
48
|
+
text.each_line do |line|
|
49
|
+
row_errors = errors.select{|err| err.row == row}.sort_by{|err| err.position}.reverse
|
50
|
+
@out.puts print_text_with_highlights(line, row_errors, options)
|
51
|
+
row = row + 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def print_text_with_highlights(string, errors, options)
|
56
|
+
errors.each do |error|
|
57
|
+
replace_with = error.colored_word
|
58
|
+
if options.suggestions == :inline
|
59
|
+
replace_with << " (#{error.suggestions.join(', ')}?)".color(:yellow)
|
60
|
+
end
|
61
|
+
|
62
|
+
string[error.column...(error.column + error.length)] = replace_with
|
63
|
+
end
|
64
|
+
string
|
65
|
+
end
|
66
|
+
|
67
|
+
def print_suggestions(errors)
|
68
|
+
@out.puts
|
69
|
+
errors.each do |error|
|
70
|
+
@out.puts "#{error.word} — #{error.suggestions.join(', ')}".color(:yellow)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module YSpell
|
5
|
+
class Client
|
6
|
+
|
7
|
+
API_PATH_SINGLE_CHECK = 'http://speller.yandex.net/services/spellservice.json/checkText'
|
8
|
+
|
9
|
+
API_PATH_MULTIPLE_MULTIPLE = 'http://speller.yandex.net/services/spellservice.json/checkTexts'
|
10
|
+
|
11
|
+
def check(text, options = {})
|
12
|
+
params = options.merge('text' => text)
|
13
|
+
request(params)
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def request(params)
|
18
|
+
http = HTTPClient.new
|
19
|
+
raw_response = http.post(API_PATH_SINGLE_CHECK, params)
|
20
|
+
|
21
|
+
results = MultiJson.load(raw_response.body)
|
22
|
+
|
23
|
+
results.map do |result|
|
24
|
+
SpellError.from_result(result)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module YSpell
|
5
|
+
class SpellError
|
6
|
+
class UnknownWord < SpellError
|
7
|
+
COLOR = :red
|
8
|
+
end
|
9
|
+
class RepeatedWord < SpellError
|
10
|
+
COLOR = :yellow
|
11
|
+
end
|
12
|
+
class Capitalization < SpellError
|
13
|
+
COLOR = :yellow
|
14
|
+
end
|
15
|
+
class TooManyErrors < SpellError
|
16
|
+
COLOR = :red
|
17
|
+
end
|
18
|
+
|
19
|
+
#COLOR = :red
|
20
|
+
|
21
|
+
attr_reader :code, :position, :row, :column, :length, :word, :suggestions
|
22
|
+
|
23
|
+
CODE_TO_ERROR = [UnknownWord, RepeatedWord, Capitalization, TooManyErrors]
|
24
|
+
|
25
|
+
def self.from_result(result)
|
26
|
+
class_by_code(result['code']).new(result)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.class_by_code(code)
|
30
|
+
key = code - 1
|
31
|
+
|
32
|
+
raise(UnknownCodeError, "Code #{code} is unknown") if CODE_TO_ERROR[key].nil?
|
33
|
+
CODE_TO_ERROR[key]
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(result)
|
37
|
+
@position = result['pos']
|
38
|
+
@row = result['row']
|
39
|
+
@column = result['col']
|
40
|
+
@length = result['len']
|
41
|
+
@word = result['word']
|
42
|
+
@suggestions = result['s']
|
43
|
+
@code = result['code']
|
44
|
+
end
|
45
|
+
|
46
|
+
def colored_word
|
47
|
+
word.color(self.class::COLOR)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/y_spell.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
<html>
|
2
|
+
<body>
|
3
|
+
<p>‘Don’t talk. I want to hear what hapens.’</p>
|
4
|
+
<p>‘Is samething happening?’ I inquired innocently.</p>
|
5
|
+
<p>‘You mean to say you don’t know?’ said Miss Baker, hon-estly surprised.</p>
|
6
|
+
<p>‘I thought everybody knew.’</p>
|
7
|
+
<p>‘I don’t.’</p>
|
8
|
+
<p>‘Why——’ she said hesitantly,</p>
|
9
|
+
<p>‘Tom’s got some woman in New York.’</p>
|
10
|
+
</body>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
‘Don’t talk. I want to hear what hapens.’
|
2
|
+
‘Is samething happening?’ I inquired innocently.
|
3
|
+
‘You mean to say you don’t know?’ said Miss Baker, hon-estly surprised.
|
4
|
+
‘I thought everybody knew.’
|
5
|
+
‘I don’t.’
|
6
|
+
‘Why——’ she said hesitantly,
|
7
|
+
‘Tom’s got some woman in New York.’
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Кога, к мечтательнму миру
|
2
|
+
Стремясь возвышенной душой,
|
3
|
+
Ты держишь на коленях лиру
|
4
|
+
Нетерпеливою рукой;
|
5
|
+
Когда сменяются виденья
|
6
|
+
Перед тобой в волшебной мгле,
|
7
|
+
И быстрый холод вдохновенья
|
8
|
+
Власы подъемлет на челе,—
|
9
|
+
Ты прав, творишь ты для немногих,
|
10
|
+
Не для завистливых судей,
|
11
|
+
Не для сбиателей убогих
|
12
|
+
Чужих суждений и вестей,
|
13
|
+
Но для друзей таланта строгих,
|
14
|
+
Священнй истины друзей.
|
15
|
+
Не всякого полюбит счастье,
|
16
|
+
Не все родились для венцов.
|
17
|
+
Блажен, кто знает сладострастье
|
18
|
+
Высоких мыслей и стихов!
|
19
|
+
Кто наслаждение прекрасным
|
20
|
+
В прекрасный получил удел
|
21
|
+
И твой восторг уразумел
|
22
|
+
Восторгом пламенным и яснм!
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'y_spell'
|
5
|
+
require 'webmock/rspec'
|
6
|
+
|
7
|
+
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
12
|
+
config.run_all_when_everything_filtered = true
|
13
|
+
config.filter_run :focus
|
14
|
+
|
15
|
+
config.order = 'random'
|
16
|
+
|
17
|
+
WebMock.enable!
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'y_spell/cli/application'
|
4
|
+
|
5
|
+
describe YSpell::CLI::Application do
|
6
|
+
include WebHelpers
|
7
|
+
let(:stdout) { StringIO.new }
|
8
|
+
let(:cli) { described_class.new(stdout) }
|
9
|
+
|
10
|
+
context 'without file and options' do
|
11
|
+
let(:argv) { [] }
|
12
|
+
|
13
|
+
it 'returns instructions' do
|
14
|
+
cli.run(argv)
|
15
|
+
stdout.rewind
|
16
|
+
stdout.read.should include('Usage: spell-check TEXT [OPTIONS]')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'check file' do
|
21
|
+
let(:argv) { ['--file=spec/fixtures/russian.txt'] }
|
22
|
+
|
23
|
+
before do
|
24
|
+
stub_api_response('[
|
25
|
+
{"code":1,"pos":0,"row":0,"col":0,"len":4,"word":"\u041a\u043e\u0433\u0430","s":["\u041a\u043e\u0433\u0434\u0430","\u041a\u043e\u043a\u0430","\u041a\u043e\u0433\u043e","\u0413\u043e\u0433\u0430"]},
|
26
|
+
{"code":1,"pos":8,"row":0,"col":8,"len":12,"word":"\u043c\u0435\u0447\u0442\u0430\u0442\u0435\u043b\u044c\u043d\u043c\u0443","s":["\u043c\u0435\u0447\u0442\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443"]}
|
27
|
+
]')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'shows errors in text' do
|
31
|
+
cli.run(argv)
|
32
|
+
stdout.rewind
|
33
|
+
|
34
|
+
stdout.read.should
|
35
|
+
include("#{'Кога'.color(:red)} #{'(Когда, Кока, Кого, Гога?)'.color(:yellow)}, к #{'мечтательнму'.color(:red)} #{'(мечтательному?)'.color(:yellow)} миру")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe YSpell::Client do
|
5
|
+
include WebHelpers
|
6
|
+
|
7
|
+
let(:client) { described_class.new }
|
8
|
+
let(:result) { client.check(text).first }
|
9
|
+
|
10
|
+
before do
|
11
|
+
WebMock.disable!
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
context 'russian' do
|
16
|
+
let(:text) { File.read('spec/fixtures/russian.txt') }
|
17
|
+
|
18
|
+
it 'returns Container' do
|
19
|
+
client.check(text).first.should be_a(YSpell::SpellError::UnknownWord)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns correct errors' do
|
23
|
+
result.code.should == 1
|
24
|
+
result.position.should == 0
|
25
|
+
result.row.should == 0
|
26
|
+
result.column.should == 0
|
27
|
+
result.length.should == 4
|
28
|
+
result.word.should == 'Кога'
|
29
|
+
result.suggestions.should == ['Когда', 'Кока', 'Кого', 'Гога']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'english' do
|
34
|
+
let(:text) { File.read('spec/fixtures/english.txt') }
|
35
|
+
|
36
|
+
it 'returns Container' do
|
37
|
+
client.check(text).first.should be_a(YSpell::SpellError::UnknownWord)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns correct errors' do
|
41
|
+
result.code.should == 1
|
42
|
+
result.position.should == 33
|
43
|
+
result.row.should == 0
|
44
|
+
result.column.should == 33
|
45
|
+
result.length.should == 6
|
46
|
+
result.word.should == 'hapens'
|
47
|
+
result.suggestions.should == ['happens']
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe YSpell::SpellError do
|
5
|
+
describe '#error_by_code' do
|
6
|
+
it 'returns class by code' do
|
7
|
+
described_class.class_by_code(1).should == YSpell::SpellError::UnknownWord
|
8
|
+
described_class.class_by_code(2).should == YSpell::SpellError::RepeatedWord
|
9
|
+
described_class.class_by_code(3).should == YSpell::SpellError::Capitalization
|
10
|
+
described_class.class_by_code(4).should == YSpell::SpellError::TooManyErrors
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'unknown code' do
|
14
|
+
it 'raise error' do
|
15
|
+
expect {
|
16
|
+
described_class.class_by_code(5)
|
17
|
+
}.to raise_error(YSpell::UnknownCodeError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module WebHelpers
|
2
|
+
def stub_api_response(body, text = nil, status = 200)
|
3
|
+
st = stub_request(:post, "http://speller.yandex.net/services/spellservice.json/checkText")
|
4
|
+
|
5
|
+
unless text.nil?
|
6
|
+
st.with(:body => {'text' => text})
|
7
|
+
end
|
8
|
+
|
9
|
+
st.to_return(:status => status, :body => body)
|
10
|
+
end
|
11
|
+
end
|
data/yspell.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 'y_spell/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "yspell"
|
8
|
+
spec.version = YSpell::VERSION
|
9
|
+
spec.authors = ["a.sabirov"]
|
10
|
+
spec.email = ["sladecj@gmail.com"]
|
11
|
+
spec.summary = "Command line spell checker"
|
12
|
+
spec.description = "It uses yandex speller api and supported languages ru, en and uk"
|
13
|
+
spec.homepage = "https://github.com/asabirov/yspell"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
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 'httpclient'
|
22
|
+
spec.add_dependency 'multi_json'
|
23
|
+
spec.add_dependency 'rainbow', '>= 2.0.0'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler'
|
26
|
+
spec.add_development_dependency 'rspec'
|
27
|
+
spec.add_development_dependency 'webmock', '>= 1.0.0'
|
28
|
+
end
|
data/yspell.iml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
3
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
4
|
+
<exclude-output />
|
5
|
+
<content url="file://$MODULE_DIR$">
|
6
|
+
<excludeFolder url="file://$MODULE_DIR$/.idea" />
|
7
|
+
</content>
|
8
|
+
<orderEntry type="jdk" jdkName="RVM: ruby-1.9.3-p125" jdkType="RUBY_SDK" />
|
9
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
10
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.3.5, RVM: ruby-1.9.3-p125) [gem]" level="application" />
|
11
|
+
<orderEntry type="library" scope="PROVIDED" name="multi_json (v1.7.7, RVM: ruby-1.9.3-p125) [gem]" level="application" />
|
12
|
+
</component>
|
13
|
+
</module>
|
14
|
+
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yspell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- a.sabirov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httpclient
|
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: multi_json
|
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: rainbow
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.0.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
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: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.0.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.0.0
|
97
|
+
description: It uses yandex speller api and supported languages ru, en and uk
|
98
|
+
email:
|
99
|
+
- sladecj@gmail.com
|
100
|
+
executables:
|
101
|
+
- yspell
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- .gitignore
|
106
|
+
- .rspec
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- bin/yspell
|
112
|
+
- lib/y_spell.rb
|
113
|
+
- lib/y_spell/cli/application.rb
|
114
|
+
- lib/y_spell/cli/presenter.rb
|
115
|
+
- lib/y_spell/client.rb
|
116
|
+
- lib/y_spell/error.rb
|
117
|
+
- lib/y_spell/spell_error.rb
|
118
|
+
- lib/y_spell/version.rb
|
119
|
+
- spec/fixtures/english.html
|
120
|
+
- spec/fixtures/english.txt
|
121
|
+
- spec/fixtures/russian.txt
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
- spec/spell_checker/cli/application_spec.rb
|
124
|
+
- spec/spell_checker/client_spec.rb
|
125
|
+
- spec/spell_checker/spell_error_spec.rb
|
126
|
+
- spec/support/web_helpers.rb
|
127
|
+
- yspell.gemspec
|
128
|
+
- yspell.iml
|
129
|
+
homepage: https://github.com/asabirov/yspell
|
130
|
+
licenses:
|
131
|
+
- MIT
|
132
|
+
metadata: {}
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 2.2.2
|
150
|
+
signing_key:
|
151
|
+
specification_version: 4
|
152
|
+
summary: Command line spell checker
|
153
|
+
test_files:
|
154
|
+
- spec/fixtures/english.html
|
155
|
+
- spec/fixtures/english.txt
|
156
|
+
- spec/fixtures/russian.txt
|
157
|
+
- spec/spec_helper.rb
|
158
|
+
- spec/spell_checker/cli/application_spec.rb
|
159
|
+
- spec/spell_checker/client_spec.rb
|
160
|
+
- spec/spell_checker/spell_error_spec.rb
|
161
|
+
- spec/support/web_helpers.rb
|
162
|
+
has_rdoc:
|