Skip to content

Instantly share code, notes, and snippets.

@rochefort
Last active December 15, 2015 14:09
Show Gist options
  • Save rochefort/5272477 to your computer and use it in GitHub Desktop.
Save rochefort/5272477 to your computer and use it in GitHub Desktop.
require 'spec_helper'
require 'idemitsu_importer'
describe Idemitsu::Importer do
describe "サンプルデータのimport" do
before do
@header, @data = Idemitsu::Importer.import('spec/fixtures/IDEMITSU_1303.csv')
end
describe "CSVファイルのheader" do
it "想定したものかつ、UTF-8で格納されていること" do
@header.should == "利用日,ご利用店名及び商品名,本人・家族区分,支払区分名称,締前入金区分,利用金額,備考".split(',')
@data.size.should == 5
end
end
describe "CSVファイルのデータ" do
it "先頭カラム(利用日)が空のデータはスキップされていること" do
@data.size.should == 5
end
it "データがCSVの内容かつ、UTF-8で格納されていること" do
@data[0].should correct_csv_values('2012/12/09', 'ケイキユウ(ストア', 2106)
@data[1].should correct_csv_values('2012/12/19', 'トウキヨウガス', 2929)
@data[2].should correct_csv_values('2012/12/28', 'アツプル アイチユ−ンズ ストア', 1070)
@data[3].should correct_csv_values('2013/01/03', 'PP *FASTSPRING BARTEND', 1355)
@data[4].should correct_csv_values('2013/01/03', 'AMAZON.CO.JP', 794)
end
end
end
end
#! /usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'csv'
module Idemitsu
module Importer
def self.import(file)
csv = CSV.read(file, :encoding => 'Windows-31J:UTF-8')
header, data = separate_header_and_data(csv)
end
private
def self.separate_header_and_data(csv)
idx = header_index(csv)
header = csv[idx]
# 日付(0番目)が無い場合(通過レートの表示)は無視し、structにセットしなおす
statement = create_struct
data = csv[idx+1..-1].select{ |d| d[0] }.map do |d|
statement.new(d[0], self.cp932_to_sjis(d[1]), d[5].to_i)
end
[header, data]
end
# 同一のStuctをnewすると warning: redefining constant Struct::Statement となるため
# インスタンス変数にセットして処理
def self.create_struct
@struct ||= Struct.new('Statement', :date, :name, :price)
end
def self.header_index(csv)
# 頭に利用日が設定されている行番号を取得
idx = 0;
csv.each_with_index do |line, i|
next unless line[0]
if line[0].encode('utf-8') =~ /^利用日/
idx = i
break
end
end
idx
end
# see also:
# http://d.hatena.ne.jp/miau/20110919/1316427760
# http://d.hatena.ne.jp/nurse/20080217
#
# cp932 sjis sjis_name
# FF5E 301C 〜FULLWIDTH TILDE
# 2225 2016 ‖ PARALLEL TO
# FF0D 2212 − FULLWIDTH HYPHEN-MINUS
# FFE0 00A2 ¢ FULLWIDTH CENT SIGN
# FFE1 00A3 £ FULLWIDTH POUND SIGN
# FFE2 00AC ¬ FULLWIDTH NOT SIGN
# 2015 2014 — HORIZONTAL BAR
# FFE4 00A6 ¦ FULLWIDTH BROKEN BAR
SJIS_MAPPINGS = "\u{301C 2016 2212 00A2 00A3 00AC 2014 00A6}"
CP932_MAPPINGS = "\u{FF5E 2225 FF0D FFE0 FFE1 FFE2 2015 FFE4}"
def self.cp932_to_sjis(str)
str.tr(CP932_MAPPINGS, SJIS_MAPPINGS)
end
end
end
if $0 == __FILE__
header, data = Idemitsu::Importer.import('IDEMITSU_1303.csv')
data.each{ |x| puts x }
end
RSpec::Matchers.define :correct_csv_values do |expected_date, expected_name, expected_price|
match do |actual|
actual.date == expected_date &&
actual.name == expected_name &&
actual.price == expected_price
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment