ledger-rest 2.0.3 → 3.0.0

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.
Files changed (41) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +1 -1
  4. data/Guardfile +4 -22
  5. data/{LICENSE.txt → LICENSE} +1 -1
  6. data/README.md +62 -11
  7. data/config.ru +1 -1
  8. data/ledger-rest.gemspec +17 -17
  9. data/ledger-rest.yml.example +3 -0
  10. data/lib/ledger-rest/app.rb +21 -34
  11. data/lib/ledger-rest/core_ext.rb +4 -3
  12. data/lib/ledger-rest/git.rb +8 -7
  13. data/lib/ledger-rest/ledger.rb +29 -24
  14. data/lib/ledger-rest/ledger/balance.rb +48 -15
  15. data/lib/ledger-rest/ledger/budget.rb +35 -16
  16. data/lib/ledger-rest/ledger/entry.rb +1 -4
  17. data/lib/ledger-rest/ledger/parser.rb +41 -37
  18. data/lib/ledger-rest/ledger/register.rb +31 -24
  19. data/lib/ledger-rest/ledger/transaction.rb +33 -28
  20. data/lib/ledger-rest/transactions.py +47 -0
  21. data/lib/ledger-rest/version.rb +2 -1
  22. data/spec/files/append.ledger +13 -0
  23. data/spec/files/budget.ledger +4 -0
  24. data/spec/files/main.ledger +4 -0
  25. data/spec/files/opening_balance.ledger +4 -0
  26. data/spec/files/transactions.ledger +11 -0
  27. data/spec/ledger-rest.yml +3 -0
  28. data/spec/ledger-rest/api/accounts_spec.rb +19 -0
  29. data/spec/ledger-rest/api/balance_spec.rb +117 -0
  30. data/spec/ledger-rest/api/budget_spec.rb +110 -0
  31. data/spec/ledger-rest/api/payees_spec.rb +19 -0
  32. data/spec/ledger-rest/api/register_spec.rb +233 -0
  33. data/spec/ledger-rest/api/transactions_spec.rb +201 -0
  34. data/spec/ledger-rest/api/version_spec.rb +13 -0
  35. data/spec/ledger-rest/ledger/balance_spec.rb +124 -0
  36. data/spec/ledger-rest/ledger/parser_spec.rb +184 -117
  37. data/spec/ledger-rest/ledger/transaction_spec.rb +38 -31
  38. data/spec/spec_helper.rb +22 -0
  39. data/spec/support/deep_eq_matcher.rb +149 -0
  40. metadata +52 -31
  41. data/ledger-rest.org +0 -22
@@ -2,40 +2,47 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe LedgerRest::Ledger::Transaction do
5
-
6
5
  context '#to_ledger' do
7
- subject {
8
- LedgerRest::Ledger::Transaction.new(:date => "2012/03/01",
9
- :effective_date => "2012/03/23",
10
- :cleared => true,
11
- :pending => false,
12
- :code => "INV#23",
13
- :payee => "me, myself and I",
14
- :postings => [
15
- {
16
- :account => "Expenses:Imaginary",
17
- :amount => "€ 23",
18
- :per_unit_cost => "USD 2300",
19
- :actual_date => "2012/03/24",
20
- :effective_date => "2012/03/25"
21
- }, {
22
- :account => "Expenses:Magical",
23
- :amount => "€ 42",
24
- :posting_cost => "USD 23000000",
25
- :virtual => true
26
- }, {
27
- :account => "Assets:Mighty"
28
- }, {
29
- :comment => "This is a freeform comment"
30
- },
31
- ])
32
- }
6
+ subject do
7
+ LedgerRest::Ledger::Transaction.new(date: '2012/03/01',
8
+ effective_date: '2012/03/23',
9
+ cleared: true,
10
+ pending: false,
11
+ code: 'INV#23',
12
+ payee: 'me, myself and I',
13
+ postings:
14
+ [
15
+ {
16
+ account: 'Expenses:Imaginary',
17
+ amount: 23.0,
18
+ commodity: 'EUR',
19
+ per_unit_cost: 2300.0,
20
+ per_unit_commodity: 'USD',
21
+ actual_date: '2012/03/24',
22
+ effective_date: '2012/03/25'
23
+ }, {
24
+ account: 'Expenses:Magical',
25
+ amount: 42.0,
26
+ commodity: 'EUR',
27
+ posting_cost: 23000000.0,
28
+ posting_cost_commodity: 'USD',
29
+ virtual: true
30
+ }, {
31
+ account: 'Assets:Mighty'
32
+ }, {
33
+ comment: 'This is a freeform comment'
34
+ },
35
+ ])
36
+ end
33
37
 
34
38
  it 'should generate correct ledger string' do
35
- subject.to_ledger.should == "2012/03/01=2012/03/23 * (INV#23) me, myself and I\n Expenses:Imaginary € 23 @@ USD 2300 ; [2012/03/24=2012/03/25]\n (Expenses:Magical) € 42 @ USD 23000000\n Assets:Mighty\n\ ; This is a freeform comment\n\n"
39
+ subject.to_ledger.should == <<TRANSACTION
40
+ 2012/03/01=2012/03/23 * (INV#23) me, myself and I
41
+ Expenses:Imaginary 23.00EUR @@ 2300.00USD ; [2012/03/24=2012/03/25]
42
+ (Expenses:Magical) 42.00EUR @ 23000000.00USD
43
+ Assets:Mighty
44
+ ; This is a freeform comment
45
+ TRANSACTION
36
46
  end
37
-
38
47
  end
39
-
40
-
41
48
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,31 @@
1
+ ENV['CONFIG_FILE'] ||= 'spec/ledger-rest.yml'
2
+
1
3
  require 'ledger-rest'
4
+ require 'rack/test'
5
+
6
+ require 'support/deep_eq_matcher.rb'
7
+
8
+ module RSpecMixin
9
+ include Rack::Test::Methods
10
+ def app
11
+ LedgerRest::App
12
+ end
13
+ end
2
14
 
3
15
  RSpec.configure do |config|
16
+ config.include RSpecMixin
17
+
4
18
  config.treat_symbols_as_metadata_keys_with_true_values = true
5
19
  config.run_all_when_everything_filtered = true
6
20
  config.filter_run :focus
7
21
 
8
22
  config.order = 'random'
9
23
  end
24
+
25
+ def restore_file(filename)
26
+ FileUtils.cp(filename, "#{filename}.backup")
27
+ yield
28
+ ensure
29
+ FileUtils.rm(filename)
30
+ FileUtils.mv("#{filename}.backup", filename, force: true)
31
+ end
@@ -0,0 +1,149 @@
1
+ module RSpec
2
+ module Deepmatch
3
+ module Methods
4
+
5
+ def match?(actual, expected)
6
+ return arrays_match?(actual, expected) if expected.is_a?(Array) && actual.is_a?(Array)
7
+ return hashes_match?(actual, expected) if expected.is_a?(Hash) && actual.is_a?(Hash)
8
+ expected == actual
9
+ end
10
+
11
+ def arrays_match?(actual, expected)
12
+ exp = expected.clone
13
+ actual.each do |a|
14
+ index = exp.find_index { |e| match? a, e }
15
+ return false if index.nil?
16
+ exp.delete_at(index)
17
+ end
18
+ exp.length == 0
19
+ end
20
+
21
+ def hashes_match?(actual, expected)
22
+ return false unless actual.keys.sort == expected.keys.sort
23
+ actual.each do |key, value|
24
+ return false unless match?(value, expected[key])
25
+ end
26
+ true
27
+ end
28
+
29
+ def diff(actual, expected, depth, options = {})
30
+ if actual.is_a?(Hash) && expected.is_a?(Hash)
31
+ diff_hash(actual, expected, depth+1)
32
+ elsif actual.is_a?(Array) && expected.is_a?(Array)
33
+ diff_array(actual, expected, depth+1)
34
+ else
35
+ if actual == expected
36
+ @diff << "#{options[:prefix]}#{actual.inspect}\n"
37
+ else
38
+ if depth > 0
39
+ if options[:missing]
40
+ @diff << "#{options[:prefix_missing]}#{expected.inspect}\n"
41
+ elsif options[:additional]
42
+ @diff << "#{options[:prefix_additional]}#{actual.inspect}\n"
43
+ else
44
+ @diff << "#{options[:prefix_missing]}#{expected.inspect}\n"
45
+ @diff << "#{options[:prefix_additional]}#{actual.inspect}\n"
46
+ end
47
+ else
48
+ @diff << "expected #{actual.inspect} to be equal #{expected.inspect}"
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def diff_array(actual, expected, depth = 1, color = :red)
55
+ intersection = intersection(actual, expected)
56
+ missing = missing(actual, expected)
57
+ additional = additional(actual, expected)
58
+
59
+ @diff << ' '*(depth-1) + "[\n"
60
+
61
+ missing.each do |element|
62
+ @diff << ' '*depth + "missing: #{element.inspect}\n"
63
+ end
64
+ additional.each do |element|
65
+ @diff << ' '*depth + "additional: #{element.inspect}\n"
66
+ end
67
+
68
+ @diff << ' '*(depth-1) + "]\n"
69
+ end
70
+
71
+ def diff_hash(actual, expected, depth = 1)
72
+ intersecting_keys = expected.keys & actual.keys
73
+ missing_keys = expected.keys - actual.keys
74
+ additional_keys = actual.keys - expected.keys
75
+
76
+ @diff << ' '*(depth-1) + "{\n"
77
+
78
+ intersecting_keys.each do |key|
79
+ diff(actual[key], expected[key], depth,
80
+ prefix: ' '*depth + "#{key.inspect} => ",
81
+ prefix_missing: ' '*depth + "missing: #{key.inspect} => ",
82
+ prefix_additional: ' '*depth + "additional: #{key.inspect} => ")
83
+ end
84
+
85
+ missing_keys.each do |key|
86
+ diff(actual[key], expected[key], depth,
87
+ missing: true,
88
+ prefix_missing: ' '*depth + "missing: #{key.inspect} => ")
89
+ end
90
+
91
+ additional_keys.each do |key|
92
+ diff(actual[key], expected[key], depth,
93
+ additional: true,
94
+ prefix_additional: ' '*depth + "additional: #{key.inspect} => ")
95
+ end
96
+
97
+ @diff << ' '*(depth-1) + "}\n"
98
+ end
99
+
100
+ def intersection(actual, expected)
101
+ exp = expected.clone
102
+ actual.select do |a|
103
+ index = exp.index { |e| match?(a, e) }
104
+ exp.delete_at(index) if index
105
+ index
106
+ end
107
+ end
108
+
109
+ def missing(actual, expected)
110
+ exp = expected.clone
111
+ actual.each do |a|
112
+ index = exp.index { |e| match?(a, e) }
113
+ exp.delete_at(index) if index
114
+ end
115
+ exp
116
+ end
117
+
118
+ def additional(actual, expected)
119
+ act = actual.clone
120
+ expected.each do |e|
121
+ index = act.index { |a| match?(a, e) }
122
+ act.delete_at(index) if index
123
+ end
124
+ act
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ RSpec::Matchers.define :deep_eq do |expected|
131
+ include RSpec::Deepmatch::Methods
132
+
133
+ match do |actual|
134
+ match?(actual, expected)
135
+ end
136
+
137
+ failure_message_for_should do |actual|
138
+ @diff = ''
139
+ "expected: #{expected}\ngot: #{actual}\n"
140
+ end
141
+
142
+ failure_message_for_should_not do |actual|
143
+ "expected that #{actual} would not equal #{expected}"
144
+ end
145
+
146
+ description do
147
+ "be deeply equal #{expected}"
148
+ end
149
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ledger-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
5
- prerelease:
4
+ version: 3.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Prof. MAAD
@@ -10,12 +9,11 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2012-11-24 00:00:00.000000000 Z
12
+ date: 2013-12-20 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: escape
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
18
  - - ! '>='
21
19
  - !ruby/object:Gem::Version
@@ -23,7 +21,6 @@ dependencies:
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
25
  - - ! '>='
29
26
  - !ruby/object:Gem::Version
@@ -31,7 +28,6 @@ dependencies:
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: sinatra
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
32
  - - ! '>='
37
33
  - !ruby/object:Gem::Version
@@ -39,7 +35,6 @@ dependencies:
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
39
  - - ! '>='
45
40
  - !ruby/object:Gem::Version
@@ -47,7 +42,6 @@ dependencies:
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: git
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
46
  - - ! '>='
53
47
  - !ruby/object:Gem::Version
@@ -55,7 +49,6 @@ dependencies:
55
49
  type: :runtime
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
53
  - - ! '>='
61
54
  - !ruby/object:Gem::Version
@@ -63,7 +56,6 @@ dependencies:
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: rake
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
60
  - - ! '>='
69
61
  - !ruby/object:Gem::Version
@@ -71,7 +63,6 @@ dependencies:
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
67
  - - ! '>='
77
68
  - !ruby/object:Gem::Version
@@ -79,7 +70,6 @@ dependencies:
79
70
  - !ruby/object:Gem::Dependency
80
71
  name: pry
81
72
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
73
  requirements:
84
74
  - - ! '>='
85
75
  - !ruby/object:Gem::Version
@@ -87,7 +77,6 @@ dependencies:
87
77
  type: :development
88
78
  prerelease: false
89
79
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
80
  requirements:
92
81
  - - ! '>='
93
82
  - !ruby/object:Gem::Version
@@ -95,7 +84,6 @@ dependencies:
95
84
  - !ruby/object:Gem::Dependency
96
85
  name: rspec
97
86
  requirement: !ruby/object:Gem::Requirement
98
- none: false
99
87
  requirements:
100
88
  - - ! '>='
101
89
  - !ruby/object:Gem::Version
@@ -103,7 +91,20 @@ dependencies:
103
91
  type: :development
104
92
  prerelease: false
105
93
  version_requirements: !ruby/object:Gem::Requirement
106
- none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rack-test
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
107
108
  requirements:
108
109
  - - ! '>='
109
110
  - !ruby/object:Gem::Version
@@ -111,7 +112,6 @@ dependencies:
111
112
  - !ruby/object:Gem::Dependency
112
113
  name: rb-inotify
113
114
  requirement: !ruby/object:Gem::Requirement
114
- none: false
115
115
  requirements:
116
116
  - - ! '>='
117
117
  - !ruby/object:Gem::Version
@@ -119,7 +119,6 @@ dependencies:
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
- none: false
123
122
  requirements:
124
123
  - - ! '>='
125
124
  - !ruby/object:Gem::Version
@@ -127,7 +126,6 @@ dependencies:
127
126
  - !ruby/object:Gem::Dependency
128
127
  name: guard-rspec
129
128
  requirement: !ruby/object:Gem::Requirement
130
- none: false
131
129
  requirements:
132
130
  - - ! '>='
133
131
  - !ruby/object:Gem::Version
@@ -135,7 +133,6 @@ dependencies:
135
133
  type: :development
136
134
  prerelease: false
137
135
  version_requirements: !ruby/object:Gem::Requirement
138
- none: false
139
136
  requirements:
140
137
  - - ! '>='
141
138
  - !ruby/object:Gem::Version
@@ -152,12 +149,12 @@ files:
152
149
  - Gemfile
153
150
  - Gemfile.lock
154
151
  - Guardfile
155
- - LICENSE.txt
152
+ - LICENSE
156
153
  - README.md
157
154
  - Rakefile
158
155
  - config.ru
159
156
  - ledger-rest.gemspec
160
- - ledger-rest.org
157
+ - ledger-rest.yml.example
161
158
  - lib/ledger-rest.rb
162
159
  - lib/ledger-rest/app.rb
163
160
  - lib/ledger-rest/core_ext.rb
@@ -169,41 +166,65 @@ files:
169
166
  - lib/ledger-rest/ledger/parser.rb
170
167
  - lib/ledger-rest/ledger/register.rb
171
168
  - lib/ledger-rest/ledger/transaction.rb
169
+ - lib/ledger-rest/transactions.py
172
170
  - lib/ledger-rest/version.rb
171
+ - spec/files/append.ledger
172
+ - spec/files/budget.ledger
173
+ - spec/files/main.ledger
174
+ - spec/files/opening_balance.ledger
175
+ - spec/files/transactions.ledger
176
+ - spec/ledger-rest.yml
177
+ - spec/ledger-rest/api/accounts_spec.rb
178
+ - spec/ledger-rest/api/balance_spec.rb
179
+ - spec/ledger-rest/api/budget_spec.rb
180
+ - spec/ledger-rest/api/payees_spec.rb
181
+ - spec/ledger-rest/api/register_spec.rb
182
+ - spec/ledger-rest/api/transactions_spec.rb
183
+ - spec/ledger-rest/api/version_spec.rb
184
+ - spec/ledger-rest/ledger/balance_spec.rb
173
185
  - spec/ledger-rest/ledger/parser_spec.rb
174
186
  - spec/ledger-rest/ledger/transaction_spec.rb
175
187
  - spec/spec_helper.rb
188
+ - spec/support/deep_eq_matcher.rb
176
189
  homepage: https://github.com/leoc/ledger-rest
177
190
  licenses: []
191
+ metadata: {}
178
192
  post_install_message:
179
193
  rdoc_options: []
180
194
  require_paths:
181
195
  - lib
182
196
  required_ruby_version: !ruby/object:Gem::Requirement
183
- none: false
184
197
  requirements:
185
198
  - - ! '>='
186
199
  - !ruby/object:Gem::Version
187
200
  version: '0'
188
- segments:
189
- - 0
190
- hash: -3952331821210503451
191
201
  required_rubygems_version: !ruby/object:Gem::Requirement
192
- none: false
193
202
  requirements:
194
203
  - - ! '>='
195
204
  - !ruby/object:Gem::Version
196
205
  version: '0'
197
- segments:
198
- - 0
199
- hash: -3952331821210503451
200
206
  requirements: []
201
207
  rubyforge_project:
202
- rubygems_version: 1.8.24
208
+ rubygems_version: 2.1.5
203
209
  signing_key:
204
- specification_version: 3
210
+ specification_version: 4
205
211
  summary: Ledger via REST.
206
212
  test_files:
213
+ - spec/files/append.ledger
214
+ - spec/files/budget.ledger
215
+ - spec/files/main.ledger
216
+ - spec/files/opening_balance.ledger
217
+ - spec/files/transactions.ledger
218
+ - spec/ledger-rest.yml
219
+ - spec/ledger-rest/api/accounts_spec.rb
220
+ - spec/ledger-rest/api/balance_spec.rb
221
+ - spec/ledger-rest/api/budget_spec.rb
222
+ - spec/ledger-rest/api/payees_spec.rb
223
+ - spec/ledger-rest/api/register_spec.rb
224
+ - spec/ledger-rest/api/transactions_spec.rb
225
+ - spec/ledger-rest/api/version_spec.rb
226
+ - spec/ledger-rest/ledger/balance_spec.rb
207
227
  - spec/ledger-rest/ledger/parser_spec.rb
208
228
  - spec/ledger-rest/ledger/transaction_spec.rb
209
229
  - spec/spec_helper.rb
230
+ - spec/support/deep_eq_matcher.rb