diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..fb7a88e1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,51 @@ +*.gem +*.rbc +/.config +/coverage/ +/InstalledFiles +/pkg/ +/spec/reports/ +/spec/examples.txt +/test/tmp/ +/test/version_tmp/ +/tmp/ + +# Used by dotenv library to load environment variables. +# .env + +## Specific to RubyMotion: +.dat* +.repl_history +build/ +*.bridgesupport +build-iPhoneOS/ +build-iPhoneSimulator/ + +## Specific to RubyMotion (use of CocoaPods): +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# vendor/Pods/ + +## Documentation cache and generated files: +/.yardoc/ +/_yardoc/ +/doc/ +/rdoc/ + +## Environment normalization: +/.bundle/ +/vendor/bundle +/lib/bundler/man/ + +# for a library or gem, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# Gemfile.lock +# .ruby-version +# .ruby-gemset + +# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: +.rvmrc +.DS_Store diff --git a/.ruby-gemset b/.ruby-gemset new file mode 100644 index 00000000..73f861e5 --- /dev/null +++ b/.ruby-gemset @@ -0,0 +1 @@ +farmar diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000..276cbf9e --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.3.0 diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..4ac00651 --- /dev/null +++ b/Rakefile @@ -0,0 +1,15 @@ +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.libs = ["lib", "specs"] + t.warning = false + t.verbose = false + t.test_files = FileList['specs/*_spec.rb'] + #convention: testfiles need to end with #_spec.rb + #old version: _test.rb + puts "Running TestTask" +end + +task default: :test do #default test, run TestTask first(built in, knows test -->TestTask) + puts "Running my Rakefile" +end diff --git a/lib/far_mar.rb b/lib/far_mar.rb new file mode 100644 index 00000000..e180582b --- /dev/null +++ b/lib/far_mar.rb @@ -0,0 +1,68 @@ +# gems your project needs +require 'csv' + +# our namespace module +module FarMar; end + +# all of our data classes that live in the module +require_relative './utils' +require_relative './finder' +require_relative './far_mar/farmar_market' +require_relative './far_mar/farmar_product' +require_relative './far_mar/farmar_sale' +require_relative './far_mar/farmar_vendor' + + + +# ...require all needed classes + + +# puts FarMar::Market.find("5").inspect +# puts FarMar::Market.new.vendors("3").inspect + +# vendor = FarMar::Vendor.new("3", "Breitenberg Inc", "5", "1") +# puts vendor.revenue + +# product = FarMar::Product.new("1","Dry Beets","1") +# puts product.sales +# product = FarMar::Product.new("1","Dry Beets","1") +# puts product.number_of_sales + +# puts FarMar::Sale.between("2013-11-11 18:43:56 -0800", "2013-11-12 12:00:35 -0800").size +# #=> 1294 + +# market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") +# puts market.products("2").size +# => 3 + +# puts FarMar::Market.search("school").size + + # market = FarMar::Market.new("2","Silverdale Farmers Market","98383","Silverdale","Kitsap","Washington","98383") + # puts market.prefered_vendor_direct.inspect + + # market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") + # puts market.prefered_vendor("2013-11-07").inspect + # => # + +# market = FarMar::Market.new("2","Silverdale Farmers Market","98383","Silverdale","Kitsap","Washington","98383") +# puts market.worst_vendor_direct(FarMar::Vendor.all).inspect +# #=> +# +# market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") +# puts market.worst_vendor("2013-11-07").inspect +# #=> + +# puts FarMar::Vendor.most_revenue(3).inspect + +# puts FarMar::Vendor.most_items(3).inspect + +# puts FarMar::Vendor.revenue("2013-11-07") +# #=>8995506.0 + +# puts FarMar::Sale.find_by_vendor_id("3").inspect +# vendor = FarMar::Vendor.new("3", "Breitenberg Inc", "5", "1") +# puts vendor.revenue("2013-11-13") +# # =>9128.0 + +puts FarMar::Product.most_revenue(1).inspect +#=>7895 diff --git a/lib/far_mar/farmar_market.rb b/lib/far_mar/farmar_market.rb new file mode 100644 index 00000000..ca4c62fa --- /dev/null +++ b/lib/far_mar/farmar_market.rb @@ -0,0 +1,128 @@ +# lib/farmar_market.rb +# require_relative '../far_mar' +require 'date' + +class FarMar::Market < Finder + attr_reader :id, :name + def initialize(id, name, address, city, county, state, zip) + @id = id + @name = name + @address = address + @city = city + @county = county + @state = state + @zip = zip + end + + # return an array of class Market objects + def self.all + market_csv_file = "/Users/mengyao/ADA_class/FarMar/support/markets.csv" + + markets = [] + CSV.foreach(market_csv_file) do |row| + id = row[0].to_s + name = row[1].to_s + address =row[2].to_s + city = row[3].to_s + county = row[4].to_s + state = row[5].to_s + zip = row[6].to_s + markets << FarMar::Market.new(id, name, address, city, county, state, zip) + end + return markets + end + + # =========inherite .find(id) from Finder class=========== + # return an Market object that corresponds to the given market id + # def self.find(id) + # found_market = nil + # all.each do |market| + # if market.id == id + # found_market = market + # break + # end + # end + # return found_market + # end + #============================================================ + + # return an array of FarMar::Market objects where the market name or vendor name contain the search_term + def self.search(search_term) + term = search_term.downcase + # return an array of Market objects found with the matched market name or vendor name + return FarMar::Market.all.select do |market| + # a Market obejct's market name + market_name = market.name + # a Market object's associated (an array of) Vendor objects + vendors = FarMar::Vendor.by_market(market.id) + # get an array of each Vendor objects' vendor name + vendor_names = vendors.map!{|vendor| vendor.name} + # find search_term in market name(a string) and in each vendor name in an array of vendor names string + market_name.downcase.include?(term) || vendor_names.any?{ |vendor_name| vendor_name.downcase.include?(term) } + end + end + + # return an array of FarMar::Product objects that are associated to the market through the FarMar::Vendor class. + # In another word, input a market_id and return the Product objects that associated with that market_id. + def products(market_id) + # return an array of its associated Vendor objects + vendors = FarMar::Vendor.by_market(market_id) + # iterate over all vendor_ids. for each vendor_id, return Product objects that associated with this vendor_id. + return vendors.map do |vendor| + FarMar::Product.all.select { |product| product.vendor_id == vendor.id } + end.flatten + # last step return array of array, call method flatten over return result + end + + # return the Vendor object with the highest revenue among a group of vendors + def prefered_vendor_direct(vendors) + # vendors => FarMar::Vendor.all can put this in method call + # get an array Vendor objects sorted by vendor revenue in accending order + vendors_by_revenue = vendors.sort_by { |vendor| vendor.revenue } + # get the vendor that has the highest revenue(the last element in the array) + return vendors_by_revenue.last + end + + # return an array of FarMar::Vendor objects that are associated with the market by the market_id field + def vendors + return FarMar::Vendor.all.select { |vendor| @id == vendor.market_id } + end + + # ====================about MIXIN:========================= + # I access Utils here directly and call get_day_range method. + # I can use mixin, put "extend" on top and outside the Market class. + # I did not do it that way as here we do not want to expose the method to this class. But I got the concept. + # ========================================================= + + # return the Vendor object with the highest revenue for the given date + def prefered_vendor(date) + beginning_time, end_time = Utils.get_day_range(date) + # get an array of Sale objects in the given date + sales = FarMar::Sale.between(beginning_time, end_time) + # get an array of Vendors associated with the Sale objects + vendors = sales.map{|sale|sale.vendor} + # get the prefered vendor associate with the Sale object on that date + return self.prefered_vendor_direct(vendors) + end + + # returnsthe vendor with the lowest revenue + def worst_vendor_direct(vendors) + # vendors => FarMar::Vendor.all can put this in method call + # get an array Vendor objects sorted by vendor revenue in accending order + vendors_by_revenue = vendors.sort_by { |vendor| vendor.revenue } + # get the vendor that has the lowest revenue(the last element in the array) + return vendors_by_revenue.first + end + + # return the vendor with the lowest revenue on the given date + def worst_vendor(date) + beginning_time, end_time = Utils.get_day_range(date) + # get an array of Sale objects in the given date + sales = FarMar::Sale.between(beginning_time, end_time) + # get an array of Vendors associated with the Sale objects + vendors = sales.map{|sale| sale.vendor} + # get the prefered vendor associate with the Sale object on that date + return self.worst_vendor_direct(vendors) + end + +end diff --git a/lib/far_mar/farmar_product.rb b/lib/far_mar/farmar_product.rb new file mode 100644 index 00000000..9ad55c1c --- /dev/null +++ b/lib/far_mar/farmar_product.rb @@ -0,0 +1,78 @@ +# lib/farmar_product.rb +# require_relative '../far_mar' + +class FarMar::Product < Finder + attr_reader :id, :vendor_id + def initialize(id, name, vendor_id) + @id = id + @name = name + @vendor_id = vendor_id + end + + # return an array of class product objects + def self.all + if @products != nil + return @products + end + + product_csv_file = "/Users/mengyao/ADA_class/FarMar/support/products.csv" + + products = [] + CSV.foreach(product_csv_file) do |row| + id = row[0].to_s + name = row[1].to_s + vendor_id =row[2].to_s + + products << FarMar::Product.new(id, name, vendor_id) + end + + @products = products + return @products + end + + # =========inherite .find(id) from Finder class=========== + # # return an product object that corresponds to the given product id + # def self.find(id) + # found_product = nil + # all.each do |product| + # if id == product.id + # found_product = product + # break + # end + # end + # return found_product + # end + #============================================================ + + # returns all of the FarMar::Product objects with the given vendor_id + def self.by_vendor(vendor_id) + return self.all.select {|product| product.vendor_id == vendor_id } + end + + # returns the top n product instances ranked by total revenue + def self.most_revenue(n) + # get an array of Product objects sorted by revenue in descending order + products_by_revenue = FarMar::Product.all.sort_by {|product| product.vendor.revenue}.reverse + # get the top n Vendor objecthighest revenue + return products_by_revenue.slice(0...n) + + end + + # returns an array of FarMar::Vendor objects that is associated with Product's vendor_id + def vendor + return FarMar::Vendor.find(@vendor_id) + end + + # return an array of FarMar::Sale objects that are associated with the product_id + def sales + return FarMar::Sale.find_by_product_id(@id) + end + + # returns the number of times this product has been sold(fixnum) + def number_of_sales + # means return the size of array of Sale objects with the same product_id + return self.sales.size + end + + +end diff --git a/lib/far_mar/farmar_sale.rb b/lib/far_mar/farmar_sale.rb new file mode 100644 index 00000000..8761f424 --- /dev/null +++ b/lib/far_mar/farmar_sale.rb @@ -0,0 +1,100 @@ +# lib/farmar_sale.rb +# require_relative '../far_mar' +require 'date' + +class FarMar::Sale < Finder + attr_reader :id, :vendor_id, :amount, :product_id, :purchase_time + def initialize(id, amount, purchase_time, vendor_id, product_id) + @id = id + @amount = amount + @purchase_time = purchase_time + @vendor_id = vendor_id + @product_id = product_id + end + + # idempotently load data + def self.load + if @sales != nil + # we have loaded this before, do not load again + return + end + + sale_csv_file = "/Users/mengyao/ADA_class/FarMar/support/sales.csv" + + @sales = [] + # index the sales by various IDs + @sale_by_id = {} + @sales_by_product_id = {} + @sales_by_vendor_id = {} + + CSV.foreach(sale_csv_file) do |row| + id = row[0].to_s + amount = row[1].to_f + purchase_time = DateTime.parse(row[2]) + vendor_id = row[3].to_s + product_id = row[4].to_s + + new_sale = FarMar::Sale.new(id, amount, purchase_time, vendor_id, product_id) + @sales << new_sale + # ensure that any new product_id key starts with a [] value + @sales_by_product_id[product_id] ||= [] + @sales_by_product_id[product_id] << new_sale + @sale_by_id[id] = new_sale + + @sales_by_vendor_id[vendor_id] ||= [] + @sales_by_vendor_id[vendor_id] << new_sale + end + end + + + # return an array of Sale objects + def self.all + load + return @sales + end + + #================Why I did not make find method inherite from Find====== + # Since I optimized the Sale class by a different structure, I would not + # inherite it from the Finder class. I will leave this refactor in the future + # if I have time. + #======================================================================= + + # return an Sale object that corresponds to the given sale id. + def self.find(id) + load + return @sale_by_id[id] + end + + # return array of Sale objects that is about the given product_id + def self.find_by_product_id(product_id) + load + return @sales_by_product_id[product_id] || [] + end + + # return array of Sale objects that is about the given vendor_id + def self.find_by_vendor_id(vendor_id) + load + return @sales_by_vendor_id[vendor_id] || [] + end + + # returns an array of FarMar::Sale objects where the purchase time is between the two times given as arguments + # Assume beginning_time and end_time are in String data type + def self.between(beginning_time, end_time) + FarMar::Sale.all.select do |sale| + purchase_time_object = sale.purchase_time + purchase_time_object >= beginning_time && purchase_time_object <= end_time + end + end + + # returns an array of FarMar::Vendor objects that is associated with Sale's vendor_id + def vendor + return FarMar::Vendor.find(@vendor_id) + end + + # returns an array of FarMar::Product objects that is associated with Sale's product_id + def product + return FarMar::Product.find(@product_id) + end + + +end diff --git a/lib/far_mar/farmar_vendor.rb b/lib/far_mar/farmar_vendor.rb new file mode 100644 index 00000000..f369c8f2 --- /dev/null +++ b/lib/far_mar/farmar_vendor.rb @@ -0,0 +1,116 @@ +# lib/farmar_vendor.rb +# require_relative '../far_mar' + +class FarMar::Vendor < Finder + attr_reader :id, :market_id, :name + def initialize(id, name, employees_num, market_id) + @id = id + @name = name + @employees_num = employees_num + @market_id = market_id + end + + # load vendor infomation from vendor csv file + # return an array of class vendor objects + def self.all + if @vendors != nil + return @vendors + end + + vendor_csv_file = "/Users/mengyao/ADA_class/FarMar/support/vendors.csv" + + vendors = [] + CSV.foreach(vendor_csv_file) do |row| + id = row[0].to_s + name = row[1].to_s + employees_num =row[2].to_s + market_id = row[3].to_s + + vendors << FarMar::Vendor.new(id, name, employees_num, market_id) + end + @vendors = vendors + return @vendors + end + + # =========inherite .find(id) from Finder class=========== + # identify vendor information by vendor id + # return an vendor object that corresponds to the given vendor id + # def self.find(id) + # found_vendor = nil + # all.each do |vendor| + # if id == vendor.id + # found_vendor = vendor + # break + # end + # end + # return found_vendor + # end + # ========================================================= + + # return all of the FarMar::Vendor objects with the given market_id + def self.by_market(market_id) + return self.all.select {|vendor| vendor.market_id == market_id } + end + + # return an array of the top n Vendor objects ranked by total revenue + def self.most_revenue(n) + # get an array of vendors sorted by revenue in descending order + vendors_by_revenue = FarMar::Vendor.all.sort_by {|vendor| vendor.revenue}.reverse + # get the top n Vendor objecthighest revenue + return vendors_by_revenue.slice(0...n) + end + + # returns the top n vendor instances ranked by total number of items sold + def self.most_items(n) + # get an array of vendors sorted by number of item sold in descending order + vendors_by_revenue = FarMar::Vendor.all.sort_by {|vendor| FarMar::Sale.find_by_vendor_id(vendor.id).size}.reverse + # get the top n Vendor objecthighest revenue + return vendors_by_revenue.slice(0...n) + end + + # returns the total revenue for that date across all vendors + def self.revenue(date) + beginning_time, end_time = Utils.get_day_range(date) + # return an array of Sale objects in the given date + sales = FarMar::Sale.between(beginning_time, end_time) + + # add up the sale amount and return the sum + return sales.inject(0.0) {|sum, sale| sum + sale.amount} + end + + # return an array of FarMar::Market objects that are associated with the market_id + def market + return FarMar::Market.find(@market_id) + end + + # return an array of FarMar::Product objects that are associated with the vendor_id + def products + return FarMar::Product.all.select { |product| product.vendor_id == @id } + end + + # return an array of FarMar::Sale objects that are associated with the vendor_id + def sales + return FarMar::Sale.find_by_vendor_id(@id) + end + + # returns the sum of all of the vendor's sales in cents(a float) + def revenue_all_sales + # add up the sale amount and return the sum + return self.sales.inject(0.0) {|sum, sale| sum + sale.amount} + end + + # returns the total revenue for that specific purchase date and Vendor object + def revenue(date = nil) + if date == nil + return revenue_all_sales + end + beginning_time, end_time = Utils.get_day_range(date) + # get an array of Sale objects in the given date + sales = FarMar::Sale.between(beginning_time, end_time) + # get an array of Sale objects by this vendor in the given date + sales = sales.select { |sale| sale.vendor_id == @id } + # add up the sale amount and return the sum + return sales.inject(0.0) {|sum, sale| sum + sale.amount} + end + +end diff --git a/lib/finder.rb b/lib/finder.rb new file mode 100644 index 00000000..5df52708 --- /dev/null +++ b/lib/finder.rb @@ -0,0 +1,12 @@ +class Finder # Model: it provides a model to represent the real word(the domin) + def self.find(id) # have seen behaviors in same pattern(methods) => inheritance(has to be a class) + found_object = nil + all.each do |object| + if object.id == id + found_object = object + break + end + end + return found_object + end +end diff --git a/lib/utils.rb b/lib/utils.rb new file mode 100644 index 00000000..4e0287c0 --- /dev/null +++ b/lib/utils.rb @@ -0,0 +1,12 @@ +module Utils # classes with different natures need to share the method => mixin (module or an instance of a class) + def self.get_day_range(date) + # Assume the date will be given a string in "year-month-day" format + # The period of time on the given date + begin_time = Date.parse(date).to_datetime + end_time = Date.parse(date).next.to_datetime + return begin_time, end_time + end +end + +# mixin-include: for instance method +# mixin-extend: for class method diff --git a/specs/market_spec.rb b/specs/market_spec.rb new file mode 100644 index 00000000..6e3dcbdf --- /dev/null +++ b/specs/market_spec.rb @@ -0,0 +1,53 @@ +require_relative 'spec_helper' +require_relative '../lib/far_mar' +# require_relative '../lib/farmar_market'#file name(as same as class name) + +describe FarMar::Market do + + it "loading a market csv file creates an array of market objects" do + expect( FarMar::Market.all.class ).must_equal(Array) + expect( FarMar::Market.all[0].class ).must_equal(FarMar::Market) + end + + it "Input a market id '5' returns the corresponding market object" do + expect(FarMar::Market.find("5").class).must_equal(FarMar::Market) + end + + it "Input a market id '2' returns all the corresponding vendor objects with the same market id" do + market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") + expect( market.vendors.class ).must_equal(Array) + expect( market.vendors[0].class ).must_equal(FarMar::Vendor) + end + + it "There are 3 Product objects associated with market id '2'" do + market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") + expect( market.products("2").size).must_equal(9) + end + + it "There are 3 Market objects that have 'school' in either in its market name or its vendor name" do + expect(FarMar::Market.search("school").size).must_equal(3) + end + + it "Input a market id '2' returns and return the vendor who has highest revenue(prefered vendor) of that market" do + market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") + expect( market.prefered_vendor_direct(FarMar::Vendor.all).class ).must_equal(FarMar::Vendor) + end + + it "Input a date '2013-11-07' returns and return Vendor who has highest revenue(prefered vendor) of that date. The vendor id is: 2590" do + market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") + expect( market.prefered_vendor("2013-11-07").id ).must_equal("2590") + end + + it "Input a market id '2' returns and return the vendor who has lowest revenue(worst vendor) of that market. Vendor id = 1160" do + market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") + expect( market.worst_vendor_direct(FarMar::Vendor.all).id ).must_equal("1160") + end + #=> + + it "Input a date '2013-11-07' returns and return Vendor who has highest revenue(prefered vendor) of that date. The vendor id is: 1470" do + market = FarMar::Market.new("2", "Silverdale Farmers Market", "98383", "Silverdale", "Kitsap", "Washington", "98383") + expect( market.worst_vendor("2013-11-07").id ).must_equal("1470") + end + #=> + +end diff --git a/specs/product_spec.rb b/specs/product_spec.rb new file mode 100644 index 00000000..a35ea380 --- /dev/null +++ b/specs/product_spec.rb @@ -0,0 +1,49 @@ +require_relative 'spec_helper' +require_relative '../lib/far_mar' +# require_relative '../lib/farmar_product'#file name(as same as class name) + +describe FarMar::Product do + + it "loading a product csv file creates an array of product objects" do + expect( FarMar::Product.all.class ).must_equal(Array) + expect( FarMar::Product.all[0].class ).must_equal(FarMar::Product) + end + + it "Input a product id '5' returns the corresponding product object" do + expect(FarMar::Product.find("5").class).must_equal(FarMar::Product) + end + + it "Input a vendor id '1', returns all the corresponding Product objects with the same vendor id" do + expect( FarMar::Product.by_vendor("1").class ).must_equal(Array) + expect( FarMar::Product.by_vendor("1")[0].class ).must_equal(FarMar::Product) + end + + it "Input a product id '1', returns all the corresponding Vendor objects with the same Product's vendor id" do + product = FarMar::Product.new("1","Dry Beets","1") + expect( product.vendor.class ).must_equal(FarMar::Vendor) + end + + it "Input a product id '1' returns all the corresponding Sale objects with the same product id" do + product = FarMar::Product.new("1","Dry Beets","1") + expect( product.sales.class ).must_equal(Array) + expect( product.sales[0].class ).must_equal(FarMar::Sale) + end + + it "There is no corresponding Sale objects with a product id '3'" do + product = FarMar::Product.new("3","Heavy Chicken","2") + expect( product.sales.class ).must_equal(Array) + expect( product.sales[0].class).must_equal(NilClass) + end + + it "The product with id '1' has been sold 7 times" do + product = FarMar::Product.new("1","Dry Beets","1") + expect( product.number_of_sales ).must_equal(7) + end + + it "The top 3 Product object ranked by total revenue has 3 objects" do + expect( FarMar::Product.most_revenue(3).size ).must_equal(3) + end + + + +end diff --git a/specs/sale_spec.rb b/specs/sale_spec.rb new file mode 100644 index 00000000..cdeb4221 --- /dev/null +++ b/specs/sale_spec.rb @@ -0,0 +1,33 @@ +require_relative 'spec_helper' +require_relative '../lib/far_mar' +# require_relative '../lib/farmar_sale'#file name(as same as class name) + +describe FarMar::Sale do + + it "loading a sale csv file creates an array of sale objects" do + expect( FarMar::Sale.all.class ).must_equal(Array) + expect( FarMar::Sale.all[0].class ).must_equal(FarMar::Sale) + end + + it "Input a sale id '5' returns the corresponding sale object" do + expect(FarMar::Sale.find("5").class).must_equal(FarMar::Sale) + end + + it "Input a sale id '1', returns all the corresponding Vendor objects with the same Sale's vendor id" do + sale = FarMar::Sale.new("1",9290,"2013-11-07 04:34:56 -0800","1","1") + expect( sale.vendor.class ).must_equal(FarMar::Vendor) + end + + it "Input a sale id '1', returns all the corresponding Product objects with the same Sale's product id" do + sale = FarMar::Sale.new("1",9290,"2013-11-07 04:34:56 -0800","1","1") + expect( sale.product.class ).must_equal(FarMar::Product) + end + + # Will make tests with more fun and meaning from now on. :D + it "Given a beginning time: 2013-11-03 04:34:56 -0800 and a end time: 2013-11-03 05:14:56 -0900, there are 12798 number of Sale objects with purchase time that fall between the period " do + begin_time = DateTime.parse("2013-11-11 18:43:56 -0800") + end_time = DateTime.parse("2013-11-12 12:00:35 -0800") + expect ( FarMar::Sale.between(begin_time, end_time).size ). must_equal(1294) + end + +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 00000000..56027e1d --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,11 @@ +#Spec_helper.rb +require 'simplecov' +SimpleCov.start + + +require 'minitest' +require 'minitest/spec' +require 'minitest/autorun' +require 'minitest/reporters' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new diff --git a/specs/vendor_spec.rb b/specs/vendor_spec.rb new file mode 100644 index 00000000..33397099 --- /dev/null +++ b/specs/vendor_spec.rb @@ -0,0 +1,67 @@ +require_relative 'spec_helper' +require_relative '../lib/far_mar' +# require_relative '../lib/farmar_vendor'#file name(as same as class name) + + +# create special csv case to test the +describe FarMar::Vendor do + + it "loading a vendor csv file creates an array of Vendor objects" do + expect( FarMar::Vendor.all.class ).must_equal(Array) + expect( FarMar::Vendor.all[0].class ).must_equal(FarMar::Vendor) + end + + it "Input a vendor id '5' returns the corresponding Vendor object" do + expect(FarMar::Vendor.find("5").class).must_equal(FarMar::Vendor) + end + + it "Input a market id '3' returns all the corresponding Market objects with the same market id" do + vendor = FarMar::Vendor.new("3", "Breitenberg Inc", "5", "1") + expect( vendor.market.class ).must_equal(FarMar::Market) + end + + it "Input a vendor id '3' returns all the corresponding Product objects with the same vendor id" do + vendor = FarMar::Vendor.new("3", "Breitenberg Inc", "5", "1") + expect( vendor.products.class ).must_equal(Array) + expect( vendor.products[0].class ).must_equal(FarMar::Product) + end + + it "Input a vendor id '3' returns all the corresponding Sale objects with the same vendor id" do + vendor = FarMar::Vendor.new("3", "Breitenberg Inc", "5", "1") + expect( vendor.sales.class ).must_equal(Array) + expect( vendor.sales[0].class ).must_equal(FarMar::Sale) + end + + it "Revenue of vendor 'Breitenberg Inc' is 40126.0 cents" do + vendor = FarMar::Vendor.new("3", "Breitenberg Inc", "5", "1") + expect( vendor.revenue ).must_equal(40126.0) + end + + it "Input a market id'1', returns all the corresponding Vendor objects with the same market id" do + expect( FarMar::Vendor.by_market("1").class ).must_equal(Array) + expect( FarMar::Vendor.by_market("1")[0].class ).must_equal(FarMar::Vendor) + end + + it "Request top 3 Vendors with highest revenue returns 3 Vendor objects" do + expect( FarMar::Vendor.most_revenue(3).size ).must_equal(3) + end + # should have better test for this one. + + it "Request top 3 Vendors with highest items sold number returns 3 Vendor objects" do + expect( FarMar::Vendor.most_revenue(3).size ).must_equal(3) + end + # should have better test for this one. + + it "The total revenue for '2013-11-07' across all vendors is 8995506.0 cents " do + expect( FarMar::Vendor.revenue("2013-11-07") ).must_equal(8995506.0) + end + #=>8995506.0 + + it "returns the total revenue for that specific purchase date and vendor instance" do + vendor = FarMar::Vendor.new("3", "Breitenberg Inc", "5", "1") + expect( vendor.revenue("2013-11-13") ).must_equal(9128.0) + end + # =>9128.0 + + +end diff --git a/temp_data_attributes_list.rb b/temp_data_attributes_list.rb new file mode 100644 index 00000000..f38c4c6f --- /dev/null +++ b/temp_data_attributes_list.rb @@ -0,0 +1,39 @@ +# Data attributes info for design reference only +# Not for execution + +class Market + market_id + market_name + market_address + city + county + state + zip +end + +class Vendor + vendor_id + vendor_name + employees_num + market_id +end + +class Product + product_id + product_name + vendor_id +end + +class Sale + sale_id + sale_amount + purchase_time + vendor_id + product_id +end + +# summary: +# 1. practice enumerable method +# 2. classic data modeling, each data is a data model(uml diagram) +# 3. think about optimization, especially in sale file(significantly larger) +# (load file/iterate over data the minimum time, store and indexing the data)