Language detection refactor (#2099)

* Extract detect_language to separate class

* Use default locale, not just en

* Add spec to confirm that whatlanguage cant identify empty string

* Allow account locale to override default in language detector

* PostStatusService supplies an account to detect language
This commit is contained in:
Matt Jankowski 2017-04-18 16:20:12 -04:00 committed by Eugen
parent 0a7588282a
commit 297c11dba2
4 changed files with 106 additions and 3 deletions

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class LanguageDetector
attr_reader :text, :account
def initialize(text, account = nil)
@text = text
@account = account
end
def to_iso_s
WhatLanguage.new(:all).language_iso(text) || default_locale.to_sym
end
private
def default_locale
account&.user&.locale || I18n.default_locale
end
end

View File

@ -19,7 +19,7 @@ class PostStatusService < BaseService
sensitive: options[:sensitive], sensitive: options[:sensitive],
spoiler_text: options[:spoiler_text] || '', spoiler_text: options[:spoiler_text] || '',
visibility: options[:visibility], visibility: options[:visibility],
language: detect_language(text), language: detect_language_for(text, account),
application: options[:application]) application: options[:application])
attach_media(status, media) attach_media(status, media)
@ -52,8 +52,8 @@ class PostStatusService < BaseService
media.update(status_id: status.id) media.update(status_id: status.id)
end end
def detect_language(text) def detect_language_for(text, account)
WhatLanguage.new(:all).language_iso(text) || 'en' LanguageDetector.new(text, account).to_iso_s
end end
def process_mentions_service def process_mentions_service

View File

@ -0,0 +1,71 @@
# frozen_string_literal: true
require 'rails_helper'
describe LanguageDetector do
describe 'to_iso_s' do
it 'detects english language' do
string = 'Hello and welcome to mastadon'
result = described_class.new(string).to_iso_s
expect(result).to eq :en
end
it 'detects spanish language' do
string = 'Obtener un Hola y bienvenidos a Mastadon'
result = described_class.new(string).to_iso_s
expect(result).to eq :es
end
describe 'when language cant be detected' do
it 'confirm language engine cant detect' do
result = WhatLanguage.new(:all).language_iso('')
expect(result).to be_nil
end
describe 'with an account' do
it 'uses the account locale when present' do
user = double(:user, locale: 'fr')
account = double(:account, user: user)
result = described_class.new('', account).to_iso_s
expect(result).to eq :fr
end
it 'uses default locale when account is present but has no locale' do
user = double(:user, locale: nil)
account = double(:accunt, user: user)
result = described_class.new('', account).to_iso_s
expect(result).to eq :en
end
end
describe 'with an `en` default locale' do
it 'uses the default locale' do
string = ''
result = described_class.new(string).to_iso_s
expect(result).to eq :en
end
end
describe 'with a non-`en` default locale' do
around(:each) do |example|
before = I18n.default_locale
I18n.default_locale = :ja
example.run
I18n.default_locale = before
end
it 'uses the default locale' do
string = ''
result = described_class.new(string).to_iso_s
expect(result).to eq :ja
end
end
end
end
end

View File

@ -64,6 +64,18 @@ RSpec.describe PostStatusService do
expect(status.application).to eq application expect(status.application).to eq application
end end
it 'creates a status with a language set' do
detector = double(to_iso_s: :en)
allow(LanguageDetector).to receive(:new).and_return(detector)
account = Fabricate(:account)
text = 'test status text'
subject.call(account, text)
expect(LanguageDetector).to have_received(:new).with(text, account)
end
it 'processes mentions' do it 'processes mentions' do
mention_service = double(:process_mentions_service) mention_service = double(:process_mentions_service)
allow(mention_service).to receive(:call) allow(mention_service).to receive(:call)