module Rooms class TitleGenerator attr_reader :room, :locale def initialize(room, locale="en") @room = room @locale = locale end def generate if room_type_number_and_destination.present? && size_adjective.present? && amenities.present? [size_adjective, room_type_number_and_destination, amenities].compact.join(" ").html_safe elsif room_type_number_and_destination.present? && amenities.present? [room_type_number_and_destination, amenities].compact.join(" ").html_safe elsif room_type_number_and_destination.present? && size_adjective.present? [size_adjective, room_type_number_and_destination].compact.join(" ").html_safe elsif room_type_number_and_destination.present? room_type_number_and_destination end end # Shared methods def t(key, options={}) value = I18n.t("rooms.title_generator.#{key}") key = "#{key}.#{sample(value.keys)}" if value.is_a?(Hash) I18n.t("rooms.title_generator.#{key}", options.merge({ locale: locale })) end # Translation Helpers def room_type @room_type ||= I18n.t("room_types.#{room.room_type.type}", locale: locale) end def destination @destination ||= room.destination.name_translations[locale] || room.destination.name_translations["en"] end # Sentences def size_adjective # For properties less than 500sq ft/50 sqm small_adjective = I18n.t("rooms.title_generator.adjectives.small", locale: locale).map{ |key, value| value } small_adjective = small_adjective.sample # For properties 500-1000 sq ft/ 50-100 sqm medium_adjective = I18n.t("rooms.title_generator.adjectives.medium", locale: locale).map{ |key, value| value } medium_adjective = medium_adjective.sample # For properties above 1000 sf/100 sqm large_adjective = I18n.t("rooms.title_generator.adjectives.large", locale: locale).map{ |key, value| value } large_adjective = large_adjective.sample if room.surface.present? && room.surface_unit.present? && room.surface_unit == "metric" case when room.surface >= 100 then large_adjective when room.surface >= 50 && room.surface < 100 then medium_adjective when room.surface < 50 then small_adjective end elsif room.surface.present? && room.surface_unit.present? && room.surface_unit == "imperial" case when room.surface >= 1000 then large_adjective when room.surface >= 500 && room.surface < 1000 then medium_adjective when room.surface < 500 then small_adjective end else return nil end end def room_type_number_and_destination if room.destination.present? && room.number_of_rooms && room.room_type.present? case when room.number_of_rooms >= 1 then t("number_type_destination", room_type: room_type, number_of_rooms: room.number_of_rooms, destination: destination) when room.number_of_rooms == 0 then t("studio_type_destination", room_type: room_type, destination: destination) end elsif room.room_type && room.number_of_rooms && room.neighborhood.present? && room.city.present? case when room.number_of_rooms >= 1 then t("number_type_neighborhood_city", room_type: room_type, number_of_rooms: room.number_of_rooms, neighborhood: room.neighborhood, city: room.city) when room.number_of_rooms == 0 then t("studio_type_neighborhood_city", room_type: room_type, neighborhood: room.neighborhood, city: room.city) end elsif room.destination.present? && room.number_of_rooms t("number_destination", number_of_rooms: room.number_of_rooms, destination: destination) elsif room.number_of_rooms && room.room_type.present? t("number_type", number_of_rooms: room.number_of_rooms, room_type: room_type) else return nil end end def amenities tmp = amenities_list if tmp.present? return t("amenities.with") + " " + tmp.to_sentence else return nil end end def amenities_list tmp = [] tmp << t("amenities.aircon") if room.airconditioning? tmp << t("amenities.parking") if room.parking tmp << t("amenities.pool") if room.pool tmp << t("amenities.gym") if room.gym tmp << t("amenities.doorman") if room.doorman tmp << t("amenities.balcony") if room.balcony tmp << t("amenities.breakfast_provided") if room.breakfast tmp end end end ______ require 'spec_helper' describe Rooms::TitleGenerator do let!(:room) { create(:room) } let(:locale) { 'en' } let(:generator) { Rooms::TitleGenerator.new(room, locale) } describe "#generate" do context "room_type_number_and_destination.present? && size_adjective.present? && amenities.present?" do it "returns the correct title for the specified large room with some amenities" do sentence = /(?:Family-friendly|Group-friendly|Perfect|Spacious|Large|Grand|Very|Spacious|Awesome|Wonderful|Fantastic|Amazing|Superb|Marvellous|Stunning|Incredible|Fine|Excellent|Fab|Superb) 4 Bedroom Apartment in Chinatown with Pool and Gym/ room.surface = 120 room.surface_unit = "metric" room.number_of_rooms = 4 room.room_type.type = "Apartment" room.destination.name = "Chinatown" room.pool = true room.gym = true expect(generator.send(:generate)).to match (sentence) end end context "room_type_number_and_destination.present? && amenities.present? - without size" do it "returns the correct title for the specified room with some amenities" do sentence = "4 Bedroom Apartment in Chinatown with Pool and Gym" room.surface = nil room.surface_unit = nil room.number_of_rooms = 4 room.room_type.type = "Apartment" room.destination.name = "Chinatown" room.pool = true room.gym = true expect(generator.send(:generate)).to match (sentence) end end context "room_type_number_and_destination.present? && size_adjective.present? - without amenities" do it "returns the correct title for for the specified small room" do sentence = /(?:Cozy|Warm|Welcoming|Compact|Comfy|Comfortable|Intimate|Agreeable|Pleasant|Delightful|Charming|Lovely|Convenient|Accessible) Studio Apartment in Chinatown/ room.surface = 40 room.surface_unit = "metric" room.number_of_rooms = 0 room.room_type.type = "Apartment" room.destination.name = "Chinatown" expect(generator.send(:generate)).to match (sentence) end it "returns the correct title for the specified medium room" do sentence = /(?:Comfortable|Spacious|Welcoming|Comfortable|Large|Good-sized|Lovely|Charming|Well-spaced|Well-appointed|Wonderful|Beautiful|Great|Fantastic|Super|Friendly|Amazing|Unbeatable|Awesome) 2 Bedroom Apartment in Chinatown/ room.surface = 80 room.surface_unit = "metric" room.number_of_rooms = 2 room.room_type.type = "Apartment" room.destination.name = "Chinatown" expect(generator.send(:generate)).to match (sentence) end it "returns the correct title for the specified large room" do sentence = /(?:Family-friendly|Group-friendly|Perfect|Spacious|Large|Grand|Very|Spacious|Awesome|Wonderful|Fantastic|Amazing|Superb|Marvellous|Stunning|Incredible|Fine|Excellent|Fab|Superb) 4 Bedroom Apartment in Chinatown/ room.surface = 120 room.surface_unit = "metric" room.number_of_rooms = 4 room.room_type.type = "Apartment" room.destination.name = "Chinatown" expect(generator.send(:generate)).to match (sentence) end end context "room_type_number_and_destination.present? - without size or amenities" do it "returns the correct title for the room specified without a size" do sentence = "4 Bedroom Apartment in Chinatown" room.surface = nil room.surface_unit = nil room.number_of_rooms = 4 room.room_type.type = "Apartment" room.destination.name = "Chinatown" expect(generator.send(:generate)).to eq (sentence) end end context "nil for required attributes" do it "returns nil if we have no suggested title to offer" do room.number_of_rooms = nil room.destination = nil room.room_type.type = nil room.neighborhood = nil room.city = nil room.surface = nil room.surface_unit = nil expect(generator.send(:generate)).to eq nil end end end describe "#size_adjective" do context "metric" do it "returns one of specified adjectives for 'small' property" do sentence = /(?:Cozy|Warm|Welcoming|Compact|Comfy|Comfortable|Intimate|Agreeable|Pleasant|Delightful|Charming|Lovely|Convenient|Accessible)/ room.surface = 40 room.surface_unit = "metric" expect(generator.send(:size_adjective)).to match (sentence) end it "returns one of specified adjectives for 'medium' property" do sentence = /(?:Comfortable|Spacious|Welcoming|Comfortable|Large|Good-sized|Lovely|Charming|Well-spaced|Well-appointed|Wonderful|Beautiful|Great|Fantastic|Super|Friendly|Amazing|Unbeatable|Awesome)/ room.surface = 80 room.surface_unit = "metric" expect(generator.send(:size_adjective)).to match (sentence) end it "returns one of specified adjectives for 'large' property" do sentence = /(?:Family-friendly|Group-friendly|Perfect|Spacious|Large|Grand|Very|Spacious|Awesome|Wonderful|Fantastic|Amazing|Superb|Marvellous|Stunning|Incredible|Fine|Excellent|Fab|Superb)/ room.surface = 120 room.surface_unit = "metric" expect(generator.send(:size_adjective)).to match (sentence) end end context "imperial" do it "returns one of specified adjectives for 'small' property" do sentence = /(?:Cozy|Warm|Welcoming|Compact|Comfy|Comfortable|Intimate|Agreeable|Pleasant|Delightful|Charming|Lovely|Convenient|Accessible)/ room.surface = 400 room.surface_unit = "imperial" expect(generator.send(:size_adjective)).to match (sentence) end it "returns one of specified adjectives for 'medium' property" do sentence = /(?:Comfortable|Spacious|Welcoming|Comfortable|Large|Good-sized|Lovely|Charming|Well-spaced|Well-appointed|Wonderful|Beautiful|Great|Fantastic|Super|Friendly|Amazing|Unbeatable|Awesome)/ room.surface = 800 room.surface_unit = "imperial" expect(generator.send(:size_adjective)).to match (sentence) end it "returns one of specified adjectives for 'large' property" do sentence = /(?:Family-friendly|Group-friendly|Perfect|Spacious|Large|Grand|Very|Spacious|Awesome|Wonderful|Fantastic|Amazing|Superb|Marvellous|Stunning|Incredible|Fine|Excellent|Fab|Superb)/ room.surface = 1200 room.surface_unit = "imperial" expect(generator.send(:size_adjective)).to match (sentence) end end context "no surface unit or measurement" do it "returns nil when no surface unit or measurement is given" do room.surface = nil room.surface_unit = nil expect(generator.send(:size_adjective)).to eq nil end end end describe "#room_type_number_and_destination" do it "returns the correct title when room has destination, # of rooms and also type with many bedrooms" do sentence = "2 Bedroom Apartment in Chinatown" room.number_of_rooms = 2 room.room_type.type = "Apartment" room.destination.name = "Chinatown" expect(generator.send(:room_type_number_and_destination)).to eq (sentence) end it "returns the correct title when room has destination, # of rooms and also type with zero bedrooms (studio)" do sentence = "Studio Apartment in Chinatown" room.number_of_rooms = 0 room.room_type.type = "Apartment" room.destination.name = "Chinatown" expect(generator.send(:room_type_number_and_destination)).to match (sentence) end it "returns the correct title when room has destination, # of rooms (but no type)" do sentence = "2 Bedroom Property in Chinatown" room.number_of_rooms = 2 room.room_type = nil room.destination.name = "Chinatown" expect(generator.send(:room_type_number_and_destination)).to eq (sentence) end it "returns the correct title when room has number of rooms, neighborhood, city and room type" do sentence = "2 Bedroom Apartment in Chinatown, Singapore" room.number_of_rooms = 2 room.destination = nil room.room_type.type = "Apartment" room.neighborhood = "Chinatown" room.city = "Singapore" expect(generator.send(:room_type_number_and_destination)).to eq (sentence) end it "returns the correct title when room has neighborhood, city and room type with zero bedrooms (studio)" do sentence = "Studio Apartment in Chinatown" room.number_of_rooms = 0 room.destination = nil room.room_type.type = "Apartment" room.neighborhood = "Chinatown" room.city = "Singapore" expect(generator.send(:room_type_number_and_destination)).to match (sentence) end end describe "#amenities" do it "returns the correct sentence when room has all the specified amenities" do sentence = "with Aircon, Parking, Pool, Gym, Doorman, Balcony, and Breakfast-provided" room.airconditioning = true room.parking = true room.pool = true room.gym = true room.doorman = true room.breakfast = true room.balcony = true expect(generator.send(:amenities)).to match (sentence) end it "returns the correct sentence when room has only one specified amenities" do sentence = "with Breakfast-provided" room.breakfast = true expect(generator.send(:amenities)).to match (sentence) end it "returns the correct sentence when room has only one specified amenities" do room.airconditioning = nil room.parking = nil room.pool = nil room.gym = nil room.doorman = nil room.breakfast = nil room.balcony = nil expect(generator.send(:amenities)).to eq nil end end end