Решение на Четвърта задача от Александър Иванов

Обратно към всички решения

Към профила на Александър Иванов

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 21 успешни тест(а)
  • 20 неуспешни тест(а)

Код

class PrivacyFilter
attr_accessor :preserve_phone_country_code, :preserve_email_hostname, :partially_preserve_email_username
def initialize(text)
@text = text
end
def filtered
text = obfuscate_emails @text
obfuscate_phones text
end
private
def obfuscate_phones(text)
text.gsub /(.*?)((?:\B\+|\b)[\d \-()]+\d)/ do |string|
left, phone = $1, $2
Validations.phone?(phone) ? left + hide_phone(phone) : string
end
end
def hide_phone(phone)
return "#{$1} [FILTERED]" if preserve_phone_country_code and phone =~ /^((?:00|\+)[1-9]\d?\d?)/
"[PHONE]"
end
def obfuscate_emails(text)
text.gsub /(.*)\b([^@\s]+@[^@\s]+)\b/ do |string|
left, email = $1, $2
Validations.email?(email) ? left + hide_email(email) : string
end
end
def hide_email(email)
return "#{$1}[FILTERED]@#{$2}" if partially_preserve_email_username and email =~ /(?:(...).{3,}|.+)@(.+)/
return "[FILTERED]@#{$1}" if preserve_email_hostname and email =~ /.+@(.+)/
"[EMAIL]"
end
end
module Validations
def self.email?(text)
text =~ /^[\da-zA-Z][\w+.]{,200}@(.+)$/ && self.hostname?($1) ? true : false
end
def self.phone?(text)
!!if text =~ /^(?:0[1-9]\d|(?:00|\+)[1-9]\d?\d?)(.+\d)$/
main_phone_part = $1
if main_phone_part.scan(/[ \-()]/).size < 2
main_phone_part.gsub(/[ \-()]/, '') =~ /\d{6,11}/
end
end
end
def self.hostname?(text)
text =~ /^([\da-zA-Z][\da-zA-Z-]{,61}[\da-zA-Z]\.\g<1>*)[\da-zA-Z]{2,3}(\.[a-zA-Z][a-zA-Z])?$/ ? true : false
end
def self.ip_address?(text)
if text =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
$~.captures.map(&:to_i).all? { |number| number >= 0 and number <= 255 }
else
false
end
end
def self.number?(text)
text =~ /^-?(0|[1-9]\d+)(\.\d+)?$/ ? true : false
end
def self.integer?(text)
text =~ /^-?(0|[1-9]\d+)$/ ? true : false
end
def self.date?(text)
text =~ /^\d\d\d\d-(\d\d)-(\d\d)$/ && $1.to_i.between?(1, 12) && $2.to_i.between?(1, 31) ? true : false
end
def self.time?(text)
if text =~ /^(\d\d):(\d\d):(\d\d)$/ && $1.to_i.between?(0, 23) && $2.to_i.between?(0, 59) && $3.to_i.between?(0, 59)
true
else
false
end
end
def self.date_time?(text)
if text =~ /^(.+)[\sT](.+)$/
date, time = $1, $2
self.date?(date) and self.time?(time)
else
false
end
end
end

Лог от изпълнението

..F.F...F.FFFF..FF.FFFF.FF.F.FF.....F...F

Failures:

  1) PrivacyFilter obfuscates more complicated emails
     Failure/Error: filter(text).should eq filtered
       
       expected: "[EMAIL]"
            got: "some.user+and-more-[EMAIL]"
       
       (compared using ==)
     # /tmp/d20130203-23049-12ell0x/spec.rb:40:in `block (3 levels) in <top (required)>'
     # /tmp/d20130203-23049-12ell0x/spec.rb:39:in `each'
     # /tmp/d20130203-23049-12ell0x/spec.rb:39:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) PrivacyFilter allows email hostname to be preserved
     Failure/Error: filter_email_usernames('some12-+3@exa.mple.com').should eq '[FILTERED]@exa.mple.com'
       
       expected: "[FILTERED]@exa.mple.com"
            got: "some12-+[FILTERED]@exa.mple.com"
       
       (compared using ==)
     # /tmp/d20130203-23049-12ell0x/spec.rb:61:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) PrivacyFilter filters more complex phone numbers
     Failure/Error: filter(text).should eq filtered
       
       expected: "[PHONE]"
            got: "+1 555 123-456"
       
       (compared using ==)
     # /tmp/d20130203-23049-12ell0x/spec.rb:85:in `block (3 levels) in <top (required)>'
     # /tmp/d20130203-23049-12ell0x/spec.rb:84:in `each'
     # /tmp/d20130203-23049-12ell0x/spec.rb:84:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) PrivacyFilter preserves whitespace around phones
     Failure/Error: filter(' +359881212-12-1 2 or...').should eq ' [PHONE] or...'
       
       expected: " [PHONE] or..."
            got: " +359881212-12-1 2 or..."
       
       (compared using ==)
     # /tmp/d20130203-23049-12ell0x/spec.rb:101:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) PrivacyFilter filters more than one phone or email
     Failure/Error: filter(text).should eq filtered
       
       expected: "\n      Contacts\n\n      Phones: [PHONE] or [PHONE]\n      Email: [EMAIL] or [EMAIL]\n    "
            got: "\n      Contacts\n\n      Phones: +1 (555) 123-456-99 or 004412125543\n      Email: contact@company.co.uk or [EMAIL]\n    "
       
       (compared using ==)
       
       Diff:
       @@ -1,7 +1,7 @@
        
              Contacts
        
       -      Phones: [PHONE] or [PHONE]
       -      Email: [EMAIL] or [EMAIL]
       +      Phones: +1 (555) 123-456-99 or 004412125543
       +      Email: contact@company.co.uk or [EMAIL]
            
     # /tmp/d20130203-23049-12ell0x/spec.rb:119:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  6) PrivacyFilter allows country code to be preserved for internationally-formatted phone numbers
     Failure/Error: filter.filtered.should eq filtered
       
       expected: "Phone: +359 [FILTERED]"
            got: "Phone: +359 2 555-1212"
       
       (compared using ==)
     # /tmp/d20130203-23049-12ell0x/spec.rb:132:in `block (3 levels) in <top (required)>'
     # /tmp/d20130203-23049-12ell0x/spec.rb:129:in `each'
     # /tmp/d20130203-23049-12ell0x/spec.rb:129:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  7) PrivacyFilter separates preserved country code from filtered phone with a space
     Failure/Error: filter.filtered.should eq filtered
       
       expected: "Phone: 0025 [FILTERED]"
            got: "Phone: 0025 (55) 12 12255"
       
       (compared using ==)
     # /tmp/d20130203-23049-12ell0x/spec.rb:144:in `block (3 levels) in <top (required)>'
     # /tmp/d20130203-23049-12ell0x/spec.rb:141:in `each'
     # /tmp/d20130203-23049-12ell0x/spec.rb:141:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  8) Validations can validate more complex emails
     Failure/Error: Validations.email?(email).should be(valid)
       
       expected #<TrueClass:2> => true
            got #<FalseClass:0> => false
       
       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       'actual.should eq(expected)' if you don't care about
       object identity in this example.
     # /tmp/d20130203-23049-12ell0x/spec.rb:171:in `block (3 levels) in <top (required)>'
     # /tmp/d20130203-23049-12ell0x/spec.rb:170:in `each'
     # /tmp/d20130203-23049-12ell0x/spec.rb:170:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  9) Validations does not break on emails in multiline strings
     Failure/Error: Validations.email?("foo@bar.com\nwat?").should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-12ell0x/spec.rb:176:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  10) Validations can validate more complex phone numbers
     Failure/Error: Validations.phone?(phone).should be(valid)
       
       expected #<TrueClass:2> => true
            got #<FalseClass:0> => false
       
       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       'actual.should eq(expected)' if you don't care about
       object identity in this example.
     # /tmp/d20130203-23049-12ell0x/spec.rb:210:in `block (3 levels) in <top (required)>'
     # /tmp/d20130203-23049-12ell0x/spec.rb:209:in `each'
     # /tmp/d20130203-23049-12ell0x/spec.rb:209:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  11) Validations does not break on phones in multiline strings
     Failure/Error: Validations.phone?("0885123123\nwat?").should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-12ell0x/spec.rb:215:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  12) Validations validates hostnames
     Failure/Error: Validations.hostname?('1.2.3.4.xip.io').should be_true
       expected: true value
            got: false
     # /tmp/d20130203-23049-12ell0x/spec.rb:222:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  13) Validations handles multiline strings in hostname validation properly
     Failure/Error: Validations.hostname?("foo.com\n").should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-12ell0x/spec.rb:233:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  14) Validations handles multiline strings in IP validation properly
     Failure/Error: Validations.ip_address?("8.8.8.8\n").should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-12ell0x/spec.rb:245:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  15) Validations validates numbers
     Failure/Error: Validations.number?('9').should be_true
       expected: true value
            got: false
     # /tmp/d20130203-23049-12ell0x/spec.rb:254:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  16) Validations handles multiline strings in numbers validation properly
     Failure/Error: Validations.number?("42\n24").should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-12ell0x/spec.rb:274:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  17) Validations validates more complex integers
     Failure/Error: Validations.integer?('9').should be_true
       expected: true value
            got: false
     # /tmp/d20130203-23049-12ell0x/spec.rb:288:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  18) Validations handles multiline strings in integer validation properly
     Failure/Error: Validations.number?("42\n24").should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-12ell0x/spec.rb:295:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  19) Validations handles newlines in date validation
     Failure/Error: Validations.date?("2012-11-19\n").should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-12ell0x/spec.rb:327:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  20) Validations handles newlines in time and datetime validation
     Failure/Error: Validations.time?("12:01:01\n").should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-12ell0x/spec.rb:360:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.05242 seconds
41 examples, 20 failures

Failed examples:

rspec /tmp/d20130203-23049-12ell0x/spec.rb:30 # PrivacyFilter obfuscates more complicated emails
rspec /tmp/d20130203-23049-12ell0x/spec.rb:59 # PrivacyFilter allows email hostname to be preserved
rspec /tmp/d20130203-23049-12ell0x/spec.rb:76 # PrivacyFilter filters more complex phone numbers
rspec /tmp/d20130203-23049-12ell0x/spec.rb:100 # PrivacyFilter preserves whitespace around phones
rspec /tmp/d20130203-23049-12ell0x/spec.rb:104 # PrivacyFilter filters more than one phone or email
rspec /tmp/d20130203-23049-12ell0x/spec.rb:122 # PrivacyFilter allows country code to be preserved for internationally-formatted phone numbers
rspec /tmp/d20130203-23049-12ell0x/spec.rb:136 # PrivacyFilter separates preserved country code from filtered phone with a space
rspec /tmp/d20130203-23049-12ell0x/spec.rb:160 # Validations can validate more complex emails
rspec /tmp/d20130203-23049-12ell0x/spec.rb:175 # Validations does not break on emails in multiline strings
rspec /tmp/d20130203-23049-12ell0x/spec.rb:184 # Validations can validate more complex phone numbers
rspec /tmp/d20130203-23049-12ell0x/spec.rb:214 # Validations does not break on phones in multiline strings
rspec /tmp/d20130203-23049-12ell0x/spec.rb:218 # Validations validates hostnames
rspec /tmp/d20130203-23049-12ell0x/spec.rb:232 # Validations handles multiline strings in hostname validation properly
rspec /tmp/d20130203-23049-12ell0x/spec.rb:244 # Validations handles multiline strings in IP validation properly
rspec /tmp/d20130203-23049-12ell0x/spec.rb:250 # Validations validates numbers
rspec /tmp/d20130203-23049-12ell0x/spec.rb:273 # Validations handles multiline strings in numbers validation properly
rspec /tmp/d20130203-23049-12ell0x/spec.rb:283 # Validations validates more complex integers
rspec /tmp/d20130203-23049-12ell0x/spec.rb:294 # Validations handles multiline strings in integer validation properly
rspec /tmp/d20130203-23049-12ell0x/spec.rb:326 # Validations handles newlines in date validation
rspec /tmp/d20130203-23049-12ell0x/spec.rb:359 # Validations handles newlines in time and datetime validation

История (2 версии и 0 коментара)

Александър обнови решението на 28.11.2012 07:54 (преди почти 12 години)

+class PrivacyFilter
+ attr_accessor :preserve_phone_country_code, :preserve_email_hostname, :partially_preserve_email_username
+
+ def initialize(text)
+ @text = text
+ end
+
+ def filtered
+ text = obfuscate_emails @text
+ obfuscate_phones text
+ end
+
+ private
+
+ def obfuscate_phones(text)
+ text.gsub /(.*?)((?:\B\+|\b)[\d \-()]+\d)/ do |string|
+ left, phone = $1, $2
+
+ Validations.phone?(phone) ? left + hide_phone(phone) : string
+ end
+ end
+
+ def hide_phone(phone)
+ return "#{$1} [FILTERED]" if preserve_phone_country_code and phone =~ /^((?:00|\+)[1-9]\d?\d?)/
+ "[PHONE]"
+ end
+
+ def obfuscate_emails(text)
+ text.gsub /(.*)\b([^@\s]+@[^@\s]+)\b/ do |string|
+ left, email = $1, $2
+
+ Validations.email?(email) ? left + hide_email(email) : string
+ end
+ end
+
+ def hide_email(email)
+ return "#{$1}[FILTERED]@#{$2}" if partially_preserve_email_username and email =~ /(?:(...).{3,}|.+)@(.+)/
+ return "[FILTERED]@#{$1}" if preserve_email_hostname and email =~ /.+@(.+)/
+ "[EMAIL]"
+ end
+end
+
+module Validations
+ def self.email?(text)
+ text =~ /^[\da-zA-Z][\w+.]{,200}@(.+)$/ and self.hostname? $1
+ end
+
+ def self.phone?(text)
+ if text =~ /^(?:0[1-9]\d|(?:00|\+)[1-9]\d?\d?)(.+\d)$/
+ main_phone_part = $1
+ if main_phone_part.scan(/[ \-()]/).size < 2
+ main_phone_part.gsub(/[ \-()]/, '') =~ /\d{6,11}/
+ end
+ end
+ end
+
+ def self.hostname?(text)
+ text =~ /^([\da-zA-Z][\da-zA-Z-]{,61}[\da-zA-Z]\.\g<1>*)[\da-zA-Z]{2,3}(\.[a-zA-Z][a-zA-Z])?$/ ? true : false
+ end
+
+ def self.ip_address?(text)
+ if text =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
+ $~.captures.map(&:to_i).all? { |number| number >= 0 and number <= 255 }
+ end
+ end
+
+ def self.number?(text)
+ text =~ /^-?(0|[1-9]\d+)(\.\d+)?$/ ? true : false
+ end
+
+ def self.integer?(text)
+ text =~ /^-?(0|[1-9]\d+)$/ ? true : false
+ end
+
+ def self.date?(text)
+ text =~ /^\d\d\d\d-(\d\d)-(\d\d)$/ and $1.to_i.between?(1, 12) and $2.to_i.between?(1, 31)
+ end
+
+ def self.time?(text)
+ text =~ /^(\d\d):(\d\d):(\d\d)$/ and $1.to_i.between?(0, 23) and $2.to_i.between?(0, 59) and $3.to_i.between?(0, 59)
+ end
+
+ def self.date_time?(text)
+ if text =~ /^(.+)[\sT](.+)$/
+ date, time = $1, $2
+ self.date?(date) and self.time?(time)
+ end
+ end
+end

Александър обнови решението на 28.11.2012 08:30 (преди почти 12 години)

class PrivacyFilter
attr_accessor :preserve_phone_country_code, :preserve_email_hostname, :partially_preserve_email_username
def initialize(text)
@text = text
end
def filtered
text = obfuscate_emails @text
obfuscate_phones text
end
private
def obfuscate_phones(text)
text.gsub /(.*?)((?:\B\+|\b)[\d \-()]+\d)/ do |string|
left, phone = $1, $2
Validations.phone?(phone) ? left + hide_phone(phone) : string
end
end
def hide_phone(phone)
return "#{$1} [FILTERED]" if preserve_phone_country_code and phone =~ /^((?:00|\+)[1-9]\d?\d?)/
"[PHONE]"
end
def obfuscate_emails(text)
text.gsub /(.*)\b([^@\s]+@[^@\s]+)\b/ do |string|
left, email = $1, $2
Validations.email?(email) ? left + hide_email(email) : string
end
end
def hide_email(email)
return "#{$1}[FILTERED]@#{$2}" if partially_preserve_email_username and email =~ /(?:(...).{3,}|.+)@(.+)/
return "[FILTERED]@#{$1}" if preserve_email_hostname and email =~ /.+@(.+)/
"[EMAIL]"
end
end
module Validations
def self.email?(text)
- text =~ /^[\da-zA-Z][\w+.]{,200}@(.+)$/ and self.hostname? $1
+ text =~ /^[\da-zA-Z][\w+.]{,200}@(.+)$/ && self.hostname?($1) ? true : false
end
def self.phone?(text)
- if text =~ /^(?:0[1-9]\d|(?:00|\+)[1-9]\d?\d?)(.+\d)$/
+ !!if text =~ /^(?:0[1-9]\d|(?:00|\+)[1-9]\d?\d?)(.+\d)$/
main_phone_part = $1
if main_phone_part.scan(/[ \-()]/).size < 2
main_phone_part.gsub(/[ \-()]/, '') =~ /\d{6,11}/
end
end
end
def self.hostname?(text)
text =~ /^([\da-zA-Z][\da-zA-Z-]{,61}[\da-zA-Z]\.\g<1>*)[\da-zA-Z]{2,3}(\.[a-zA-Z][a-zA-Z])?$/ ? true : false
end
def self.ip_address?(text)
if text =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
$~.captures.map(&:to_i).all? { |number| number >= 0 and number <= 255 }
+ else
+ false
end
end
def self.number?(text)
text =~ /^-?(0|[1-9]\d+)(\.\d+)?$/ ? true : false
end
def self.integer?(text)
text =~ /^-?(0|[1-9]\d+)$/ ? true : false
end
def self.date?(text)
- text =~ /^\d\d\d\d-(\d\d)-(\d\d)$/ and $1.to_i.between?(1, 12) and $2.to_i.between?(1, 31)
+ text =~ /^\d\d\d\d-(\d\d)-(\d\d)$/ && $1.to_i.between?(1, 12) && $2.to_i.between?(1, 31) ? true : false
end
def self.time?(text)
- text =~ /^(\d\d):(\d\d):(\d\d)$/ and $1.to_i.between?(0, 23) and $2.to_i.between?(0, 59) and $3.to_i.between?(0, 59)
+ if text =~ /^(\d\d):(\d\d):(\d\d)$/ && $1.to_i.between?(0, 23) && $2.to_i.between?(0, 59) && $3.to_i.between?(0, 59)
+ true
+ else
+ false
+ end
end
def self.date_time?(text)
if text =~ /^(.+)[\sT](.+)$/
date, time = $1, $2
self.date?(date) and self.time?(time)
+ else
+ false
end
end
end