ledger-rest 2.0.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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