ffi-gphoto2 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -1
  3. data/Rakefile +2 -0
  4. data/examples/intervalometer.rb +9 -7
  5. data/examples/list_config.rb +3 -5
  6. data/examples/live_view.rb +6 -12
  7. data/examples/record_movie.rb +10 -13
  8. data/ffi-gphoto2.gemspec +2 -1
  9. data/lib/ffi/gphoto2_port.rb +2 -2
  10. data/lib/gphoto2/camera/capture.rb +59 -0
  11. data/lib/gphoto2/camera/configuration.rb +136 -0
  12. data/lib/gphoto2/camera/event.rb +56 -0
  13. data/lib/gphoto2/camera/filesystem.rb +44 -0
  14. data/lib/gphoto2/camera.rb +95 -166
  15. data/lib/gphoto2/camera_abilities.rb +6 -6
  16. data/lib/gphoto2/camera_abilities_list.rb +7 -6
  17. data/lib/gphoto2/camera_event.rb +1 -8
  18. data/lib/gphoto2/camera_file.rb +15 -5
  19. data/lib/gphoto2/camera_file_path.rb +3 -5
  20. data/lib/gphoto2/camera_folder.rb +11 -0
  21. data/lib/gphoto2/camera_list.rb +3 -10
  22. data/lib/gphoto2/camera_widgets/camera_widget.rb +27 -14
  23. data/lib/gphoto2/camera_widgets/radio_camera_widget.rb +1 -0
  24. data/lib/gphoto2/camera_widgets/range_camera_widget.rb +1 -0
  25. data/lib/gphoto2/context.rb +2 -6
  26. data/lib/gphoto2/entry.rb +2 -0
  27. data/lib/gphoto2/port_info.rb +8 -6
  28. data/lib/gphoto2/port_info_list.rb +5 -6
  29. data/lib/gphoto2/port_result.rb +2 -0
  30. data/lib/gphoto2/struct.rb +11 -0
  31. data/lib/gphoto2/version.rb +1 -1
  32. data/lib/gphoto2.rb +13 -0
  33. data/spec/gphoto2/camera_abilities_list_spec.rb +5 -5
  34. data/spec/gphoto2/camera_abilities_spec.rb +7 -7
  35. data/spec/gphoto2/camera_file_path_spec.rb +2 -2
  36. data/spec/gphoto2/camera_file_spec.rb +7 -7
  37. data/spec/gphoto2/camera_folder_spec.rb +3 -3
  38. data/spec/gphoto2/camera_list_spec.rb +3 -3
  39. data/spec/gphoto2/camera_spec.rb +37 -272
  40. data/spec/gphoto2/camera_widgets/date_camera_widget_spec.rb +1 -1
  41. data/spec/gphoto2/camera_widgets/radio_camera_widget_spec.rb +4 -4
  42. data/spec/gphoto2/camera_widgets/range_camera_widget_spec.rb +2 -2
  43. data/spec/gphoto2/camera_widgets/text_camera_widget_spec.rb +1 -1
  44. data/spec/gphoto2/camera_widgets/toggle_camera_widget_spec.rb +2 -2
  45. data/spec/gphoto2/context_spec.rb +1 -1
  46. data/spec/gphoto2/entry_spec.rb +2 -2
  47. data/spec/gphoto2/port_info_list_spec.rb +4 -4
  48. data/spec/gphoto2/port_info_spec.rb +9 -10
  49. data/spec/spec_helper.rb +0 -7
  50. data/spec/support/shared_examples/camera/capture_examples.rb +41 -0
  51. data/spec/support/shared_examples/camera/configuration_examples.rb +161 -0
  52. data/spec/support/shared_examples/camera/event_examples.rb +39 -0
  53. data/spec/support/shared_examples/camera/filesystem_examples.rb +46 -0
  54. data/spec/support/shared_examples/camera_widget_examples.rb +13 -13
  55. metadata +32 -4
@@ -7,7 +7,7 @@ module GPhoto2
7
7
  describe '#value' do
8
8
  it 'has a Time return value' do
9
9
  widget = DateCameraWidget.new(nil)
10
- widget.stub(:value).and_return(Time.now)
10
+ allow(widget).to receive(:value).and_return(Time.now)
11
11
  expect(widget.value).to be_kind_of(Time)
12
12
  end
13
13
  end
@@ -7,7 +7,7 @@ module GPhoto2
7
7
  describe '#value' do
8
8
  it 'has a String return value' do
9
9
  widget = RadioCameraWidget.new(nil)
10
- widget.stub(:value).and_return('text')
10
+ allow(widget).to receive(:value).and_return('text')
11
11
  expect(widget.value).to be_kind_of(String)
12
12
  end
13
13
  end
@@ -17,11 +17,11 @@ module GPhoto2
17
17
  size = 2
18
18
 
19
19
  widget = RadioCameraWidget.new(nil)
20
- widget.stub(:count_choices).and_return(size)
21
- widget.stub(:get_choice).and_return("choice")
20
+ allow(widget).to receive(:count_choices).and_return(size)
21
+ allow(widget).to receive(:get_choice).and_return("choice")
22
22
 
23
23
  expect(widget).to receive(:get_choice).exactly(size).times
24
-
24
+
25
25
  choices = widget.choices
26
26
 
27
27
  expect(choices.size).to eq(size)
@@ -7,7 +7,7 @@ module GPhoto2
7
7
  describe '#value' do
8
8
  it 'has a Float return value' do
9
9
  widget = RangeCameraWidget.new(nil)
10
- widget.stub(:value).and_return(0.0)
10
+ allow(widget).to receive(:value).and_return(0.0)
11
11
  expect(widget.value).to be_kind_of(Float)
12
12
  end
13
13
  end
@@ -18,7 +18,7 @@ module GPhoto2
18
18
  range = (min..max).step(inc).to_a
19
19
 
20
20
  widget = RangeCameraWidget.new(nil)
21
- widget.stub(:get_range).and_return([min, max, inc])
21
+ allow(widget).to receive(:get_range).and_return([min, max, inc])
22
22
 
23
23
  expect(widget.range).to eq(range)
24
24
  end
@@ -7,7 +7,7 @@ module GPhoto2
7
7
  describe '#value' do
8
8
  it 'has a String return value' do
9
9
  widget = TextCameraWidget.new(nil)
10
- widget.stub(:value).and_return('text')
10
+ allow(widget).to receive(:value).and_return('text')
11
11
  expect(widget.value).to be_kind_of(String)
12
12
  end
13
13
  end
@@ -7,13 +7,13 @@ module GPhoto2
7
7
  describe '#value' do
8
8
  it 'can have a TrueClass return value' do
9
9
  widget = ToggleCameraWidget.new(nil)
10
- widget.stub(:value).and_return(true)
10
+ allow(widget).to receive(:value).and_return(true)
11
11
  expect(widget.value).to be_kind_of(TrueClass)
12
12
  end
13
13
 
14
14
  it 'can have a FalseClass return value' do
15
15
  widget = ToggleCameraWidget.new(nil)
16
- widget.stub(:value).and_return(false)
16
+ allow(widget).to receive(:value).and_return(false)
17
17
  expect(widget.value).to be_kind_of(FalseClass)
18
18
  end
19
19
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module GPhoto2
4
4
  describe Context do
5
5
  before do
6
- Context.any_instance.stub(:new)
6
+ allow_any_instance_of(Context).to receive(:new)
7
7
  end
8
8
 
9
9
  describe '#finalize' do
@@ -8,8 +8,8 @@ module GPhoto2
8
8
  let(:value) { 'usb:250,006' }
9
9
 
10
10
  before do
11
- entry.stub(:get_name).and_return(name)
12
- entry.stub(:get_value).and_return(value)
11
+ allow(entry).to receive(:get_name).and_return(name)
12
+ allow(entry).to receive(:get_value).and_return(value)
13
13
  end
14
14
 
15
15
  describe '#name' do
@@ -3,8 +3,8 @@ require 'spec_helper'
3
3
  module GPhoto2
4
4
  describe PortInfoList do
5
5
  before do
6
- PortInfoList.any_instance.stub(:new)
7
- PortInfoList.any_instance.stub(:load)
6
+ allow_any_instance_of(PortInfoList).to receive(:new)
7
+ allow_any_instance_of(PortInfoList).to receive(:load)
8
8
  end
9
9
 
10
10
  describe '#lookup_path' do
@@ -13,7 +13,7 @@ module GPhoto2
13
13
  index = 0
14
14
 
15
15
  list = PortInfoList.new
16
- list.stub(:_lookup_path).and_return(index)
16
+ allow(list).to receive(:_lookup_path).and_return(index)
17
17
 
18
18
  expect(list.lookup_path(port)).to eq(index)
19
19
  end
@@ -21,7 +21,7 @@ module GPhoto2
21
21
 
22
22
  describe '#at' do
23
23
  it 'returns a new PortInfo instance at the specified index' do
24
- PortInfo.any_instance.stub(:new)
24
+ allow_any_instance_of(PortInfo).to receive(:new)
25
25
 
26
26
  list = PortInfoList.new
27
27
  port_info = list.at(0)
@@ -6,17 +6,16 @@ module GPhoto2
6
6
  let(:index) { 0 }
7
7
 
8
8
  before do
9
- PortInfo.any_instance.stub(:new)
9
+ allow_any_instance_of(PortInfo).to receive(:new)
10
10
  end
11
11
 
12
12
  describe '.find' do
13
13
  it 'returns a new PortInfo instance from a port path' do
14
- PortInfoList.any_instance.stub(:new)
15
- PortInfoList.any_instance.stub(:load)
16
- PortInfoList.any_instance.stub(:lookup_path)
17
- PortInfoList.any_instance.stub(:[]).and_return do
18
- PortInfo.new(port_info_list, index)
19
- end
14
+ allow_any_instance_of(PortInfoList).to receive(:new)
15
+ allow_any_instance_of(PortInfoList).to receive(:load)
16
+ allow_any_instance_of(PortInfoList).to receive(:lookup_path)
17
+ info = PortInfo.new(port_info_list, index)
18
+ allow_any_instance_of(PortInfoList).to receive(:[]).and_return(info)
20
19
 
21
20
  port_info = PortInfo.find('usb:250,006')
22
21
  expect(port_info).to be_kind_of(PortInfo)
@@ -27,7 +26,7 @@ module GPhoto2
27
26
  it 'returns the name of the port' do
28
27
  name = 'name'
29
28
  port_info = PortInfo.new(port_info_list, index)
30
- port_info.stub(:get_name).and_return(name)
29
+ allow(port_info).to receive(:get_name).and_return(name)
31
30
  expect(port_info.name).to eq(name)
32
31
  end
33
32
  end
@@ -36,7 +35,7 @@ module GPhoto2
36
35
  it 'returns the path of the port' do
37
36
  path = 'path'
38
37
  port_info = PortInfo.new(port_info_list, index)
39
- port_info.stub(:get_path).and_return(path)
38
+ allow(port_info).to receive(:get_path).and_return(path)
40
39
  expect(port_info.path).to eq(path)
41
40
  end
42
41
  end
@@ -45,7 +44,7 @@ module GPhoto2
45
44
  it 'returns the type of the port' do
46
45
  type = :usb
47
46
  port_info = PortInfo.new(port_info_list, index)
48
- port_info.stub(:get_type).and_return(type)
47
+ allow(port_info).to receive(:get_type).and_return(type)
49
48
  expect(port_info.type).to eq(type)
50
49
  end
51
50
  end
data/spec/spec_helper.rb CHANGED
@@ -3,10 +3,3 @@ require 'gphoto2'
3
3
 
4
4
  __dir__ ||= File.dirname(__FILE__)
5
5
  Dir[File.join(__dir__, 'support/**/*.rb')].each { |f| require f }
6
-
7
- RSpec.configure do |config|
8
- config.treat_symbols_as_metadata_keys_with_true_values = true
9
- config.run_all_when_everything_filtered = true
10
- config.filter_run :focus
11
- config.order = 'random'
12
- end
@@ -0,0 +1,41 @@
1
+ module GPhoto2
2
+ shared_examples_for Camera::Capture do
3
+ describe '#capture' do
4
+ let(:camera) { Camera.new(model, port) }
5
+ let(:path) { double('camera_file_path', folder: 'folder', name: 'name') }
6
+
7
+ before do
8
+ allow(camera).to receive(:_capture).and_return(path)
9
+ end
10
+
11
+ it 'saves the camera configuration' do
12
+ expect(camera).to receive(:save)
13
+ camera.capture
14
+ end
15
+
16
+ it 'returns a new CameraFile' do
17
+ expect(camera).to receive(:_capture)
18
+ expect(camera.capture).to be_kind_of(CameraFile)
19
+ end
20
+ end
21
+
22
+ describe '#preview' do
23
+ let(:camera) { Camera.new(model, port) }
24
+ let(:file) { double('camera_file') }
25
+
26
+ before do
27
+ allow(camera).to receive(:save)
28
+ allow(camera).to receive(:capture_preview).and_return(file)
29
+ end
30
+
31
+ it 'saves the camera configuration' do
32
+ expect(camera).to receive(:save)
33
+ camera.preview
34
+ end
35
+
36
+ it 'returns a new CameraFile' do
37
+ expect(camera.preview).to eq(file)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,161 @@
1
+ module GPhoto2
2
+ shared_examples_for Camera::Configuration do
3
+ describe '#window' do
4
+ let(:camera) { Camera.new(model, port) }
5
+ let(:window) { double('camera_widget') }
6
+
7
+ it 'always returns the same CameraWidget instance' do
8
+ allow(camera).to receive(:get_config).and_return(window)
9
+ expect(camera.window).to eq(window)
10
+ expect(camera.window).to eq(window)
11
+ end
12
+ end
13
+
14
+ describe '#config' do
15
+ it 'returns a map of configuration widgets' do
16
+ camera = Camera.new(model, port)
17
+ window = double('camera_widget')
18
+ allow(camera).to receive(:window).and_return(window)
19
+ allow(window).to receive(:flatten).and_return({ 'iso' => window })
20
+
21
+ expect(camera.config).to eq({ 'iso' => window })
22
+ end
23
+ end
24
+
25
+ describe '#reload' do
26
+ let(:camera) do
27
+ camera = Camera.new(model, port)
28
+ window = double('camera_widget')
29
+ allow(window).to receive(:flatten)
30
+ allow(camera).to receive(:get_config).and_return(window)
31
+ camera
32
+ end
33
+
34
+ it 'reloads the configuration from the camera' do
35
+ expect(camera).to receive(:get_config).once
36
+ camera.reload
37
+ end
38
+
39
+ it 'marks the camera as not dirty' do
40
+ camera.reload
41
+ expect(camera.dirty?).to be(false)
42
+ end
43
+ end
44
+
45
+ describe '#[]' do
46
+ let(:window) { double('camera_widget') }
47
+
48
+ let(:camera) do
49
+ camera = Camera.new(model, port)
50
+ allow(camera).to receive(:config).and_return({ 'iso' => window })
51
+ camera
52
+ end
53
+
54
+ context 'when the specified key exists' do
55
+ it 'returns a CameraWidget' do
56
+ expect(camera['iso']).to eq(window)
57
+ end
58
+ end
59
+
60
+ context 'when the specified key does not exist' do
61
+ it 'returns nil' do
62
+ expect(camera['shutterspeed2']).to be_nil
63
+ end
64
+ end
65
+ end
66
+
67
+ describe '#[]=' do
68
+ let(:window) do
69
+ window = double('camera_widget')
70
+ expect(window).to receive(:value=).with(400)
71
+ window
72
+ end
73
+
74
+ let(:camera) do
75
+ camera = Camera.new(model, port)
76
+ allow(camera).to receive(:[]).and_return(window)
77
+ camera
78
+ end
79
+
80
+ it "sets a widget's value" do
81
+ camera['iso'] = 400
82
+ end
83
+
84
+ it 'marks the camera as dirty' do
85
+ camera['iso'] = 400
86
+ expect(camera).to be_dirty
87
+ end
88
+
89
+ it 'returns the passed value' do
90
+ expect(camera['iso'] = 400).to eq(400)
91
+ end
92
+ end
93
+
94
+ describe '#update' do
95
+ let(:camera) do
96
+ camera = Camera.new(model, port)
97
+ allow(camera).to receive(:[]=)
98
+ allow(camera).to receive(:save)
99
+ camera
100
+ end
101
+
102
+ it 'sets one or more camera setting' do
103
+ expect(camera).to receive(:[]=).exactly(2).times
104
+ camera.update('iso' => 400, 'shutterspeed2' => '1/30')
105
+ end
106
+
107
+ it 'immediately saves the settings to the camera' do
108
+ expect(camera).to receive(:save)
109
+ camera.update
110
+ end
111
+ end
112
+
113
+ describe '#save' do
114
+ let(:camera) do
115
+ camera = Camera.new(model, port)
116
+ allow(camera).to receive_message_chain(:[], :value=)
117
+ allow(camera).to receive(:set_config)
118
+ camera
119
+ end
120
+
121
+ context 'when the camera is marked as dirty' do
122
+ it 'returns true' do
123
+ camera['iso'] = 400
124
+ expect(camera.save).to be(true)
125
+ end
126
+
127
+ it 'marks the camera as not dirty' do
128
+ camera['iso'] = 400
129
+ camera.save
130
+ expect(camera).not_to be_dirty
131
+ end
132
+ end
133
+
134
+ context 'when the camera is not marked as dirty' do
135
+ it 'returns false' do
136
+ expect(camera.save).to be(false)
137
+ end
138
+ end
139
+ end
140
+
141
+ describe '#dirty?' do
142
+ context 'when the configuration changed' do
143
+ it 'returns true' do
144
+ camera = Camera.new(model, port)
145
+ allow(camera).to receive_message_chain(:[], :value=)
146
+
147
+ camera['iso'] = 400
148
+
149
+ expect(camera).to be_dirty
150
+ end
151
+ end
152
+
153
+ context 'when the configuration has not changed' do
154
+ it 'returns false' do
155
+ camera = Camera.new(model, port)
156
+ expect(camera).not_to be_dirty
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,39 @@
1
+ module GPhoto2
2
+ shared_examples_for Camera::Event do
3
+ describe '#wait' do
4
+ let(:camera) { Camera.new(model, port) }
5
+ let(:event) { double('camera_event') }
6
+
7
+ before do
8
+ allow(camera).to receive(:wait_for_event).and_return(event)
9
+ end
10
+
11
+ it 'waits for a camera event' do
12
+ expect(camera).to receive(:wait_for_event)
13
+ camera.wait
14
+ end
15
+
16
+ it 'returns an event symbol' do
17
+ expect(camera.wait).to eq(event)
18
+ end
19
+ end
20
+
21
+ describe '#wait_for' do
22
+ let(:camera) { Camera.new(model, port) }
23
+ let(:event) { double('camera_event', type: :capture_complete) }
24
+
25
+ before do
26
+ allow(camera).to receive(:wait).and_return(event)
27
+ end
28
+
29
+ it 'blocks until a given event is returned from #wait' do
30
+ expect(camera).to receive(:wait)
31
+ camera.wait_for(:capture_complete)
32
+ end
33
+
34
+ it 'returns the first event of the given type' do
35
+ expect(camera.wait_for(:capture_complete)).to eq(event)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,46 @@
1
+ module GPhoto2
2
+ shared_examples_for Camera::Filesystem do
3
+ describe '#filesystem' do
4
+ let(:camera) { Camera.new(model, port) }
5
+
6
+ context 'when a path is passed' do
7
+ let(:path) { '/store_00010001' }
8
+
9
+ it 'assumes the path is absolute' do
10
+ fs = camera.filesystem(path[1..-1])
11
+ expect(fs.path).to eq(path)
12
+ end
13
+
14
+ it 'returns a folder at the path that was passed' do
15
+ fs = camera.filesystem(path)
16
+ expect(fs.path).to eq(path)
17
+ end
18
+ end
19
+
20
+ context 'when no path is passed' do
21
+ it 'returns a folder at the root of the filesystem' do
22
+ fs = camera.filesystem
23
+ expect(fs.path).to eq('/')
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#file' do
29
+ it 'retrieves a file from the camera' do
30
+ camera = Camera.new(model, port)
31
+ allow(camera).to receive(:file_get)
32
+ expect(camera).to receive(:file_get)
33
+ camera.file(double('camera_file'))
34
+ end
35
+ end
36
+
37
+ describe '#delete' do
38
+ it 'deletes a file from the camera' do
39
+ camera = Camera.new(model, port)
40
+ allow(camera).to receive(:file_delete)
41
+ expect(camera).to receive(:file_delete)
42
+ camera.delete(double('camera_file'))
43
+ end
44
+ end
45
+ end
46
+ end