Решение на Пета задача - DataModel от Теодора Петкова

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

Към профила на Теодора Петкова

Резултати

  • 2 точки от тестове
  • 0 бонус точки
  • 2 точки общо
  • 9 успешни тест(а)
  • 16 неуспешни тест(а)

Код

class DataModel
attr_accessor :id
def self.attributes(*fields)
fields.each do |field|
getter(field)
setter(field)
end
end
def self.data_store(*)
end
def initialize(hash = {})
self.class.instance_methods(false).each do |att|
instance_variable_set("@#{att}", hash[att]) if hash.include?(att)
end
end
def save
end
def delete
end
def self.where(*)
end
def self.getter(attr_name)
define_method(attr_name) do
instance_variable_get("@#{attr_name}")
end
end
def self.setter(attr_name)
define_method("#{attr_name}=") do |attr_value|
instance_variable_set("@#{attr_name}", attr_value)
end
end
end
class IStore < NoMethodError
def create
raise NotImplementedError, "Implement the method 'create' in a child class"
end
def find
raise NotImplementedError, "Implement the method 'find' in a child class"
end
def update
raise NotImplementedError, "Implement the method 'update' in a child class"
end
def delete
raise NotImplementedError, "Implement the method 'delete' in a child class"
end
end
module Records
def self.contains_record(records, record)
record.all? do |key, value|
records.any? do |r_key, r_value|
key == r_key && value == r_value
end
end
end
end
class HashStore < IStore
extend Records
attr_reader :storage
def initialize
@id = 1
@storage = {}
end
def create(record)
@storage[@id] = record
@id += 1
end
def find(record)
(@storage.find_all do |_, s_value|
Records.contains_record(s_value, record)
end).map do |_, s_value|
s_value
end
end
def update(id, record)
@storage[id] = record
end
def delete(record)
@storage.each do |s_key, s_value|
@storage.delete(s_key) if Records.contains_record(s_value, record)
end
end
end
class ArrayStore < IStore
extend Records
attr_reader :storage
def initialize
@storage = []
end
def create(record)
@storage.push(record)
end
def find(record)
@storage.find_all do |s_value|
Records.contains_record(s_value, record)
end
end
def update(_, record)
storage.push(record)
end
def delete(record)
@storage.each do |s_value|
@storage.delete(s_value) if Records.contains_record(s_value, record)
end
end
end

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

.F.FFFFF.FFFFFF..F....FFF

Failures:

  1) DataModel has attributes and data_model getters
     Failure/Error: expect(user_model.attributes).to include :first_name
       expected [] to include :first_name
       Diff:
       @@ -1,2 +1,2 @@
       -[:first_name]
       +[]
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:22:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  2) DataModel has #find_by_<attribute> methods
     Failure/Error: expect(user_model.find_by_first_name('Ivan').map(&:id)).to eq [record.id]
     NoMethodError:
       undefined method `find_by_first_name' for #<Class:0x007f2f1f6f9fc8>
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:43:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  3) DataModel id generation creates id on first save and does not change it
     Failure/Error: expect(record.id).to_not be nil
       
       expected not #<NilClass:8> => nil
                got #<NilClass:8> => nil
       
       Compared using equal?, which compares object identity.
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:54:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  4) DataModel id generation does not reuse ids
     Failure/Error: expect(ivan.id).to eq 1
       
       expected: 1
            got: nil
       
       (compared using ==)
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:65:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  5) DataModel id generation does not break when there are two models with the same store
     Failure/Error: expect(ivan.id).to eq 1
       
       expected: 1
            got: nil
       
       (compared using ==)
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:83:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  6) DataModel equality comparison compares by id if both records are saved
     Failure/Error: modified_ivan = user_model.where(id: ivan.id).first
     NoMethodError:
       undefined method `first' for nil:NilClass
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:102:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  7) DataModel.where finds records by attributes
     Failure/Error: records = user_model.where(first_name: 'Ivan').map(&:last_name)
     NoMethodError:
       undefined method `map' for nil:NilClass
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:125:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  8) DataModel.where finds records by multiple attributes
     Failure/Error: ).map(&:last_name)
     NoMethodError:
       undefined method `map' for nil:NilClass
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:133:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  9) DataModel.where returns empty collection when nothing is found
     Failure/Error: expect(user_model.where(first_name: 'Petar')).to be_empty
     NoMethodError:
       undefined method `empty?' for nil:NilClass
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:139:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  10) DataModel.where raises an error if the query is by an unknown key
     Failure/Error: DataModel::UnknownAttributeError,
     NameError:
       uninitialized constant DataModel::UnknownAttributeError
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:144:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  11) DataModel#delete deletes only the record for which it is called
     Failure/Error: ivan.delete
     NoMethodError:
       undefined method `delete' for nil:NilClass
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:156:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  12) DataModel#delete raises an error if the record is not saved
     Failure/Error: DataModel::DeleteUnsavedRecordError
     NameError:
       uninitialized constant DataModel::DeleteUnsavedRecordError
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:164:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  13) HashStore behaves like a data store #update updates the attributes of a record with a given ID
     Failure/Error: expect(store.find(id: 2)).to eq [{id: 2, name: 'Georgi'}]
       
       expected: [{:id=>2, :name=>"Georgi"}]
            got: [{:id=>2, :name=>"Pesho"}, {:id=>2, :name=>"Georgi"}]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>2, :name=>"Georgi"}]
       +[{:id=>2, :name=>"Pesho"}, {:id=>2, :name=>"Georgi"}]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1b1bm6o/spec.rb:235
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:201:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  14) ArrayStore behaves like a data store #update updates the attributes of a record with a given ID
     Failure/Error: expect(store.find(id: 2)).to eq [{id: 2, name: 'Georgi'}]
       
       expected: [{:id=>2, :name=>"Georgi"}]
            got: [{:id=>2, :name=>"Pesho"}, {:id=>2, :name=>"Georgi"}]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>2, :name=>"Georgi"}]
       +[{:id=>2, :name=>"Pesho"}, {:id=>2, :name=>"Georgi"}]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1b1bm6o/spec.rb:239
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:201:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  15) ArrayStore behaves like a data store #update only updates records with the correct IDs
     Failure/Error: expect(store.find(id: 2)).to eq [{id: 2, name: 'Sasho'}]
       
       expected: [{:id=>2, :name=>"Sasho"}]
            got: [{:id=>2, :name=>"Pesho"}, {:id=>2, :name=>"Sasho"}]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>2, :name=>"Sasho"}]
       +[{:id=>2, :name=>"Pesho"}, {:id=>2, :name=>"Sasho"}]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1b1bm6o/spec.rb:239
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:213:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  16) ArrayStore behaves like a data store #delete can delete multiple records with a single query
     Failure/Error: expect(store.find({})).to eq [gosho]
       
       expected: [{:id=>3, :name=>"Gosho"}]
            got: [{:id=>2, :name=>"Pesho"}, {:id=>3, :name=>"Gosho"}]
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -[{:id=>3, :name=>"Gosho"}]
       +[{:id=>2, :name=>"Pesho"}, {:id=>3, :name=>"Gosho"}]
     Shared Example Group: "a data store" called from /tmp/d20161202-15620-1b1bm6o/spec.rb:239
     # /tmp/d20161202-15620-1b1bm6o/spec.rb:229:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.02687 seconds
25 examples, 16 failures

Failed examples:

rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:21 # DataModel has attributes and data_model getters
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:39 # DataModel has #find_by_<attribute> methods
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:48 # DataModel id generation creates id on first save and does not change it
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:62 # DataModel id generation does not reuse ids
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:74 # DataModel id generation does not break when there are two models with the same store
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:92 # DataModel equality comparison compares by id if both records are saved
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:124 # DataModel.where finds records by attributes
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:129 # DataModel.where finds records by multiple attributes
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:138 # DataModel.where returns empty collection when nothing is found
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:142 # DataModel.where raises an error if the query is by an unknown key
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:151 # DataModel#delete deletes only the record for which it is called
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:162 # DataModel#delete raises an error if the record is not saved
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:196 # HashStore behaves like a data store #update updates the attributes of a record with a given ID
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:196 # ArrayStore behaves like a data store #update updates the attributes of a record with a given ID
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:204 # ArrayStore behaves like a data store #update only updates records with the correct IDs
rspec /tmp/d20161202-15620-1b1bm6o/spec.rb:218 # ArrayStore behaves like a data store #delete can delete multiple records with a single query

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

Теодора обнови решението на 01.12.2016 20:26 (преди около 8 години)

+class DataModel
+ def self.attributes(*fields)
+ fields.each do |field|
+ getter(field)
+ setter(field)
+ end
+
+ end
+
+ def self.data_store(*)
+ end
+
+ def initialize(hash = {})
+ end
+
+ def save
+ end
+
+ def delete
+ end
+
+ def self.getter(attr_name)
+ define_method(attr_name) do
+ instance_variable_get("@#{attr_name}")
+ end
+ end
+
+ def self.setter(attr_name)
+ define_method("#{attr_name}=") do |attr_value|
+ instance_variable_set("@#{attr_name}", attr_value)
+ end
+ end
+end
+
+class IStore < NoMethodError
+ def create
+ raise NotImplementedError, "Implement the method 'create' in a child class"
+ end
+
+ def find
+ raise NotImplementedError, "Implement the method 'find' in a child class"
+ end
+
+ def update
+ raise NotImplementedError, "Implement the method 'update' in a child class"
+ end
+
+ def delete
+ raise NotImplementedError, "Implement the method 'delete' in a child class"
+ end
+end
+
+module Records
+ def self.contains_record(records, record)
+ record.all? do |key, value|
+ records.any? do |r_key, r_value|
+ key == r_key && value == r_value
+ end
+ end
+ end
+end
+class HashStore < IStore
+ extend Records
+ attr_reader :storage
+ def initialize
+ @id = 1
+ @storage = {}
+ end
+
+ def create(record)
+ @storage[@id] = record
+ @id += 1
+ end
+
+ def find(record)
+ (@storage.find_all do |_, s_value|
+ Records.contains_record(s_value, record)
+ end).map do |_, s_value|
+ s_value
+ end
+ end
+
+ def update(id, record)
+ @storage[id] = record
+ end
+
+ def delete(record)
+ @storage.each do |s_key, s_value|
+ @storage.delete(s_key) if Records.contains_record(s_value, record)
+ end
+ end
+end
+
+class ArrayStore < IStore
+ extend Records
+ attr_reader :storage
+ def initialize
+ @storage = []
+ end
+
+ def create(record)
+ @storage.push(record)
+ end
+
+ def find(record)
+ @storage.find_all do |s_value|
+ Records.contains_record(s_value, record)
+ end
+ end
+
+ def update(_, record)
+ storage.push(record)
+ end
+
+ def delete(record)
+ @storage.each do |s_value|
+ @storage.delete(s_value) if Records.contains_record(s_value, record)
+ end
+ end
+end

Теодора обнови решението на 01.12.2016 23:52 (преди около 8 години)

class DataModel
+ attr_accessor :id
+
def self.attributes(*fields)
fields.each do |field|
getter(field)
setter(field)
end
end
def self.data_store(*)
end
def initialize(hash = {})
+ self.class.instance_methods(false).each do |att|
+ instance_variable_set("@#{att}", hash[att]) if hash.include?(att)
+ end
end
def save
end
def delete
+ end
+
+ def self.where(*)
end
def self.getter(attr_name)
define_method(attr_name) do
instance_variable_get("@#{attr_name}")
end
end
def self.setter(attr_name)
define_method("#{attr_name}=") do |attr_value|
instance_variable_set("@#{attr_name}", attr_value)
end
end
end
class IStore < NoMethodError
def create
raise NotImplementedError, "Implement the method 'create' in a child class"
end
def find
raise NotImplementedError, "Implement the method 'find' in a child class"
end
def update
raise NotImplementedError, "Implement the method 'update' in a child class"
end
def delete
raise NotImplementedError, "Implement the method 'delete' in a child class"
end
end
module Records
def self.contains_record(records, record)
record.all? do |key, value|
records.any? do |r_key, r_value|
key == r_key && value == r_value
end
end
end
end
class HashStore < IStore
extend Records
attr_reader :storage
def initialize
@id = 1
@storage = {}
end
def create(record)
@storage[@id] = record
@id += 1
end
def find(record)
(@storage.find_all do |_, s_value|
Records.contains_record(s_value, record)
end).map do |_, s_value|
s_value
end
end
def update(id, record)
@storage[id] = record
end
def delete(record)
@storage.each do |s_key, s_value|
@storage.delete(s_key) if Records.contains_record(s_value, record)
end
end
end
class ArrayStore < IStore
extend Records
attr_reader :storage
def initialize
@storage = []
end
def create(record)
@storage.push(record)
end
def find(record)
@storage.find_all do |s_value|
Records.contains_record(s_value, record)
end
end
def update(_, record)
storage.push(record)
end
def delete(record)
@storage.each do |s_value|
@storage.delete(s_value) if Records.contains_record(s_value, record)
end
end
end