finexclub 0.1.1

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.
@@ -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