sie 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MTZiMGU5Y2JlZWE3MjJkMDIxZGQ1NzQwNjlmZDRmZDk1YTYxMTk5Ng==
4
+ OTRlMWFiNTRkMmRjZDllMmY2MWYzYjFiMWYxZWI1MTNjNDNhODZkYw==
5
5
  data.tar.gz: !binary |-
6
- MTQzMTQ5ZTliZTc5NzA5ZGE5MWViNThkZjE1OTgwMGFkNTI3ODg5Nw==
6
+ MzliZThiOGNhNjZmODMyNzVkNTJhZWY0NzYzOTRjMGIyMjFkYTM1Zg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NzRiMTUwZTEyMzhmOTE4YTE2ZGU0Zjg0ZTk1Mzc5MTM0MTI0YjNhODVmMGRm
10
- ZTY2ZDFjZjFlM2YxZmQ4NGZkODIzZjhmNTRlNTY2NmMwZmE4NGVlNGM3Nzk0
11
- MTYxNGRiNjRkZjE2ZWI4NzJhMTllOGNmMWVmYWRiMWFhYTZjZmI=
9
+ ODJiZjc3ZDI5YWFiN2YxZTg0NTEwMTNjYjVjZDI4NjhlYWJhOGM4YzUyZjNi
10
+ Y2QxMDA2YmI4MjFiMDU3OWFhMjE5NmNjZTM2ZTRjYTdlMzFiOTA5OTcyNmQ4
11
+ ODdmNDAwYjZmNDRmZmM2NjY4ZDFhYzI0NTEwZDcyYTFkYmVkNzM=
12
12
  data.tar.gz: !binary |-
13
- MmExNTViM2VkY2M1OGExZmM4YjcwNzFhOTliNTQ1OWY5M2IzZjI0NzRlNjUx
14
- YTdhZmNlNTlkYTI5OWFhNjNlZjIyYWRjMjhkZGMzNDkxZjc3MGM2MTMzMDdm
15
- YWU2OWIwYTkwOGQ5NDU2NDc5N2Y1MDU0ZWY3ZGExMTBiYmZmYTg=
13
+ MzBlMzIzZTAyMGVkYTE1YWYyM2E4MDQ1NjM0MjMyMmU1Yjg3NGQ5MzBiMjFj
14
+ ZGJlMDY1MjhhZGJiZTQ4NTRmNzg0OTFkMGNmMjA5MTlmMjdmOGU0N2M1NzMz
15
+ NjI5ZjFjYzBhMTg5YzFlMTVmMjg1MGM0ZWY5YjQzZDIxODNkN2Q=
data/README.md CHANGED
@@ -124,6 +124,12 @@ File.open("path/to/file.se") do |f|
124
124
  end
125
125
  ```
126
126
 
127
+ By default the parser will raise an error if it encounters unknown entry types. Use the `lenient` option to avoid this:
128
+
129
+ ```ruby
130
+ parser = Sie::Parser.new(lenient: true)
131
+ ```
132
+
127
133
  For more info, see the specs.
128
134
 
129
135
  ## Developing
@@ -144,9 +150,10 @@ Getting the latest code and gems:
144
150
 
145
151
  1. Fork it
146
152
  2. Create your feature branch (`git checkout -b my-new-feature`)
147
- 3. Commit your changes (`git commit -am 'Add some feature'`)
148
- 4. Push to the branch (`git push origin my-new-feature`)
149
- 5. Create new Pull Request
153
+ 3. Try to be consistent with the local code style. `[ foo ]` not `[foo]`, double quotes not single quotes, small and well named methods, etc.
154
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
155
+ 5. Push to the branch (`git push origin my-new-feature`)
156
+ 6. Create new Pull Request
150
157
 
151
158
  ## Credits and license
152
159
 
data/lib/sie/document.rb CHANGED
@@ -5,10 +5,11 @@ require "active_support/core_ext/module/delegation"
5
5
 
6
6
  module Sie
7
7
  class Document
8
- pattr_initialize :data_source
9
8
  # Because fortnox imposes these limits
10
9
  DESCRIPTION_LENGTH_MAX = 30
11
10
 
11
+ pattr_initialize :data_source
12
+
12
13
  def render
13
14
  add_header
14
15
  add_financial_years
data/lib/sie/parser.rb CHANGED
@@ -9,6 +9,12 @@ module Sie
9
9
  END_OF_ARRAY = "}"
10
10
  ENTRY = /^#/
11
11
 
12
+ attr_private :options
13
+
14
+ def initialize(options = {})
15
+ @options = options
16
+ end
17
+
12
18
  def parse(io)
13
19
  stack = []
14
20
  sie_file = SieFile.new
@@ -34,7 +40,13 @@ module Sie
34
40
  private
35
41
 
36
42
  def parse_line(line)
37
- LineParser.new(line).parse
43
+ LineParser.new(line, lenient: lenient).parse
44
+ rescue BuildEntry::InvalidEntryError => ex
45
+ raise ex, "#{ex.message}. Pass 'lenient: true' to Parser.new to avoid this exception."
46
+ end
47
+
48
+ def lenient
49
+ options.fetch(:lenient, false)
38
50
  end
39
51
  end
40
52
  end
@@ -0,0 +1,57 @@
1
+ module Sie
2
+ class Parser
3
+ class BuildEntry
4
+ method_object :line, :first_token, :tokens, :lenient
5
+
6
+ InvalidEntryError = Class.new(StandardError)
7
+
8
+ def call
9
+ if first_token.known_entry_type?
10
+ build_complete_entry
11
+ elsif lenient
12
+ build_empty_entry
13
+ else
14
+ raise_invalid_entry_error
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def build_complete_entry
21
+ entry = build_empty_entry
22
+ entry_type = first_token.entry_type
23
+
24
+ entry_type.each_with_index do |entry_type, i|
25
+ break if i >= tokens.size
26
+
27
+ if entry_type.is_a?(Hash)
28
+ skip_array(tokens, i)
29
+ next
30
+ else
31
+ label = entry_type
32
+ entry.attributes[label] = tokens[i].value
33
+ end
34
+ end
35
+
36
+ entry
37
+ end
38
+
39
+ def build_empty_entry
40
+ Entry.new(first_token.label)
41
+ end
42
+
43
+ def raise_invalid_entry_error
44
+ raise InvalidEntryError, "Unknown entry type: #{first_token.label}"
45
+ end
46
+
47
+ def skip_array(tokens, i)
48
+ if tokens[i].is_a?(Tokenizer::BeginArrayToken) &&
49
+ !tokens[i+1].is_a?(Tokenizer::EndArrayToken)
50
+ raise "We currently don't support metadata within entries as we haven't had a need for it yet (the data between {} in #{line})."
51
+ end
52
+
53
+ tokens.reject! { |token| token.is_a?(Tokenizer::EndArrayToken) }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,32 +1,17 @@
1
1
  require "sie/parser/tokenizer"
2
2
  require "sie/parser/entry"
3
3
  require "sie/parser/sie_file"
4
+ require "sie/parser/build_entry"
4
5
 
5
6
  module Sie
6
7
  class Parser
7
8
  class LineParser
8
- pattr_initialize :line
9
+ pattr_initialize :line, [ :lenient ]
9
10
 
10
11
  def parse
11
12
  tokens = tokenize(line)
12
13
  first_token = tokens.shift
13
-
14
- entry = Entry.new(first_token.label)
15
- entry_type = first_token.entry_type
16
-
17
- entry_type.each_with_index do |entry_type, i|
18
- break if i >= tokens.size
19
-
20
- if entry_type.is_a?(Hash)
21
- skip_array(tokens, i)
22
- next
23
- else
24
- label = entry_type
25
- entry.attributes[label] = tokens[i].value
26
- end
27
- end
28
-
29
- entry
14
+ build_entry(first_token, tokens)
30
15
  end
31
16
 
32
17
  private
@@ -35,13 +20,8 @@ module Sie
35
20
  Tokenizer.new(line).tokenize
36
21
  end
37
22
 
38
- def skip_array(tokens, i)
39
- if tokens[i].is_a?(Tokenizer::BeginArrayToken) &&
40
- !tokens[i+1].is_a?(Tokenizer::EndArrayToken)
41
- raise "We currently don't support metadata within entries as we haven't had a need for it yet (the data between {} in #{line})."
42
- end
43
-
44
- tokens.reject! { |token| token.is_a?(Tokenizer::EndArrayToken) }
23
+ def build_entry(first_token, tokens)
24
+ BuildEntry.call(line, first_token, tokens, lenient)
45
25
  end
46
26
  end
47
27
  end
@@ -10,6 +10,10 @@ module Sie
10
10
  @value = value
11
11
  end
12
12
 
13
+ def known_entry_type?
14
+ Sie::Parser::ENTRY_TYPES.has_key?(label)
15
+ end
16
+
13
17
  def entry_type
14
18
  Sie::Parser::ENTRY_TYPES.fetch(label)
15
19
  end
data/lib/sie/version.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  module Sie
2
- VERSION = "2.1.0"
2
+ # For versioning see: http://semver.org/
3
+ VERSION = "2.2.0"
3
4
  end
@@ -0,0 +1,32 @@
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
+ }
@@ -18,7 +18,39 @@ describe Sie::Parser do
18
18
  end
19
19
  end
20
20
 
21
- def open_file(fixture_file)
22
- File.open(File.join(File.dirname(__FILE__), "../#{fixture_file}"))
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)
23
55
  end
24
56
  end
@@ -14,6 +14,26 @@ describe Sie::Parser::LineParser, "parse" do
14
14
  })
15
15
  end
16
16
 
17
+ context "with unknown entry" do
18
+ let(:line) { "#MOMSKOD 2611 10"}
19
+
20
+ context "using a lenient parser" do
21
+ let(:parser) { Sie::Parser::LineParser.new(line, lenient: true) }
22
+
23
+ it "raises no error when encountering unknown entries" do
24
+ expect { parser.parse }.not_to raise_error
25
+ end
26
+ end
27
+
28
+ context "using a strict parser" do
29
+ let(:parser) { Sie::Parser::LineParser.new(line) }
30
+
31
+ it "raises error when encountering unknown entries" do
32
+ expect { parser.parse }.to raise_error(/Unknown entry type/)
33
+ end
34
+ end
35
+ end
36
+
17
37
  it "fails if you have non empty metadata arrays until there is a need to support that" do
18
38
  parser = Sie::Parser::LineParser.new('#TRANS 2400 { 1 "2" } -200 20130101 "Foocorp expense"')
19
39
  expect(-> { parser.parse }).to raise_error(/don't support metadata/)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sie
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Barsoom AB
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-09 00:00:00.000000000 Z
11
+ date: 2015-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: attr_extras
@@ -99,6 +99,7 @@ files:
99
99
  - lib/sie/document/renderer.rb
100
100
  - lib/sie/document/voucher_series.rb
101
101
  - lib/sie/parser.rb
102
+ - lib/sie/parser/build_entry.rb
102
103
  - lib/sie/parser/entry.rb
103
104
  - lib/sie/parser/entry_types.rb
104
105
  - lib/sie/parser/line_parser.rb
@@ -113,6 +114,7 @@ files:
113
114
  - script/turbux_rspec
114
115
  - sie.gemspec
115
116
  - spec/fixtures/sie_file.se
117
+ - spec/fixtures/sie_file_with_unknown_entries.se
116
118
  - spec/integration/parser_spec.rb
117
119
  - spec/spec_helper.rb
118
120
  - spec/unit/document/renderer_spec.rb
@@ -147,6 +149,7 @@ specification_version: 4
147
149
  summary: Parses and generates SIE files (http://sie.se/)
148
150
  test_files:
149
151
  - spec/fixtures/sie_file.se
152
+ - spec/fixtures/sie_file_with_unknown_entries.se
150
153
  - spec/integration/parser_spec.rb
151
154
  - spec/spec_helper.rb
152
155
  - spec/unit/document/renderer_spec.rb