sie 4.0.0 → 4.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12f2a07994c6646b39d43549d25640af5593d05e8ebe93145bbee75d64adc9e5
4
- data.tar.gz: 5401be347bc8c5886678eaa63d027fad9da681d70ea477ba613dd85816d00258
3
+ metadata.gz: 03fce1590113082c1f1dd3f7e678a1b0524d5fc6983515db89814d391fb316fe
4
+ data.tar.gz: 5eae064606c80b137a3b5cd5d6a571de20b1a6e2074d9e51975b752ffaba76dd
5
5
  SHA512:
6
- metadata.gz: 3f913dfe20748fc6dbba3d0486362d43e6c12251e5d6980b906b376295d71f2e34c5e1af19649a43770b55c86f7d890c0755cc3de362ffb889b628ee2bfc00cd
7
- data.tar.gz: d60adfe6ce535b77cf77ccfc923121539e4162743c03a28e9ce877577ce9ebc42de058c0e0d2daa8af0cb12a57ea3843055ffeef808fab636aa41a9348337362
6
+ metadata.gz: 444307d156642b1fef67949d4a5632675f6fe9d65ce46b5d383c893333642a71c6eb1d44522ac69dddcbcdf975fb195acefa27c596a803a456cc55682fc096b0
7
+ data.tar.gz: 55abf86ae21e562f19da367fdf265d3107c0446b4744a0f3e0dbe1e73bad4276b8a8bf23f6ec63c1cb8aa8789ac6e4c39c5d50d188d9ec0ae2fc2ba555147154
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Sie
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/barsoom/sie.png)](http://travis-ci.org/barsoom/sie)
4
- [![Code Climate](https://codeclimate.com/github/barsoom/sie.png)](https://codeclimate.com/github/barsoom/sie)
3
+ [![Build status](https://github.com/barsoom/sie/actions/workflows/ci.yml/badge.svg)](https://github.com/barsoom/sie/actions/workflows/ci.yml)
4
+ [![Code Climate](https://codeclimate.com/github/barsoom/sie.svg)](https://codeclimate.com/github/barsoom/sie)
5
5
 
6
+ SIE parser and generator supporting the [format "SIE typ 1-4 – Klassisk SIE"](https://sie.se/format/).
6
7
 
7
8
  ## Installation
8
9
 
@@ -161,7 +162,7 @@ Getting the latest code and gems:
161
162
 
162
163
  ## Resources
163
164
 
164
- [SIE format specification rev 4B (swedish)](http://www.sie.se/wp-content/uploads/2014/01/SIE_filformat_ver_4B_080930.pdf)
165
+ [SIE format specification rev 4B (Swedish)](https://sie.se/wp-content/uploads/2020/05/SIE_filformat_ver_4B_080930.pdf)
165
166
 
166
167
  ## See also
167
168
 
@@ -9,7 +9,7 @@ class Sie::Document::Renderer
9
9
  end
10
10
 
11
11
  def add_line(label, *values)
12
- append ["##{ label }", *format_values(values)].join(" ")
12
+ append [ "##{label}", *format_values(values) ].join(" ")
13
13
  end
14
14
 
15
15
  def add_array
@@ -36,7 +36,7 @@ class Sie::Document::Renderer
36
36
  end
37
37
 
38
38
  def encoded(text)
39
- text.encode(ENCODING, :invalid => :replace, :undef => :replace, :replace => "?")
39
+ text.encode(ENCODING, invalid: :replace, undef: :replace, replace: "?")
40
40
  end
41
41
 
42
42
  def format_value(value)
data/lib/sie/document.rb CHANGED
@@ -10,7 +10,7 @@ module Sie
10
10
  # - Visma etc -> 100
11
11
  DESCRIPTION_LENGTH_MAX = 100
12
12
 
13
- pattr_initialize :data_source
13
+ pattr_initialize :data_source, [ exclude_balance_rows: false ]
14
14
 
15
15
  def render
16
16
  add_header
@@ -25,6 +25,9 @@ module Sie
25
25
 
26
26
  private
27
27
 
28
+ delegate :add_line, :add_array,
29
+ to: :renderer
30
+
28
31
  delegate :program, :program_version, :generated_on, :company_name,
29
32
  :accounts, :balance_account_numbers, :closing_account_numbers,
30
33
  :balance_before, :each_voucher, :dimensions,
@@ -55,6 +58,8 @@ module Sie
55
58
  end
56
59
 
57
60
  def add_balances
61
+ return if exclude_balance_rows
62
+
58
63
  financial_years.each_with_index do |date_range, index|
59
64
  add_balance_rows("IB", -index, balance_account_numbers, date_range.begin)
60
65
  add_balance_rows("UB", -index, balance_account_numbers, date_range.end)
@@ -129,8 +134,6 @@ module Sie
129
134
  end
130
135
  end
131
136
 
132
- delegate :add_line, :add_array, to: :renderer
133
-
134
137
  def renderer
135
138
  @renderer ||= Renderer.new
136
139
  end
@@ -27,9 +27,9 @@ module Sie
27
27
  entry.attributes[label] = attr_tokens.first
28
28
  else
29
29
  type = attr.fetch(:type)
30
- values = attr_tokens.
31
- each_slice(type.size).
32
- map { |slice| Hash[type.zip(slice)] }
30
+ values = attr_tokens
31
+ .each_slice(type.size)
32
+ .map { |slice| Hash[type.zip(slice)] }
33
33
 
34
34
  entry.attributes[label] = values
35
35
  end
@@ -53,6 +53,7 @@ module Sie
53
53
  hash_tokens = []
54
54
  while token = tokens.shift
55
55
  break if token.is_a?(Tokenizer::EndArrayToken)
56
+
56
57
  hash_tokens << token.value
57
58
  end
58
59
 
@@ -1,41 +1,41 @@
1
1
  module Sie
2
2
  class Parser
3
3
  ENTRY_TYPES = {
4
- "adress" => [ 'kontakt', 'utdelningsadr', 'postadr', 'tel' ],
5
- "bkod" => [ 'SNI-kod' ],
6
- "dim" => [ 'dimensionsnr', 'namn' ],
7
- "enhet" => [ 'kontonr', 'enhet' ],
8
- "flagga" => [ 'x' ],
9
- "fnamn" => [ 'foretagsnamn' ],
10
- "fnr" => [ 'foretagsid' ],
11
- "format" => [ 'PC8' ],
12
- "ftyp" => [ 'foretagstyp' ],
13
- "gen" => [ 'datum', 'sign' ],
14
- "ib" => [ 'arsnr', 'konto', 'saldo', 'kvantitet' ],
15
- "konto" => [ 'kontonr', 'kontonamn' ],
16
- "kptyp" => [ 'typ' ],
17
- "ktyp" => [ 'kontonr', 'kontotyp' ],
18
- "objekt" => [ 'dimensionsnr', 'objektnr', 'objektnamn' ],
19
- "oib" => [ 'arsnr', 'konto', { name: 'objekt', type: [ 'dimensionsnr', 'objektnr' ] }, 'saldo', 'kvantitet' ],
20
- "omfattn" => [ 'datum' ],
21
- "orgnr" => [ 'orgnr', 'forvnr', 'verknr' ],
22
- "oub" => [ 'arsnr', 'konto', { name: 'objekt', type: [ 'dimensionsnr', 'objektnr' ] }, 'saldo', 'kvantitet' ],
23
- "pbudget" => [ 'arsnr', 'period', 'konto', { name: 'objekt', type: [ 'dimensionsnr', 'objektnr' ] }, 'saldo', 'kvantitet' ],
24
- "program" => [ 'programnamn', 'version' ],
25
- "prosa" => [ 'text' ],
26
- "psaldo" => [ 'arsnr', 'period', 'konto', { name: 'objekt', type: [ 'dimensionsnr', 'objektnr' ] }, 'saldo', 'kvantitet' ],
27
- "rar" => [ 'arsnr', 'start', 'slut' ],
28
- "res" => [ 'ars', 'konto', 'saldo', 'kvantitet' ],
29
- "sietyp" => [ 'typnr' ],
30
- "sru" => [ 'konto', 'SRU-kod' ],
31
- "taxar" => [ 'ar' ],
32
- "trans" => [ 'kontonr', { name: 'objektlista', type: [ 'dimensionsnr', 'objektnr' ], many: true }, 'belopp', 'transdat', 'transtext', 'kvantitet', 'sign' ],
33
- "rtrans" => [ 'kontonr', { name: 'objektlista', type: [ 'dimensionsnr', 'objektnr' ], many: true }, 'belopp', 'transdat', 'transtext', 'kvantitet', 'sign' ],
34
- "btrans" => [ 'kontonr', { name: 'objektlista', type: [ 'dimensionsnr', 'objektnr' ], many: true }, 'belopp', 'transdat', 'transtext', 'kvantitet', 'sign' ],
35
- "ub" => [ 'arsnr', 'konto', 'saldo', 'kvantitet' ],
36
- "underdim" => [ 'dimensionsnr', 'namn', 'superdimension' ],
37
- "valuta" => [ 'valutakod' ],
38
- "ver" => [ 'serie', 'vernr', 'verdatum', 'vertext', 'regdatum', 'sign' ]
4
+ "adress" => [ "kontakt", "utdelningsadr", "postadr", "tel" ],
5
+ "bkod" => [ "SNI-kod" ],
6
+ "dim" => [ "dimensionsnr", "namn" ],
7
+ "enhet" => [ "kontonr", "enhet" ],
8
+ "flagga" => [ "x" ],
9
+ "fnamn" => [ "foretagsnamn" ],
10
+ "fnr" => [ "foretagsid" ],
11
+ "format" => [ "PC8" ],
12
+ "ftyp" => [ "foretagstyp" ],
13
+ "gen" => [ "datum", "sign" ],
14
+ "ib" => [ "arsnr", "konto", "saldo", "kvantitet" ],
15
+ "konto" => [ "kontonr", "kontonamn" ],
16
+ "kptyp" => [ "typ" ],
17
+ "ktyp" => [ "kontonr", "kontotyp" ],
18
+ "objekt" => [ "dimensionsnr", "objektnr", "objektnamn" ],
19
+ "oib" => [ "arsnr", "konto", { name: "objekt", type: [ "dimensionsnr", "objektnr" ] }, "saldo", "kvantitet" ],
20
+ "omfattn" => [ "datum" ],
21
+ "orgnr" => [ "orgnr", "forvnr", "verknr" ],
22
+ "oub" => [ "arsnr", "konto", { name: "objekt", type: [ "dimensionsnr", "objektnr" ] }, "saldo", "kvantitet" ],
23
+ "pbudget" => [ "arsnr", "period", "konto", { name: "objekt", type: [ "dimensionsnr", "objektnr" ] }, "saldo", "kvantitet" ],
24
+ "program" => [ "programnamn", "version" ],
25
+ "prosa" => [ "text" ],
26
+ "psaldo" => [ "arsnr", "period", "konto", { name: "objekt", type: [ "dimensionsnr", "objektnr" ] }, "saldo", "kvantitet" ],
27
+ "rar" => [ "arsnr", "start", "slut" ],
28
+ "res" => [ "ars", "konto", "saldo", "kvantitet" ],
29
+ "sietyp" => [ "typnr" ],
30
+ "sru" => [ "konto", "SRU-kod" ],
31
+ "taxar" => [ "ar" ],
32
+ "trans" => [ "kontonr", { name: "objektlista", type: [ "dimensionsnr", "objektnr" ], many: true }, "belopp", "transdat", "transtext", "kvantitet", "sign" ],
33
+ "rtrans" => [ "kontonr", { name: "objektlista", type: [ "dimensionsnr", "objektnr" ], many: true }, "belopp", "transdat", "transtext", "kvantitet", "sign" ],
34
+ "btrans" => [ "kontonr", { name: "objektlista", type: [ "dimensionsnr", "objektnr" ], many: true }, "belopp", "transdat", "transtext", "kvantitet", "sign" ],
35
+ "ub" => [ "arsnr", "konto", "saldo", "kvantitet" ],
36
+ "underdim" => [ "dimensionsnr", "namn", "superdimension" ],
37
+ "valuta" => [ "valutakod" ],
38
+ "ver" => [ "serie", "vernr", "verdatum", "vertext", "regdatum", "sign" ],
39
39
  }
40
40
  end
41
41
  end
@@ -19,7 +19,7 @@ module Sie
19
19
  end
20
20
 
21
21
  def label
22
- value.sub(/^#/, '').downcase
22
+ value.sub(/^#/, "").downcase
23
23
  end
24
24
  end
25
25
 
@@ -88,7 +88,7 @@ module Sie
88
88
  end
89
89
 
90
90
  def find_unquoted_string
91
- scanner.scan(/\S+/)
91
+ scanner.scan(/[^}\s]+/)
92
92
  end
93
93
 
94
94
  def remove_unnecessary_escapes(match)
data/lib/sie/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Sie
2
2
  # For versioning see: http://semver.org/
3
- VERSION = "4.0.0"
3
+ VERSION = "4.1.2"
4
4
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sie
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Barsoom AB
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-17 00:00:00.000000000 Z
11
+ date: 2022-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: attr_extras
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: activesupport
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -39,41 +25,13 @@ dependencies:
39
25
  - !ruby/object:Gem::Version
40
26
  version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.3'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '1.3'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
28
+ name: attr_extras
71
29
  requirement: !ruby/object:Gem::Requirement
72
30
  requirements:
73
31
  - - ">="
74
32
  - !ruby/object:Gem::Version
75
33
  version: '0'
76
- type: :development
34
+ type: :runtime
77
35
  prerelease: false
78
36
  version_requirements: !ruby/object:Gem::Requirement
79
37
  requirements:
@@ -87,13 +45,7 @@ executables: []
87
45
  extensions: []
88
46
  extra_rdoc_files: []
89
47
  files:
90
- - ".gitignore"
91
- - ".rspec"
92
- - ".travis.yml"
93
- - Gemfile
94
- - Gemfile.pre_2.2.2
95
48
  - README.md
96
- - Rakefile
97
49
  - lib/sie.rb
98
50
  - lib/sie/document.rb
99
51
  - lib/sie/document/renderer.rb
@@ -107,26 +59,11 @@ files:
107
59
  - lib/sie/parser/tokenizer.rb
108
60
  - lib/sie/parser/tokenizer/token.rb
109
61
  - lib/sie/version.rb
110
- - script/bootstrap
111
- - script/refresh
112
- - script/test
113
- - script/turbux_rspec
114
- - sie.gemspec
115
- - spec/fixtures/sie_file.se
116
- - spec/fixtures/sie_file_with_unknown_entries.se
117
- - spec/integration/parser_spec.rb
118
- - spec/spec_helper.rb
119
- - spec/unit/build_entry_spec.rb
120
- - spec/unit/document/renderer_spec.rb
121
- - spec/unit/document/voucher_series_spec.rb
122
- - spec/unit/document_spec.rb
123
- - spec/unit/parser/line_parser_spec.rb
124
- - spec/unit/parser/tokenizer_spec.rb
125
- - spec/unit/parser_spec.rb
126
62
  homepage: ''
127
63
  licenses:
128
64
  - MIT
129
- metadata: {}
65
+ metadata:
66
+ rubygems_mfa_required: 'true'
130
67
  post_install_message:
131
68
  rdoc_options: []
132
69
  require_paths:
@@ -142,19 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
79
  - !ruby/object:Gem::Version
143
80
  version: '0'
144
81
  requirements: []
145
- rubygems_version: 3.0.3
82
+ rubygems_version: 3.3.11
146
83
  signing_key:
147
84
  specification_version: 4
148
- summary: Parses and generates SIE files (http://sie.se/)
149
- test_files:
150
- - spec/fixtures/sie_file.se
151
- - spec/fixtures/sie_file_with_unknown_entries.se
152
- - spec/integration/parser_spec.rb
153
- - spec/spec_helper.rb
154
- - spec/unit/build_entry_spec.rb
155
- - spec/unit/document/renderer_spec.rb
156
- - spec/unit/document/voucher_series_spec.rb
157
- - spec/unit/document_spec.rb
158
- - spec/unit/parser/line_parser_spec.rb
159
- - spec/unit/parser/tokenizer_spec.rb
160
- - spec/unit/parser_spec.rb
85
+ summary: Parses and generates SIE files (https://sie.se/)
86
+ test_files: []
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- .idea
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --format progress
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.6
4
- - 2.5
5
- - 2.4
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in sie.gemspec
4
- gemspec
data/Gemfile.pre_2.2.2 DELETED
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in sie.gemspec
4
- gemspec
5
-
6
- # Ruby <2.2.2 can't use Active Support 5.
7
- # https://apotonick.wordpress.com/2012/08/14/different-gemfiles-for-ruby-1-8-and-1-9-on-travis-ci/
8
- gem "activesupport", "< 5"
data/Rakefile DELETED
@@ -1,15 +0,0 @@
1
- require "bundler/gem_tasks"
2
-
3
- namespace :spec do
4
- task :unit do
5
- puts "Running unit tests:"
6
- system("rspec spec/unit/**_spec.rb") || exit(1)
7
- end
8
-
9
- task :integration do
10
- puts "Running integrated tests:"
11
- system("rspec spec/integration/**_spec.rb") || exit(1)
12
- end
13
- end
14
-
15
- task :default => [ :"spec:unit", :"spec:integration" ]
data/script/bootstrap DELETED
@@ -1,3 +0,0 @@
1
- gem install bundler --no-ri --no-rdoc &&
2
- bundle &&
3
- rake
data/script/refresh DELETED
@@ -1,25 +0,0 @@
1
- #!/bin/bash
2
-
3
- printf "\e[00;34mGetting the latest version\e[00m... "
4
-
5
- (git status|grep 'nothing to commit' 1> /dev/null)
6
-
7
- if [ ! $? -eq 0 ]
8
- then
9
- set -e
10
- git stash 1> /dev/null
11
- git pull --rebase 1> /dev/null
12
- git stash pop 1> /dev/null
13
- else
14
- set -e
15
- git pull --rebase 1> /dev/null
16
- fi
17
-
18
- echo "done"
19
-
20
- printf "\e[00;34mBundling\e[00m... "
21
- bundle 1> /dev/null
22
- echo "done"
23
- echo
24
-
25
- rake
data/script/test DELETED
@@ -1 +0,0 @@
1
- script/turbux_rspec
data/script/turbux_rspec DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Command to run the specs the correct way when triggered from the turbux vim plugin.
4
-
5
- command = "rspec #{ARGV.first}"
6
- exit(1) unless system(command)
data/sie.gemspec DELETED
@@ -1,27 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'sie/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "sie"
8
- spec.version = Sie::VERSION
9
- spec.authors = ["Barsoom AB"]
10
- spec.email = ["all@barsoom.se"]
11
- spec.description = %q{SIE parser and generator}
12
- spec.summary = %q{Parses and generates SIE files (http://sie.se/)}
13
- spec.homepage = ""
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_dependency "attr_extras"
22
- spec.add_dependency "activesupport"
23
-
24
- spec.add_development_dependency "bundler", "~> 1.3"
25
- spec.add_development_dependency "rake"
26
- spec.add_development_dependency "rspec"
27
- end
@@ -1,28 +0,0 @@
1
- #FLAGGA 0
2
- #PROGRAM "fooconomic" "1.0"
3
- #FORMAT PC8
4
- #GEN 20130101
5
- #SIETYP 4
6
- #ORGNR 555555-5555
7
- #FNAMN "Foocorp"
8
- #ADRESS "Foocorp" "" "12345 City" "555-12345"
9
- #KONTO 1510 "Accounts receivable"
10
- #KTYP 1510 T
11
- #SRU 1510 204
12
- #KONTO 1930 "Bank account"
13
- #KTYP 1930 T
14
- #SRU 1930 200
15
- #KONTO 2440 Supplier
16
- #KTYP 2440 S
17
- #SRU 2440 300
18
- #VER A 1 20130101 "Invoice" 20120105
19
- {
20
- #TRANS 1510 {} -200 20130101 "Coffee machine"
21
- #TRANS 4100 {} 180 20130101 "Coffee machine"
22
- #TRANS 2611 {} -20 20130101 "VAT"
23
- }
24
- #VER A 2 20130102 "Payment" 20120105
25
- {
26
- #TRANS 1510 {} -200 20130101 "Payment: Coffee machine"
27
- #TRANS 1970 {} 200 20130101 "Payment: Coffee machine"
28
- }
@@ -1,32 +0,0 @@
1
- #FLAGGA 0
2
- #PROGRAM "fooconomic" "1.0"
3
- #FORMAT PC8
4
- #GEN 20130101
5
- #SIETYP 4
6
- #ORGNR 555555-5555
7
- #FNAMN "Foocorp"
8
- #ADRESS "Foocorp" "" "12345 City" "555-12345"
9
- #KONTO 1510 "Accounts receivable"
10
- #KTYP 1510 T
11
- #SRU 1510 204
12
- #KONTO 1930 "Bank account"
13
- #KTYP 1930 T
14
- #SRU 1930 200
15
- #KONTO 2440 Supplier
16
- #KTYP 2440 S
17
- #SRU 2440 300
18
- #KONTO 2610 "Utgaende moms, oreducerad "
19
- #KTYP 2610 S
20
- #SRU 2610 7369
21
- #MOMSKOD 2610 10
22
- #VER A 1 20130101 "Invoice" 20120105
23
- {
24
- #TRANS 1510 {} -200 20130101 "Coffee machine"
25
- #TRANS 4100 {} 180 20130101 "Coffee machine"
26
- #TRANS 2611 {} -20 20130101 "VAT"
27
- }
28
- #VER A 2 20130102 "Payment" 20120105
29
- {
30
- #TRANS 1510 {} -200 20130101 "Payment: Coffee machine"
31
- #TRANS 1970 {} 200 20130101 "Payment: Coffee machine"
32
- }
@@ -1,56 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Sie::Parser do
6
- it "parses a file" do
7
- parser = Sie::Parser.new
8
-
9
- open_file("fixtures/sie_file.se") do |f|
10
- sie_file = parser.parse(f)
11
-
12
- expect(sie_file.entries_with_label("fnamn").first.attributes["foretagsnamn"]).to eq("Foocorp")
13
-
14
- account = sie_file.entries_with_label("konto").first
15
- expect(account.attributes["kontonr"]).to eq("1510")
16
- expect(account.attributes["kontonamn"]).to eq("Accounts receivable")
17
- expect(sie_file.entries_with_label("ver").size).to eq(2)
18
- end
19
- end
20
-
21
- context "with unknown entries" do
22
- let(:file_with_unknown_entries) { "fixtures/sie_file_with_unknown_entries.se" }
23
-
24
- context "using a lenient parser" do
25
- let(:parser) { Sie::Parser.new(lenient: true) }
26
-
27
- it "handles unknown entries without raising error" do
28
- open_file(file_with_unknown_entries) do |f|
29
- expect { parser.parse(f) }.not_to raise_error
30
- end
31
- end
32
-
33
- it "continues to parse the complete file after unknown entries" do
34
- open_file(file_with_unknown_entries) do |f|
35
- sie_file = parser.parse(f)
36
-
37
- expect(sie_file.entries_with_label("ver").size).to eq(2)
38
- end
39
- end
40
- end
41
-
42
- context "with strict parser" do
43
- let(:parser) { Sie::Parser.new }
44
-
45
- it "raises error when encountering unknown entries" do
46
- open_file(file_with_unknown_entries) do |f|
47
- expect { parser.parse(f) }.to raise_error(/Unknown entry type: momskod.+Pass 'lenient: true'/)
48
- end
49
- end
50
- end
51
- end
52
-
53
- def open_file(fixture_file, &block)
54
- File.open(File.join(File.dirname(__FILE__), "../#{fixture_file}"), &block)
55
- end
56
- end
data/spec/spec_helper.rb DELETED
@@ -1,5 +0,0 @@
1
- require "sie"
2
-
3
- RSpec.configure do |config|
4
- config.order = 'random'
5
- end
@@ -1,17 +0,0 @@
1
- require "spec_helper"
2
- require "sie/parser/build_entry"
3
- require "sie/parser/tokenizer"
4
-
5
- describe Sie::Parser::BuildEntry, ".call" do
6
- context "with an unexpected token at start of array" do
7
- it "raises InvalidEntryError" do
8
- line = '#TRANS 2400 [] -200 20130101 "Foocorp expense"'
9
- tokens = Sie::Parser::Tokenizer.new(line).tokenize
10
- first_token = tokens.shift
11
-
12
- expect {
13
- Sie::Parser::BuildEntry.call(line, first_token, tokens, false)
14
- }.to raise_error(Sie::Parser::BuildEntry::InvalidEntryError)
15
- end
16
- end
17
- end
@@ -1,13 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Sie::Document::Renderer, "#add_line" do
6
- it "replaces input of the wrong encoding with '?'" do
7
- renderer = Sie::Document::Renderer.new
8
- renderer.add_line "Hello ☃", 1
9
- output = renderer.render
10
-
11
- expect(output).to eq "#Hello ? 1\n"
12
- end
13
- end
@@ -1,41 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Sie::Document::VoucherSeries, ".for" do
4
- subject(:series) { Sie::Document::VoucherSeries.for(creditor, type) }
5
-
6
- let(:type) { :invoice }
7
-
8
- context "when on the creditor side" do
9
- let(:creditor) { true }
10
-
11
- context "with an invoice" do
12
- let(:type) { :invoice }
13
- it { should == "LF" }
14
- end
15
-
16
- context "with a payment" do
17
- let(:type) { :payment }
18
- it { should == "KB" }
19
- end
20
- end
21
-
22
- context "when on the debtor side" do
23
- let(:creditor) { false }
24
-
25
- context "with an invoice" do
26
- let(:type) { :invoice }
27
- it { should == "KF" }
28
- end
29
-
30
- context "with a payment" do
31
- let(:type) { :payment }
32
- it { should == "KI" }
33
- end
34
- end
35
-
36
- context "when neither a payment or invoice" do
37
- let(:creditor) { false }
38
- let(:type) { :manual_bookable }
39
- it { should == "LV" }
40
- end
41
- end
@@ -1,294 +0,0 @@
1
- # encoding: utf-8
2
- require "spec_helper"
3
- require "sie"
4
- require "active_support/core_ext/date/calculations"
5
-
6
- describe Sie::Document, "#render" do
7
- let(:financial_years) {
8
- [
9
- Date.new(2011, 1, 1)..Date.new(2011, 12, 31),
10
- Date.new(2012, 1, 1)..Date.new(2012, 12, 31),
11
- Date.new(2013, 1, 1)..Date.new(2013, 12, 31),
12
- ]
13
- }
14
- let(:generated_on) { Date.yesterday }
15
- let(:accounts) {
16
- [
17
- number: 1500, description: "Customer ledger",
18
- ]
19
- }
20
- let(:vouchers) {
21
- [
22
- {
23
- creditor: false, type: :invoice, number: 1, booked_on: Date.new(2011, 9, 3), description: "Invoice 1",
24
- voucher_lines: [
25
- {
26
- account_number: 1500, amount: 512.0, booked_on: Date.new(2011, 9, 3), description: "Item 1",
27
- dimensions: { 6 => 1 }
28
- },
29
- {
30
- account_number: 3100, amount: -512.0, booked_on: Date.new(2011, 9, 3), description: "Item 1",
31
- dimensions: { 6 => 1 }
32
- },
33
- ]
34
- },
35
- {
36
- creditor: true, type: :payment, number: 2, booked_on: Date.new(2012, 8, 31), description: "Payout 1",
37
- voucher_lines: [
38
- {
39
- account_number: 2400, amount: 256.0, booked_on: Date.new(2012, 8, 31), description: "Payout line 1"
40
- },
41
- {
42
- account_number: 1970, amount: -256.0, booked_on: Date.new(2012, 8, 31), description: "Payout line 2"
43
- },
44
- ]
45
- }
46
- ]
47
- }
48
- let(:dimensions) {
49
- [
50
- {
51
- number: 6, description: "Project",
52
- objects: [
53
- { number: 1, description: "Education" }
54
- ]
55
- }
56
- ]
57
- }
58
-
59
- class TestDataSource
60
- attr_accessor :program, :program_version, :generated_on, :company_name,
61
- :accounts, :balance_account_numbers, :closing_account_numbers,
62
- :vouchers, :financial_years, :dimensions
63
-
64
- # vouchers is not part of the expected interface so making it private.
65
- #
66
- # Sie::Document uses #each_voucher so that you can build documents for huge sets of vouchers
67
- # by loading them in batches.
68
- private :vouchers
69
-
70
- def initialize(hash)
71
- hash.each do |k, v|
72
- public_send("#{k}=", v)
73
- end
74
- end
75
-
76
- def each_voucher(&block)
77
- vouchers.each(&block)
78
- end
79
-
80
- def balance_before(account_number, date)
81
- if account_number == 9999
82
- # So we can test empty balances.
83
- nil
84
- else
85
- # Faking a fetch based on date and number.
86
- account_number.to_i + (date.mday * 100).to_f
87
- end
88
- end
89
- end
90
-
91
- let(:doc) {
92
- data_source = TestDataSource.new(
93
- accounts: accounts,
94
- vouchers: vouchers,
95
- program: "Foonomic",
96
- program_version: "3.11",
97
- generated_on: generated_on,
98
- company_name: "Foocorp",
99
- financial_years: financial_years,
100
- balance_account_numbers: [ 1500, 2400, 9999 ],
101
- closing_account_numbers: [ 3100, 9999 ],
102
- dimensions: dimensions
103
- )
104
- Sie::Document.new(data_source)
105
- }
106
-
107
- let(:sie_file) { Sie::Parser.new.parse(doc.render) }
108
-
109
- it "adds a header" do
110
- expect(entry_attribute("flagga", "x")).to eq("0")
111
- expect(entry_attribute("program", "programnamn")).to eq("Foonomic")
112
- expect(entry_attribute("program", "version")).to eq("3.11")
113
- expect(entry_attribute("format", "PC8")).to eq("PC8")
114
- expect(entry_attribute("gen", "datum")).to eq(generated_on.strftime("%Y%m%d"))
115
- expect(entry_attribute("sietyp", "typnr")).to eq("4")
116
- expect(entry_attribute("fnamn", "foretagsnamn")).to eq("Foocorp")
117
- end
118
-
119
- it "has accounting years" do
120
- expect(indexed_entry_attribute("rar", 0, "arsnr")).to eq("0")
121
- expect(indexed_entry_attribute("rar", 0, "start")).to eq("20130101")
122
- expect(indexed_entry_attribute("rar", 0, "slut")).to eq("20131231")
123
- expect(indexed_entry_attribute("rar", 1, "arsnr")).to eq("-1")
124
- expect(indexed_entry_attribute("rar", 1, "start")).to eq("20120101")
125
- expect(indexed_entry_attribute("rar", 1, "slut")).to eq("20121231")
126
- expect(indexed_entry_attribute("rar", 2, "arsnr")).to eq("-2")
127
- expect(indexed_entry_attribute("rar", 2, "start")).to eq("20110101")
128
- expect(indexed_entry_attribute("rar", 2, "slut")).to eq("20111231")
129
- end
130
-
131
- it "has accounts" do
132
- expect(indexed_entry_attributes("konto", 0)).to eq("kontonr" => "1500", "kontonamn" => "Customer ledger")
133
- end
134
-
135
- it "has dimensions" do
136
- expect(indexed_entry_attributes("dim", 0)).to eq("dimensionsnr" => "6", "namn" => "Project")
137
- end
138
-
139
- it "has objects" do
140
- expect(indexed_entry_attributes("objekt", 0)).to eq("dimensionsnr" => "6", "objektnr" => "1", "objektnamn" => "Education")
141
- end
142
-
143
- it "has balances brought forward (ingående balans)" do
144
- expect(indexed_entry_attributes("ib", 0)).not_to eq("arsnr" => "0", "konto" => "9999", "saldo" => "")
145
- expect(indexed_entry_attributes("ib", 0)).to eq("arsnr" => "0", "konto" => "1500", "saldo" => "1600.0")
146
- expect(indexed_entry_attributes("ib", 1)).to eq("arsnr" => "0", "konto" => "2400", "saldo" => "2500.0")
147
- expect(indexed_entry_attributes("ib", 2)).to eq("arsnr" => "-1", "konto" => "1500", "saldo" => "1600.0")
148
- expect(indexed_entry_attributes("ib", 3)).to eq("arsnr" => "-1", "konto" => "2400", "saldo" => "2500.0")
149
- expect(indexed_entry_attributes("ib", 4)).to eq("arsnr" => "-2", "konto" => "1500", "saldo" => "1600.0")
150
- expect(indexed_entry_attributes("ib", 5)).to eq("arsnr" => "-2", "konto" => "2400", "saldo" => "2500.0")
151
- end
152
-
153
- it "has balances carried forward (utgående balans)" do
154
- expect(indexed_entry_attributes("ub", 0)).not_to eq("arsnr" => "0", "konto" => "9999", "saldo" => "")
155
- expect(indexed_entry_attributes("ub", 0)).to eq("arsnr" => "0", "konto" => "1500", "saldo" => "4600.0")
156
- expect(indexed_entry_attributes("ub", 1)).to eq("arsnr" => "0", "konto" => "2400", "saldo" => "5500.0")
157
- expect(indexed_entry_attributes("ub", 2)).to eq("arsnr" => "-1", "konto" => "1500", "saldo" => "4600.0")
158
- expect(indexed_entry_attributes("ub", 3)).to eq("arsnr" => "-1", "konto" => "2400", "saldo" => "5500.0")
159
- expect(indexed_entry_attributes("ub", 4)).to eq("arsnr" => "-2", "konto" => "1500", "saldo" => "4600.0")
160
- expect(indexed_entry_attributes("ub", 5)).to eq("arsnr" => "-2", "konto" => "2400", "saldo" => "5500.0")
161
- end
162
-
163
- it "has closing account balances (saldo för resultatkonto)" do
164
- expect(indexed_entry_attributes("res", 0)).not_to eq("ars" => "0", "konto" => "9999", "saldo" => "")
165
- expect(indexed_entry_attributes("res", 0)).to eq("ars" => "0", "konto" => "3100", "saldo" => "6200.0")
166
- expect(indexed_entry_attributes("res", 1)).to eq("ars" => "-1", "konto" => "3100", "saldo" => "6200.0")
167
- expect(indexed_entry_attributes("res", 2)).to eq("ars" => "-2", "konto" => "3100", "saldo" => "6200.0")
168
- end
169
-
170
- it "has vouchers" do
171
- expect(indexed_entry("ver", 0).attributes).to eq(
172
- "serie" => "KF", "vernr" => "1",
173
- "verdatum" => "20110903", "vertext" => "Invoice 1"
174
- )
175
- expect(indexed_voucher_entries(0)[0].attributes).to eq(
176
- "kontonr" => "1500", "belopp" => "512.0",
177
- "transdat" => "20110903", "transtext" => "Item 1",
178
- "objektlista" => [{"dimensionsnr" => "6", "objektnr" => "1"}]
179
- )
180
- expect(indexed_voucher_entries(0)[1].attributes).to eq(
181
- "kontonr" => "3100", "belopp" => "-512.0",
182
- "transdat" => "20110903", "transtext" => "Item 1",
183
- "objektlista" => [{"dimensionsnr" => "6", "objektnr" => "1"}]
184
- )
185
-
186
- expect(indexed_entry("ver", 1).attributes).to eq(
187
- "serie" => "KB", "vernr" => "2",
188
- "verdatum" => "20120831", "vertext" => "Payout 1"
189
- )
190
- expect(indexed_voucher_entries(1)[0].attributes).to eq(
191
- "kontonr" => "2400", "belopp" => "256.0",
192
- "transdat" => "20120831", "transtext" => "Payout line 1",
193
- "objektlista" => []
194
- )
195
- expect(indexed_voucher_entries(1)[1].attributes).to eq(
196
- "kontonr" => "1970", "belopp" => "-256.0",
197
- "transdat" => "20120831", "transtext" => "Payout line 2",
198
- "objektlista" => []
199
- )
200
- end
201
-
202
- context "with really long descriptions" do
203
- let(:accounts) {
204
- [
205
- number: 1500, description: "k" * 101 # Make sure that the description exceeds the limit (100 chars).
206
- ]
207
- }
208
- let(:vouchers) {
209
- [
210
- build_voucher(
211
- description: "d" * 101,
212
- voucher_lines: [
213
- build_voucher_line(description: "v" * 101),
214
- build_voucher_line(description: "Payout line 2"),
215
- ]
216
- )
217
- ]
218
- }
219
-
220
- it "truncates the descriptions" do
221
- expect(indexed_entry_attributes("konto", 0)).to eq("kontonr" => "1500", "kontonamn" => "k" * 100)
222
- expect(indexed_entry("ver", 0).attributes["vertext"]).to eq("d" * 100)
223
- expect(indexed_voucher_entries(0)[0].attributes["transtext"]).to eq("v" * 100)
224
- end
225
- end
226
-
227
- context "with a zeroed single voucher line" do
228
- let(:vouchers) {
229
- [
230
- build_voucher(voucher_lines: [ build_voucher_line(amount: 0) ])
231
- ]
232
- }
233
-
234
- it "ensures there are at least two lines" do
235
- expect(indexed_voucher_entries(0).size).to eq(2)
236
- end
237
- end
238
-
239
- context "with a series defined" do
240
- let(:vouchers) {
241
- [
242
- build_voucher(series: "X"),
243
- ]
244
- }
245
-
246
- it "reads the series from the voucher" do
247
- expect(indexed_entry("ver", 0).attributes["serie"]).to eq("X")
248
- end
249
- end
250
-
251
- private
252
-
253
- def build_voucher(attributes)
254
- defaults = {
255
- creditor: true,
256
- type: :payment,
257
- number: 1,
258
- booked_on: Date.today,
259
- description: "A voucher",
260
- voucher_lines: [
261
- build_voucher_line,
262
- build_voucher_line,
263
- ],
264
- }
265
- defaults.merge(attributes)
266
- end
267
-
268
- def build_voucher_line(attributes = {})
269
- defaults = { account_number: 1234, amount: 1, booked_on: Date.today, description: "A voucher line" }
270
- defaults.merge(attributes)
271
- end
272
-
273
- def entry_attribute(label, attribute)
274
- indexed_entry_attribute(label, 0, attribute)
275
- end
276
-
277
- def indexed_entry_attribute(label, index, attribute)
278
- indexed_entry_attributes(label, index).fetch(attribute) do
279
- raise "Unknown attribute #{ attribute } in #{ entry.attributes.keys.inspect }"
280
- end
281
- end
282
-
283
- def indexed_entry_attributes(label, index)
284
- indexed_entry(label, index).attributes
285
- end
286
-
287
- def indexed_voucher_entries(index)
288
- indexed_entry("ver", index).entries
289
- end
290
-
291
- def indexed_entry(label, index)
292
- sie_file.entries_with_label(label)[index] or raise "No entry with label #{ label.inspect } found!"
293
- end
294
- end
@@ -1,37 +0,0 @@
1
- require "spec_helper"
2
- require "sie/parser/line_parser"
3
-
4
- describe Sie::Parser::LineParser, "parse" do
5
- it "parses lines from a sie file" do
6
- parser = Sie::Parser::LineParser.new('#TRANS 2400 {"3" "5"} -200 20130101 "Foocorp expense"')
7
- entry = parser.parse
8
- expect(entry.label).to eq("trans")
9
- expect(entry.attributes).to eq({
10
- "kontonr" => "2400",
11
- "belopp" => "-200",
12
- "transdat" => "20130101",
13
- "transtext" => "Foocorp expense",
14
- "objektlista" => [{"dimensionsnr" => "3", "objektnr" => "5"}],
15
- })
16
- end
17
-
18
- context "with unknown entry" do
19
- let(:line) { "#MOMSKOD 2611 10"}
20
-
21
- context "using a lenient parser" do
22
- let(:parser) { Sie::Parser::LineParser.new(line, lenient: true) }
23
-
24
- it "raises no error when encountering unknown entries" do
25
- expect { parser.parse }.not_to raise_error
26
- end
27
- end
28
-
29
- context "using a strict parser" do
30
- let(:parser) { Sie::Parser::LineParser.new(line) }
31
-
32
- it "raises error when encountering unknown entries" do
33
- expect { parser.parse }.to raise_error(/Unknown entry type/)
34
- end
35
- end
36
- end
37
- end
@@ -1,98 +0,0 @@
1
- require "spec_helper"
2
- require "sie/parser/tokenizer"
3
-
4
- describe Sie::Parser::Tokenizer do
5
- it "tokenizes the given line" do
6
- tokenizer = Sie::Parser::Tokenizer.new('#TRANS 2400 {} -200 20130101 "Foocorp expense"')
7
- tokens = tokenizer.tokenize
8
-
9
- expect(token_table_for(tokens)).to eq([
10
- [ "EntryToken", "TRANS" ],
11
- [ "StringToken", "2400" ],
12
- [ "BeginArrayToken", "" ],
13
- [ "EndArrayToken", "" ],
14
- [ "StringToken", "-200" ],
15
- [ "StringToken", "20130101" ],
16
- [ "StringToken", "Foocorp expense" ]
17
- ])
18
- end
19
-
20
- it "can parse metadata arrays" do
21
- tokenizer = Sie::Parser::Tokenizer.new('#TRANS 2400 { 1 "2" } -200 20130101 "Foocorp expense"')
22
- tokens = tokenizer.tokenize
23
-
24
- expect(token_table_for(tokens)).to eq([
25
- [ "EntryToken", "TRANS" ],
26
- [ "StringToken", "2400" ],
27
- [ "BeginArrayToken", "" ],
28
- [ "StringToken", "1" ],
29
- [ "StringToken", "2" ],
30
- [ "EndArrayToken", "" ],
31
- [ "StringToken", "-200" ],
32
- [ "StringToken", "20130101" ],
33
- [ "StringToken", "Foocorp expense" ]
34
- ])
35
- end
36
-
37
- it "handles escaped quotes in quoted strings" do
38
- tokenizer = Sie::Parser::Tokenizer.new('"String with \\" quote"')
39
- tokens = tokenizer.tokenize
40
-
41
- expect(token_table_for(tokens)).to eq([
42
- [ "StringToken", 'String with " quote']
43
- ])
44
- end
45
-
46
- it "handles escaped quotes in non-quoted strings" do
47
- tokenizer = Sie::Parser::Tokenizer.new('String_with_\\"_quote')
48
- tokens = tokenizer.tokenize
49
-
50
- expect(token_table_for(tokens)).to eq([
51
- [ "StringToken", 'String_with_"_quote']
52
- ])
53
- end
54
-
55
- it "handles escaped backslash in strings" do
56
- tokenizer = Sie::Parser::Tokenizer.new('"String with \\\\ backslash"')
57
- tokens = tokenizer.tokenize
58
-
59
- expect(token_table_for(tokens)).to eq([
60
- [ "StringToken", 'String with \\ backslash']
61
- ])
62
- end
63
-
64
- it "has reasonable behavior for consecutive escape characters" do
65
- tokenizer = Sie::Parser::Tokenizer.new('"\\\\\\"\\\\"')
66
- tokens = tokenizer.tokenize
67
-
68
- expect(token_table_for(tokens)).to eq([
69
- [ "StringToken", '\\"\\']
70
- ])
71
- end
72
-
73
- it "handles tab character as field separator" do
74
- tokenizer = Sie::Parser::Tokenizer.new("#TRANS\t2400")
75
- tokens = tokenizer.tokenize
76
-
77
- expect(token_table_for(tokens)).to eq([
78
- [ "EntryToken", "TRANS"],
79
- [ "StringToken", "2400"]
80
- ])
81
- end
82
-
83
- it "rejects control characters" do
84
- codes_not_allowed = (0..8).to_a + (10..31).to_a + [127]
85
- codes_not_allowed.each do |x|
86
- tokenizer = Sie::Parser::Tokenizer.new([x].pack("C"))
87
- expect{tokenizer.tokenize}.to raise_error /Unhandled character/
88
- end
89
- end
90
-
91
- private
92
-
93
- def token_table_for(tokens)
94
- tokens.map { |token|
95
- [ token.class.name.split("::").last, token.value ]
96
- }
97
- end
98
- end
@@ -1,42 +0,0 @@
1
- require "spec_helper"
2
- require "sie/parser"
3
-
4
- describe Sie::Parser, "parse" do
5
- it "parses sie data that includes arrays" do
6
- data = <<-DATA
7
- #VER "LF" 2222 20130101 "Foocorp expense"
8
- {
9
- #TRANS 2400 {} -200 20130101 "Foocorp expense"
10
- #TRANS 4100 {} 180 20130101 "Widgets from foocorp"
11
- #TRANS 2611 {} -20 20130101 "VAT"
12
- }
13
- DATA
14
-
15
- parser = Sie::Parser.new
16
- sie_file = parser.parse(data)
17
-
18
- voucher_entry = sie_file.entries.first
19
- expect(sie_file.entries.size).to eq(1)
20
- expect(voucher_entry.attributes["verdatum"]).to eq("20130101")
21
- expect(voucher_entry.entries.size).to eq(3)
22
- expect(voucher_entry.entries.first.attributes["kontonr"]).to eq("2400")
23
- end
24
-
25
- it "handles leading whitespace" do
26
- data = <<-DATA
27
- #VER "LF" 2222 20130101 "Foocorp expense"
28
- {
29
- #TRANS 2400 {} -200 20130101 "Foocorp expense"
30
- #TRANS 4100 {} 180 20130101 "Widgets from foocorp"
31
- #TRANS 2611 {} -20 20130101 "VAT"
32
- }
33
- DATA
34
-
35
- parser = Sie::Parser.new
36
- sie_file = parser.parse(data)
37
-
38
- voucher_entry = sie_file.entries.first
39
- expect(sie_file.entries.size).to eq(1)
40
- expect(voucher_entry.entries.size).to eq(3)
41
- end
42
- end