Undr

На память

Проверка на русские символы в строке

1 Star2 Stars3 Stars4 Stars5 Stars (3 голосов, средний: 3.67 из 5)
Loading ... Loading ...

without comments

Как-то потребовалось делать проверку на кириллицу в строке. Данный код проверяет состоит ли строка только из символов кириллицы и цифр и других знаков:

Читать дальше »

Написал undr ()

4 ноября 2011 в 11:11

Размещено в Примеры, Программирование

Метки:

Тестирование модулей с помощью RSpec

1 Star2 Stars3 Stars4 Stars5 Stars (3 голосов, средний: 3.67 из 5)
Loading ... Loading ...

without comments

К примеру, у нас есть такой модуль, который мы добавляем в классы Airport, City:

  module Nameable
    extend ActiveSupport::Concern
   
    module InstanceMethods
      def name locale=:en
        locale = :en if !name_ru || name_ru.empty?
        send(name_method(locale))
      end
   
      def localized_name
        name(I18n.locale || :en)
      end

      private
      def name_method locale=:en
        "name_#{locale}".to_sym
      end
    end
   
    included do
      field :name_en, :type => String
      field :name_ru, :type => String
      validates_presence_of :name_en
    end
  end
  class Airport
    include Mongoid::Document
    include Nameable
  end
  class City
    include Mongoid::Document
    include Nameable
  end

Чтобы протестировать модуль, для него нужно создать shared_examples_for блок:

  shared_examples_for :Nameable do  
    it{should have_fields(:name_en).of_type(String)}
    it{should have_fields(:name_ru).of_type(String)}
    it{should validate_presence_of(:name_en)}

    describe '#name' do
      specify{nameable.name(:en).should == 'Name'}
      specify{nameable.name(:ru).should == 'Имя'}
 
      context 'if russian name is null' do
        before do
          nameable.name_ru = nil
        end
   
        specify{nameable.name(:en).should == 'Name'}
        specify{nameable.name(:ru).should == 'Name'}
      end
    end
   
    # И так далее...
  end

В блоке используется одна переменная nameable, которая будет определяться в спеке того класса, к которому мы подключим модуль. То есть в spec/models/airport_spec.rb пишем примерно так:

require 'spec_helper'
require 'models/nameable_spec'

describe Airport do
  it{should be_mongoid_document}
 
  before do
    Airport.delete_all
  end
 
  context do
    let(:nameable){Factory.create(:airport,
      :name_en => 'Name',
      :name_ru => 'Имя'
    )}
    it_behaves_like :Nameable
  end

Вобщем то, переменных может быть сколько угодно, это зависит от тестируемого модуля. Теперь добавляем примерно тоже самое в spec/models/city_spec.rb:

require 'spec_helper'
require 'models/nameable_spec'

describe City do
  it{should be_mongoid_document}
 
  before do
    City.delete_all
  end
 
  context do
    let(:nameable){Factory.create(:city,
      :name_en => 'Name',
      :name_ru => 'Имя'
    )}
    it_behaves_like :Nameable
  end

Запускаем тест:

undr$ bundle exec rspec spec/models/airport_spec.rb

Работает. Запускаем несколько тестов:

undr$ bundle exec rake spec:models

Тесты вызывают ошибку:

/Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/rspec-core-2.6.4/lib/rspec/core/shared_example_group.rb:59:in `ensure_shared_example_group_name_not_taken': Shared example group 'Nameable' already exists (ArgumentError)
    from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/rspec-core-2.6.4/lib/rspec/core/shared_example_group.rb:8:in `shared_context'
    from /Users/undr/projects/ruby/*******/spec/models/nameable_spec.rb:1:in `<top (required)>'
    from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `load'
    from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `block in load'
...

Чтобы избежать этого надо предотвратить повторное определение блока shared_examples_for. Просто этот перед определением блока делайте проверку на его наличие:

unless RSpec.world.shared_example_groups.has_key?(:Nameable)
  shared_examples_for :Nameable do  
   
    ...
   
  end
end

Таким образом у меня получилось удобно, без лишнего кода, тестировать модули подмешанные к классам.

Написал undr ()

21 октября 2011 в 09:30

Доклад по Grape

1 Star2 Stars3 Stars4 Stars5 Stars (1 голосов, средний: 5.00 из 5)
Loading ... Loading ...

without comments

Написал undr ()

3 октября 2011 в 06:41

Размещено в Примеры, Программирование

Метки: , , ,

Презентация. Как работает шардинг в MongoDB

1 Star2 Stars3 Stars4 Stars5 Stars (4 голосов, средний: 5.00 из 5)
Loading ... Loading ...

without comments

Написал undr ()

22 августа 2011 в 10:00

Русский язык и \w в регулярках

1 Star2 Stars3 Stars4 Stars5 Stars (3 голосов, средний: 5.00 из 5)
Loading ... Loading ...

without comments

Для того, чтобы выбрать все буквы, в регулярных выражениях используется выражение \w.

"Bla-bla-bla! (c)".gsub(/[^\w]/u, '') # => "BlaBlaBlac"

С русским языком такое не получится:

"Бла-Бла-Бла! (с)".gsub(/[^\w]/u, '') # => ""

Самое первое что приходит на ум это:

"Бла-Бла-Бла! (с)".gsub(/[-я]/iu, '') # => "БлаБлаБлас"

Оппана! Вроде работает, но на самом деле, это не корректное выражение. Пример:

'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЁЯЧСМИТЬБЮйцукенгшщзхъфывапролджэёячсмитьбю1234567890=/!"№%:,.;()_+!@#$%^&*()'.gsub(/[-я]/ui, '')
# => "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮйцукенгшщзхъфывапролджэячсмитьбю"

Буквы ё и Ё потерялись. Правильно так: /[-яё]/ui

'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЁЯЧСМИТЬБЮйцукенгшщзхъфывапролджэёячсмитьбю1234567890=/!"№%:,.;()_+!@#$%^&*()'.gsub(/[-яё]/ui, '')
# => "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЁЯЧСМИТЬБЮйцукенгшщзхъфывапролджэёячсмитьбю"

Написал undr ()

19 августа 2011 в 16:46

MongoId документы и метод to_a

1 Star2 Stars3 Stars4 Stars5 Stars (1 голосов, средний: 5.00 из 5)
Loading ... Loading ...

without comments

Сегодня натолкнулся на странный баг в программе. Использовал Mongoid для работы с MongoDb. Моделька была примерно такая:

class Content::Airport < Content::Place
  field :coordinates, :type => Array
  field :index, :type => Integer
 
  index [[ :coordinates, Mongo::GEO2D ]]
 
  referenced_in :parent, :class_name => 'Content::City', :inverse_of => :children, :index => true, :validate => false
 
  def city
    parent
  end
 
  def to_a
    [
      code,
      name,
      coordinates.try(:join, ':'),
      city.try(:name),
      city.try(:index).try(:to_i),
      index.to_i
    ]
  end
end

В классе Content::Place добавлялись некоторые общие поля и модуль Mongoid::Tree.

При попытке создать аэропорт привязанный к городу выпадала ошибка:

BSON::InvalidDocument: Cannot serialize an object of class Content::City into BSON.
    from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/bson-1.3.1/lib/bson/bson_c.rb:24:in `serialize'
    from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/bson-1.3.1/lib/bson/bson_c.rb:24:in `serialize'
    from /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/mongo-1.3.1/lib/mongo/cursor.rb:425:in `construct_query_message'

Читать дальше »

Написал undr ()

4 августа 2011 в 16:50

Кэширование фрагментов HTML кода в шаблонах ActionMailer

1 Star2 Stars3 Stars4 Stars5 Stars (2 голосов, средний: 3.00 из 5)
Loading ... Loading ...

without comments

Задача: реализовать кэширование фрагментов HTML кода в шаблоне письма для рассылки.

Первое решение которое приходит в голову – это использовать хелпер cache, например так:

...
<h1>Result has been executed for long time</h1>

<% cache cache_key do %>
  <div>
  <%= doing_something_long_time_and_show_result %>
  </div>
<% end %>
...

Но этот способ не работает, так как ActiveMailer не содержит методы для кэширования. И в результате у нас ошибка:

Error: ActionView::Template::Error - undefined method `perform_caching' for #<SomeMailer:0x0000010827a9f8>
  /Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.7/lib/action_view/helpers/cache_helper.rb:37:in `cache'
  ...

Второй вариант, это использовать Rails.cache.fetch:

...
<h1>Result has been executed for long time</h1>

<%= Rails.cache.fetch cache_key do %>
  <div>
  <%= doing_something_long_time_and_show_result %>
  </div>
<% end %>
...

Ошибки уже нет, но результат не верный. В кэш попадает все содержимое шаблона, а не часть в блоке, и, как следствие, в результате письмо содержит дублированные куски HTML кода. То есть сначала выводится заголовок, потом опять заголовок и содержимое блока.

Чтобы убрать дублирование HTML кода в результате, нужно написать примерно такой хелпер:

def mailer_cache key, &block
  Rails.cache.fetch(key) do
    with_output_buffer(&block)
  end
end

И в шаблоне вызывать его.

...
<h1>Result has been executed for long time</h1>

<%= mailer_cache cache_key do %>
  <div>
  <%= doing_something_long_time_and_show_result %>
  </div>
<% end %>
...

Написал undr ()

28 июня 2011 в 14:58

Просто понравился мультик

1 Star2 Stars3 Stars4 Stars5 Stars (1 голосов, средний: 5.00 из 5)
Loading ... Loading ...

without comments

Написал undr ()

5 мая 2011 в 18:28

Размещено в Разное

Что же такое Railtie, Engine и Plugin?

1 Star2 Stars3 Stars4 Stars5 Stars (9 голосов, средний: 5.00 из 5)
Loading ... Loading ...

without comments

Railtie

Railtie – это ядро фреймворка, обеспечивает возможности для расширения Rails и/или изменения процесса инициализации.

Каждый основной компонент Rails (ActionMailer, ActionController, ActionView, ActiveRecord и ActiveResource) является Railtie, так что каждый из них сам несет ответственность за свою инициализацию. Например, это освобождает Rails от каких-либо привязок к ActiveRecord, позволяя другой ORM работать с Rails.

Создание расширений для Rails не требует какой-либо реализации Railtie, но, если Вы хотите взаимодействовать с Rails во время его загрузки или после нее, Railtie – это то, что Вам нужно для такого взаимодействия. Например, чтобы реализовать в плагине одно из ниже перечисленного Вам бы понадобился Railtie:

  • создать свои инициализаторы Rails::Initializable#initializer
  • конфигурировать Rails или приложение, например чтобы добавить свой генератор
  • добавить свои ключи в config.* для конфигурации среды (environment)
  • установить подписку на события ActiveSupport::Notifications
  • добавить rake задачи в Rails

    Читать дальше »

Написал undr ()

1 апреля 2011 в 00:15

Как тестировать помощники для rails с помощью rspec, использующие методы render(), concat() и capture()?

1 Star2 Stars3 Stars4 Stars5 Stars (Еще не оценили)
Loading ... Loading ...

without comments

Когда я писал небольшой плагин для rails, добавляющий в приложение возможность быстрого создания javascript вкладок, у меня возникли трудности с тестированием. Методы плагина, которые использовали методы render(), concat() и capture(), невозможно было нормально протестировать, все время возникали ошибки в самих тестах.

Читать дальше »

Написал undr ()

24 ноября 2010 в 11:47