finexclub 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,203 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'Finexclub::Document' do
4
+ before do
5
+ @core = mock_core
6
+ class Foo
7
+ include Finexclub::Document
8
+ end
9
+ @object = Foo.new
10
+ @object.stub!(:core).and_return(@core)
11
+ end
12
+
13
+ it 'should swallow when assigned to _id' do
14
+ lambda {
15
+ @object._id = 111
16
+ }.should.not.raise
17
+ end
18
+
19
+ describe '.apply_meta' do
20
+ before do
21
+ @meta = {
22
+ :foo => :string,
23
+ :index => :integer,
24
+ :rate => :float,
25
+ :symbol => :symbol,
26
+ :updated => :timestamp,
27
+ :screenshot => :image
28
+ }
29
+ end
30
+
31
+ it 'should save meta as class variable' do
32
+ @object.apply_meta(@meta)
33
+ Foo.meta.should == @meta
34
+ end
35
+
36
+ [
37
+ :string,
38
+ :integer,
39
+ :float,
40
+ :timestamp,
41
+ :image
42
+ ].each do |field_type|
43
+ it "should define methods for #{field_type} type" do
44
+ Foo.should.receive("define_#{field_type}_fields".to_sym).with(:foo)
45
+ @object.apply_meta({:foo => field_type})
46
+ end
47
+ end
48
+ end
49
+
50
+ describe '.to_doc' do
51
+ before do
52
+ class Foo
53
+ field :symbol, :symbol
54
+ field :index, :integer
55
+ field :foo, :string
56
+
57
+ doc_fields :foo, :index
58
+ end
59
+ @object = Foo.new
60
+ end
61
+
62
+ it 'should only export specified fields' do
63
+ @object.build(:symbol => "eurusd", :index => 100, :foo => "bar")
64
+ @object.to_doc.should == {:index => 100, :foo => "bar"}
65
+ end
66
+ end
67
+
68
+ describe '.build' do
69
+ before do
70
+ @object.apply_meta({:foo => :string})
71
+ end
72
+
73
+ it 'should assign attribute values from symbols hash' do
74
+ @object.should.receive("foo=".to_sym).with("bar")
75
+ @object.build(:foo => "bar")
76
+ end
77
+
78
+ it 'should assign attribute values from string hash' do
79
+ @object.should.receive("foo=".to_sym).with("bar")
80
+ @object.build("foo" => "bar")
81
+ end
82
+ end
83
+
84
+ describe 'string fields' do
85
+ before do
86
+ @object.apply_meta({:foo => :string})
87
+ end
88
+
89
+ it 'should covert to string' do
90
+ @object.foo = 100
91
+ @object.foo.should == "100"
92
+ end
93
+
94
+ it 'should assign and read strings' do
95
+ @object.foo = "bar"
96
+ @object.foo.should == "bar"
97
+ end
98
+ end
99
+
100
+ describe 'integer fields' do
101
+ before do
102
+ @object.apply_meta({:foo => :integer})
103
+ end
104
+
105
+ it 'should convert integers from strings' do
106
+ @object.foo = "100"
107
+ @object.foo.should == 100
108
+ @object.foo.class.should == Fixnum
109
+ end
110
+
111
+ it 'should assign and read integers' do
112
+ @object.foo = 100
113
+ @object.foo.should == 100
114
+ @object.foo.class.should == Fixnum
115
+ end
116
+ end
117
+
118
+ describe 'float fields' do
119
+ before do
120
+ @object.apply_meta({:foo => :float})
121
+ end
122
+
123
+ it 'should convert to float from string' do
124
+ @object.foo = "1.1234"
125
+ @object.foo.should == 1.1234
126
+ @object.foo.class.should == Float
127
+ end
128
+
129
+ it 'should assign and read floats' do
130
+ @object.foo = 1.5
131
+ @object.foo.should == 1.5
132
+ @object.foo.class.should == Float
133
+ end
134
+ end
135
+
136
+ describe 'timestamp field' do
137
+ before do
138
+ @object.apply_meta({:updated => :timestamp})
139
+ end
140
+
141
+ it 'initialize from Time instance' do
142
+ ts = Time.now
143
+ @object.updated = ts
144
+ @object.updated.should == ts.to_i
145
+ @object.updated.class.should == Fixnum
146
+ end
147
+
148
+ it 'assign and read timestamp' do
149
+ @object.updated = 123123
150
+ @object.updated.should == 123123
151
+ end
152
+
153
+ it 'should provide updated_at as UTC Time' do
154
+ @object.updated = 123123
155
+ @object.updated_at.should == Time.at(123123).utc
156
+ end
157
+
158
+ it 'should provide updated_date date' do
159
+ # 2010-10-05
160
+ @object.updated = 1286236800
161
+ @object.updated_date.should == '2010-10-05'
162
+ end
163
+ end
164
+
165
+ describe 'symbol field' do
166
+ before do
167
+ @object.apply_meta({:symbol => :symbol})
168
+ end
169
+
170
+ it 'should convert to lowercase' do
171
+ @object.symbol = "EURUSD"
172
+ @object.symbol.should == "eurusd"
173
+ end
174
+
175
+ it 'should ignore case if lowercase' do
176
+ @object.symbol = "eurusd"
177
+ @object.symbol.should == "eurusd"
178
+ end
179
+ end
180
+
181
+ describe 'image field' do
182
+ before do
183
+ @object.apply_meta({:screenshot => :image})
184
+ end
185
+
186
+ it 'should store file if assigned to screenshot_filename' do
187
+ @core.images.should.receive(:store).with("egg.png").and_return("image_uid")
188
+ @object.screenshot_filename = "egg.png"
189
+ @object.screenshot.should == "image_uid"
190
+ end
191
+
192
+ it 'should assign and read image id' do
193
+ @object.screenshot = "image_uid"
194
+ @object.screenshot.should == "image_uid"
195
+ end
196
+
197
+ it 'should provide access to image' do
198
+ @core.images.should.receive(:fetch).with("image_uid").and_return(img=mock('job'))
199
+ @object.screenshot = "image_uid"
200
+ @object.screenshot_image.should == img
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'Finexclub::Images' do
4
+ before do
5
+ @core = mock_core
6
+ @images = Finexclub::Images.new(@core)
7
+ end
8
+
9
+ it 'should initialize Dragonfly application' do
10
+ @images.app.should == Dragonfly[:images]
11
+ end
12
+
13
+
14
+ describe 'configuring' do
15
+ it 'should allow configuring screenshot_path' do
16
+ @images.screenshot_path = "ololo"
17
+ @images.screenshot_path.should == "ololo"
18
+ end
19
+
20
+ it 'should forward configure_with' do
21
+ @images.app.should.receive(:configure_with).with(:rmagick)
22
+ @images.configure_with(:rmagick)
23
+ end
24
+
25
+ it 'should forward configure' do
26
+ @images.app.should.receive(:configure)
27
+ @images.configure {|app| }
28
+ end
29
+ end
30
+
31
+ describe '.store' do
32
+ before do
33
+ @images.screenshot_path = TEST_IMAGES_PATH
34
+ end
35
+
36
+ it 'should store given file using Dragonfly' do
37
+ File.should.receive(:new).with("#{TEST_IMAGES_PATH}/egg.png").and_return(image_file = mock('file'))
38
+ @images.app.should.receive(:store).with(image_file).and_return("image_uid")
39
+ @images.store("egg.png").should == "image_uid"
40
+ end
41
+ end
42
+
43
+ describe '.fetch' do
44
+ it 'should respond to .fetch' do
45
+ @images.app.should.receive(:fetch).with('image_uid').and_return(job = mock('job'))
46
+ @images.fetch('image_uid').should == job
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,99 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'Finexclub::Manager' do
4
+ before do
5
+ @core = mock_core
6
+ @manager = Finexclub::Manager.new(@core)
7
+ @manager.db = mock_mongo
8
+ end
9
+
10
+ describe 'mongo' do
11
+ before do
12
+ @mongo = mock('mongo')
13
+ @manager.db = @mongo
14
+ end
15
+ it 'should provide mongo instance' do
16
+ @manager.db.should == @mongo
17
+ end
18
+ it 'should have collection accessor' do
19
+ @mongo.stub!(:collection).and_return(coll = mock('coll'))
20
+ @manager.collection.should == coll
21
+ end
22
+ end
23
+
24
+ describe '.find' do
25
+ it 'should call find on collection and return Cursor' do
26
+ @manager.collection.should.receive(:find).with({:date => "2010-10-01"}, {}).and_return(c = mock('cursor'))
27
+ @manager.find(:date => "2010-10-01")
28
+ end
29
+ end
30
+
31
+ describe '.find_one' do
32
+ it 'should call find on collection' do
33
+ @manager.collection.should.receive(:find_one).with({:date => "2010-10-01", :symbol => "eurusd" }, {}).and_return({})
34
+ @manager.find_one(:date => "2010-10-01", :symbol => "eurusd").class == Finexclub::Chart
35
+ end
36
+
37
+ it 'should return nil if nothing found' do
38
+ @manager.collection.should.receive(:find_one).with({:date => "2010-10-01", :symbol => "eurusd"}, {}).and_return(nil)
39
+ @manager.find_one(:date => "2010-10-01", :symbol => "eurusd").should == nil
40
+ end
41
+ end
42
+
43
+ describe '.last_updated' do
44
+ before do
45
+ @cursor = mock('cursor', :first => {"updated" => 123})
46
+ end
47
+
48
+ it 'should search for the latest timestamp in collection' do
49
+ @manager.collection.should.receive(:find).with({}, :fields => {:updated => 1}, :sort => [['updated', :desc]], :limit => 1).and_return(@cursor)
50
+ @manager.last_updated.should == Time.at(123)
51
+ end
52
+
53
+ it 'should return nil if nothing found' do
54
+ @manager.collection.stub!(:find).and_return(mock('cursor', :first => nil))
55
+ @manager.last_updated.should == nil
56
+ end
57
+ end
58
+
59
+ describe '.add_signal' do
60
+ before do
61
+ class Omega < Finexclub::Signal
62
+ field :symbol, :symbol
63
+ field :updated, :timestamp
64
+ field :foo, :string
65
+
66
+ doc_fields :foo, :updated
67
+ end
68
+ end
69
+
70
+ it 'should update collection' do
71
+ #Mon Oct 04 18:10:20 0700 2010
72
+ ts = 1286190620
73
+
74
+ Finexclub::Signal.stub!(:handler_for).with(:omega).and_return(Omega)
75
+ @manager.collection.should.receive(:update).with(
76
+ {
77
+ :date => '2010-10-04',
78
+ :symbol => 'eurusd'
79
+ },
80
+ {
81
+ "$push" => {:omega => {:foo => "bar", :updated => 1286190620}},
82
+ "$set" => {:updated => 1286190620}
83
+ },
84
+ :upsert => true
85
+ )
86
+
87
+ Timecop.travel(Time.at(ts))
88
+ @manager.add_signal(:omega, {"foo" => "bar", "symbol" => "EURUSD"})
89
+ end
90
+ end
91
+
92
+ describe 'Cursor' do
93
+ before do
94
+ @mongo_cursor = mock('mongo_cursor')
95
+ class Foo; end
96
+ @cursor = Finexclub::Manager::Cursor.new(@core, Foo, @mongo_cursor)
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'Finexclub::Signal' do
4
+ before do
5
+ @core = mock_core
6
+ @signal = Finexclub::Signal.new(@core)
7
+ end
8
+
9
+ describe 'self.build' do
10
+ before do
11
+ class Finexclub::Signals::Foo < Finexclub::Signal
12
+ field :foo, :integer
13
+ end
14
+ end
15
+
16
+ describe 'self.handler_for' do
17
+ it 'should return valid signal class' do
18
+ Finexclub::Signal.handler_for(:foo).should == Finexclub::Signals::Foo
19
+ end
20
+
21
+ it 'should raise with unknown handler' do
22
+ lambda {
23
+ Finexclub::Signal.handler_for(:bar)
24
+ }.should.raise(NameError)
25
+ end
26
+ end
27
+
28
+ it 'should create new signal instance and initialize it with params' do
29
+ Finexclub::Signals::Foo.should.receive(:new).with(@core).and_return(sig = mock('signal'))
30
+ params = mock('params')
31
+ sig.should.receive(:build).with(params)
32
+
33
+ Finexclub::Signal.build(@core, :foo, params).should == sig
34
+ end
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,52 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'Finexclub::Signals::Zeta' do
4
+ before do
5
+ @core = mock_core
6
+ @zeta = Finexclub::Signals::Zeta.new(@core)
7
+ end
8
+
9
+ it 'should have meta' do
10
+ Finexclub::Signals::Zeta.meta.should == {
11
+ :updated => :timestamp,
12
+ :symbol => :symbol,
13
+ :up_support => :float,
14
+ :up_resist => :float,
15
+ :down_support => :float,
16
+ :down_resist => :float,
17
+ :screenshot => :image
18
+ }
19
+ end
20
+
21
+ it 'should build from doc' do
22
+ @zeta.build(:up_support => 1.1, :up_resist => 1.2, :down_support => 2.1, :down_resist => 2.2, :symbol => "eurusd", :screenshot => "image_uid")
23
+ @zeta.up_support.should == 1.1
24
+ @zeta.up_resist.should == 1.2
25
+ @zeta.down_support.should == 2.1
26
+ @zeta.down_resist.should == 2.2
27
+ @zeta.symbol.should == "eurusd"
28
+ @zeta.screenshot.should == "image_uid"
29
+ end
30
+
31
+ it 'should respond to #up_channel? / #down_channel' do
32
+ @zeta.build(:up_support => 0, :up_resist => 0)
33
+ @zeta.up_channel?.should == false
34
+
35
+ @zeta.build(:down_support => 0, :down_resist => 0)
36
+ @zeta.down_channel?.should == false
37
+ end
38
+
39
+ it 'should export valid doc' do
40
+ @core.images.stub!(:store).and_return('image_uid')
41
+ @zeta.build("up_support" => "1.1", "up_resist" => "1.2", "down_support" => "2.1", "down_resist" => "2.2", "updated" => 123, "screenshot_filename" => "egg.png")
42
+ @zeta.to_doc.should == {
43
+ :updated => 123,
44
+ :up_support => 1.1,
45
+ :up_resist => 1.2,
46
+ :down_support => 2.1,
47
+ :down_resist => 2.2,
48
+ :screenshot => 'image_uid'
49
+ }
50
+ end
51
+ end
52
+
@@ -0,0 +1,34 @@
1
+ require "rubygems"
2
+ require "bacon"
3
+ require "facon"
4
+ require "ap"
5
+ require "timecop"
6
+ require "chronic"
7
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/finexclub')
8
+
9
+ TEST_IMAGES_PATH = File.expand_path(File.dirname(__FILE__) + "/../samples")
10
+
11
+ class Bacon::Context
12
+ include Finexclub::Fabrication
13
+
14
+ def mock_core(extra_stubs = {})
15
+ mock('core', {
16
+ :images => mock('images', :store => 'image_uid'),
17
+ :signals => mock('signals')
18
+ }.merge(extra_stubs)
19
+ )
20
+ end
21
+
22
+ def mock_mongo(extra_stubs = {})
23
+ mock('mongo', {
24
+ :collection => mock('collection', :update => true)
25
+ }.merge(extra_stubs)
26
+ )
27
+ end
28
+
29
+ def test_core
30
+ Finexclub::Core.send(:new)
31
+ end
32
+ end
33
+
34
+ Bacon.summary_on_exit
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: finexclub
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 1
9
+ version: 0.1.1
10
+ platform: ruby
11
+ authors:
12
+ - Alex Levin
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-06 00:00:00 +07:00
18
+ default_executable: finexclub_updater
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bacon
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 1
30
+ - 0
31
+ version: 1.1.0
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: facon
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 4
44
+ - 1
45
+ version: 0.4.1
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: mongo
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 0
58
+ - 8
59
+ version: 1.0.8
60
+ type: :runtime
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: dragonfly
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ - 7
72
+ - 6
73
+ version: 0.7.6
74
+ type: :runtime
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: sinatra
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 1
85
+ - 0
86
+ - 0
87
+ version: 1.0.0
88
+ type: :runtime
89
+ version_requirements: *id005
90
+ - !ruby/object:Gem::Dependency
91
+ name: awesome_print
92
+ prerelease: false
93
+ requirement: &id006 !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ - 2
100
+ - 1
101
+ version: 0.2.1
102
+ type: :runtime
103
+ version_requirements: *id006
104
+ description: Finexclub gem stores and retrieves Forex signals and screenshots. It is the heart of the http://trendsonforex.com and http://finexclub.net
105
+ email: clubfinex@gmail.com
106
+ executables:
107
+ - finexclub_updater
108
+ extensions: []
109
+
110
+ extra_rdoc_files:
111
+ - LICENSE
112
+ - README.rdoc
113
+ files:
114
+ - .document
115
+ - .gitignore
116
+ - LICENSE
117
+ - README.rdoc
118
+ - Rakefile
119
+ - VERSION
120
+ - bin/finexclub_updater
121
+ - config.ru
122
+ - finexclub.gemspec
123
+ - lib/finexclub.rb
124
+ - lib/finexclub/app.rb
125
+ - lib/finexclub/chart.rb
126
+ - lib/finexclub/core.rb
127
+ - lib/finexclub/document.rb
128
+ - lib/finexclub/fabrication.rb
129
+ - lib/finexclub/images.rb
130
+ - lib/finexclub/manager.rb
131
+ - lib/finexclub/signal.rb
132
+ - lib/finexclub/signals/alpha.rb
133
+ - lib/finexclub/signals/zeta.rb
134
+ - samples/egg.png
135
+ - spec/finexclub/alpha_spec.rb
136
+ - spec/finexclub/app_spec.rb
137
+ - spec/finexclub/chart_spec.rb
138
+ - spec/finexclub/core_spec.rb
139
+ - spec/finexclub/document_spec.rb
140
+ - spec/finexclub/images_spec.rb
141
+ - spec/finexclub/manager_spec.rb
142
+ - spec/finexclub/signal_spec.rb
143
+ - spec/finexclub/zeta_spec.rb
144
+ - spec/spec_helper.rb
145
+ has_rdoc: true
146
+ homepage: http://github.com/alexlevin/finexclub
147
+ licenses: []
148
+
149
+ post_install_message:
150
+ rdoc_options:
151
+ - --charset=UTF-8
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ segments:
159
+ - 0
160
+ version: "0"
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ segments:
166
+ - 0
167
+ version: "0"
168
+ requirements: []
169
+
170
+ rubyforge_project:
171
+ rubygems_version: 1.3.6
172
+ signing_key:
173
+ specification_version: 3
174
+ summary: Little helper to maintain Forex signals and screenshots
175
+ test_files:
176
+ - spec/finexclub/signal_spec.rb
177
+ - spec/finexclub/manager_spec.rb
178
+ - spec/finexclub/app_spec.rb
179
+ - spec/finexclub/alpha_spec.rb
180
+ - spec/finexclub/core_spec.rb
181
+ - spec/finexclub/images_spec.rb
182
+ - spec/finexclub/chart_spec.rb
183
+ - spec/finexclub/document_spec.rb
184
+ - spec/finexclub/zeta_spec.rb
185
+ - spec/spec_helper.rb