kuby 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9370fe068bbcbf6b38c2ad3806e73021157a594a
4
+ data.tar.gz: 010e342da6d058879dbd8b3ffa69a07b9e5b73f2
5
+ SHA512:
6
+ metadata.gz: 04ab9831be23e1aff218257771c6248f526c8309df40789ca9090fdeeb72a419c96108bab4e1c816f14eb0284ed52558f8bd51ee766bb825b2bdad1ff3a4d584
7
+ data.tar.gz: 5725160e4ae5582a558245acf55395f66f8bca769c812e5dd5024218ba50183e03f5b66deefa8e63e55c650900926b4e503135112d0c2443816c771f21d4eda6
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create 2.0.0@kuby
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kuby.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,10 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
9
+ end
10
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ralph Rooding
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # Kuby
2
+
3
+ [![Build Status](https://travis-ci.org/rrooding/kuby.png?branch=master)](https://travis-ci.org/rrooding/kuby)
4
+
5
+ ### Crash your Kerbals using Ruby!
6
+
7
+ Kuby is a Ruby wrapper for the game [Kerbal Space Program](https://kerbalspaceprogram.com/). This gem exposes a simple DSL with which you can control your rockets.
8
+
9
+ ## Installation
10
+
11
+ Install the gem:
12
+
13
+ $ gem install kuby
14
+
15
+ Make sure you have a recent version of KSP and also install the [Telemachus plugin](http://kerbalspaceport.com/telemachus/).
16
+
17
+ ## Usage
18
+
19
+ ### Basic example
20
+
21
+ Create a ruby file with the following contents (simple_launch.rb for example):
22
+
23
+ require 'rubygems'
24
+ require 'kuby'
25
+
26
+ # Optional parameters :host, :port, otherwise defaults will be used (127.0.0.1:8085)
27
+ link = Kuby::Link.new
28
+
29
+ # Connect to KSP
30
+ link.connect!
31
+
32
+ # Initiate first stage
33
+ link.stage!
34
+
35
+ # Set to full throttle
36
+ link.throttle_full
37
+
38
+ # Activate SAS
39
+ link.toggle_sas
40
+
41
+ Now create a new rocket in KSP or load an existing one. Be sure to add one of the Telemachus antennas to it, otherwise your rocket won't be able to communicate. Now go to the launchpad and when the ship is loaded and you are ready for launch, execute the following command in a terminal:
42
+
43
+ $ ruby simple_launch.rb
44
+
45
+ Kuby will connect to your rocket and issue the commands in the order you specified in the file, your rocket will activate the first stage, go to full throttle and enable SAS. After that, the script ends but your rocket will keep flying.
46
+
47
+ ### Advanced example
48
+
49
+ This example will fly your rocket to ± 150 meters and then keeps it floating there by changing the throttle using an implementation of a PID controller
50
+
51
+ require 'rubygems'
52
+ require 'kuby'
53
+
54
+ # Optional parameters :host, :port, otherwise defaults will be used (127.0.0.1:8085)
55
+ link = Kuby::Link.new
56
+
57
+ # Connect to KSP
58
+ link.connect!
59
+
60
+ # Initiate first stage
61
+ link.stage!
62
+
63
+ # Set to full throttle
64
+ link.throttle_full
65
+
66
+ # Activate SAS
67
+ link.toggle_sas
68
+
69
+ # Wait untill we're at 150 meters
70
+ while link.altitude < 150 do
71
+ sleep 0.2
72
+ end
73
+
74
+ target = 0.0
75
+ previous = 0.0
76
+ error = 0.0
77
+ integral = 0.0
78
+ derivative = 0.0
79
+ time = link.mission_time
80
+
81
+ loop do
82
+ dt = link.mission_time - time
83
+ time = link.mission_time
84
+ error = target - link.vertical_speed
85
+ integral = integral + error * dt
86
+ derivative = (error - previous)/dt
87
+
88
+ new_throttle = (error/10 + integral/15 + derivative/30)
89
+
90
+ if new_throttle > 1.0
91
+ new_throttle = 1.0
92
+ elsif new_throttle < 0.0
93
+ new_throttle = 0.0
94
+ end
95
+
96
+ link.set_throttle new_throttle
97
+
98
+ previous = error
99
+
100
+ sleep 0.2
101
+ end
102
+
103
+
104
+ ## Contributing
105
+
106
+ 1. Fork it
107
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
108
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
109
+ 4. Push to the branch (`git push origin my-new-feature`)
110
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc 'Default: run rspec'
5
+ task :default => :spec
6
+
7
+ desc 'Run specs'
8
+ RSpec::Core::RakeTask.new
data/kuby.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kuby/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "kuby"
8
+ gem.version = Kuby::VERSION
9
+ gem.authors = ["Ralph Rooding"]
10
+ gem.email = ["ralph@izerion.com"]
11
+ gem.description = %q{Crash your Kerbals using Ruby!}
12
+ gem.summary = %q{Crash your Kerbals using Ruby!}
13
+ gem.homepage = "https://github.com/rrooding/kuby"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'excon'
21
+ gem.add_dependency 'multi_json'
22
+
23
+ gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'rspec'
25
+ gem.add_development_dependency 'guard-rspec'
26
+ gem.add_development_dependency 'webmock'
27
+ end
@@ -0,0 +1,9 @@
1
+ module Kuby
2
+ class Link
3
+ module ApiMethods
4
+ def version
5
+ Gem::Version.new api_get('a.version')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,70 @@
1
+ module Kuby
2
+ class Link
3
+ module FlightMethods
4
+ def abort
5
+ api_get('f.abort')
6
+ end
7
+
8
+ # Define a method for each of the 10 action groups
9
+ (1..10).each do |group_no|
10
+ define_method "actiongroup_#{group_no}" do
11
+ api_get("f.ag#{group_no}")
12
+ end
13
+ end
14
+
15
+ def brake
16
+ api_get('f.brake')
17
+ end
18
+
19
+ def set_throttle(t)
20
+ if t > 1.0
21
+ t = 1.0
22
+ elsif t < 0.0
23
+ t = 0.0
24
+ end
25
+
26
+ api_set('f.setThrottle', t)
27
+ end
28
+
29
+ def stage!
30
+ api_get('f.stage')
31
+ end
32
+
33
+ def throttle
34
+ api_get('f.throttle').to_f
35
+ end
36
+
37
+ def throttle_down
38
+ api_get('f.throttleDown')
39
+ end
40
+
41
+ def throttle_up
42
+ api_get('f.throttleUp')
43
+ end
44
+
45
+ def throttle_full
46
+ api_get('f.throttleFull')
47
+ end
48
+
49
+ def throttle_zero
50
+ api_get('f.throttleZero')
51
+ end
52
+
53
+ def toggle_gear
54
+ api_get('f.gear')
55
+ end
56
+
57
+ def toggle_light
58
+ api_get('f.light')
59
+ end
60
+
61
+ def toggle_rcs
62
+ api_get('f.rcs')
63
+ end
64
+
65
+ def toggle_sas
66
+ api_get('f.sas')
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,17 @@
1
+ module Kuby
2
+ class Link
3
+ module NavbalMethods
4
+ def heading
5
+ api_get('n.heading').to_f
6
+ end
7
+
8
+ def pitch
9
+ api_get('n.pitch').to_f
10
+ end
11
+
12
+ def roll
13
+ api_get('n.roll').to_f
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Kuby
2
+ class Link
3
+ module PausedMethods
4
+ PAUSE_STATES = [:not_paused, :flight_paused, :out_of_power, :antenna_disabled, :vessel_wo_antenna, :unknown_pause_state]
5
+
6
+ def paused?
7
+ pause_value > 0
8
+ end
9
+
10
+ def pause_state
11
+ PAUSE_STATES[pause_value]
12
+ end
13
+
14
+ private
15
+
16
+ def pause_value
17
+ api_get('p.paused').to_i
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,73 @@
1
+ module Kuby
2
+ class Link
3
+ module VesselMethods
4
+ def altitude
5
+ api_get('v.altitude').to_f
6
+ end
7
+
8
+ def height
9
+ api_get('v.heightFromTerrain').to_f
10
+ end
11
+
12
+ def terrain_height
13
+ api_get('v.terrainHeight').to_f
14
+ end
15
+
16
+ def mission_time
17
+ api_get('v.missionTime').to_f
18
+ end
19
+
20
+ def surface_velocity
21
+ api_get('v.surfaceVelocity').to_f
22
+ end
23
+
24
+ def surface_velocity_x
25
+ api_get('v.surfaceVelocityx').to_f
26
+ end
27
+
28
+ def surface_velocity_y
29
+ api_get('v.surfaceVelocityy').to_f
30
+ end
31
+
32
+ def surface_velocity_z
33
+ api_get('v.surfaceVelocityz').to_f
34
+ end
35
+
36
+ def angular_velocity
37
+ api_get('v.angularVelocity').to_f
38
+ end
39
+
40
+ def orbital_velocity
41
+ api_get('v.orbitalVelocity').to_f
42
+ end
43
+
44
+ def surface_speed
45
+ api_get('v.surfaceSpeed').to_f
46
+ end
47
+
48
+ def vertical_speed
49
+ api_get('v.verticalSpeed').to_f
50
+ end
51
+
52
+ def atmospheric_density
53
+ api_get('v.atmosphericDensity').to_f
54
+ end
55
+
56
+ def lat
57
+ api_get('v.lat')
58
+ end
59
+
60
+ def long
61
+ api_get('v.long')
62
+ end
63
+
64
+ def dynamic_pressure
65
+ api_get('v.dynamicPressure').to_f
66
+ end
67
+
68
+ def name
69
+ api_get('v.name')
70
+ end
71
+ end
72
+ end
73
+ end
data/lib/kuby/link.rb ADDED
@@ -0,0 +1,62 @@
1
+ require 'multi_json'
2
+ require 'kuby/link/api_methods'
3
+ require 'kuby/link/flight_methods'
4
+ require 'kuby/link/navbal_methods'
5
+ require 'kuby/link/paused_methods'
6
+ require 'kuby/link/vessel_methods'
7
+
8
+ class Kuby::Link
9
+ MIN_TELEMACHUS_VERSION = Gem::Version.new('1.4.6.0')
10
+
11
+ attr_reader :host, :port
12
+
13
+ include Kuby::Link::ApiMethods
14
+ include Kuby::Link::FlightMethods
15
+ include Kuby::Link::NavbalMethods
16
+ include Kuby::Link::PausedMethods
17
+ include Kuby::Link::VesselMethods
18
+
19
+ def initialize(options={})
20
+ @host = options.fetch(:host, '127.0.0.1')
21
+ @port = options.fetch(:port, 8085).to_i
22
+ @path = 'telemachus/datalink'
23
+ end
24
+
25
+ def connect!
26
+ # Raise error when the telemachus version is not supported, this also automatically
27
+ # checks if the connection can be made
28
+ unless supported_version?
29
+ raise Kuby::UnsupportedTelemachusVersion.new("Please install Telemachus #{MIN_TELEMACHUS_VERSION} or higher")
30
+ end
31
+
32
+ true
33
+ end
34
+
35
+ private
36
+
37
+ def api_set(ret, *args)
38
+ api_get("#{ret}[#{args.join(',')}]")
39
+ end
40
+
41
+ def api_get(ret)
42
+ # All Telemachus api methods are GET, the api command is passed in as the 'ret' parameter,
43
+ # the returned result is in the form of: {"ret":"<value>"}
44
+ res = Excon.get(uri, { tcp_nodelay: true, query: "ret=#{ret}" })
45
+
46
+ # Parse the result
47
+ data = MultiJson.load(res.body, symbolize_keys: true)
48
+
49
+ data[:ret]
50
+ rescue Excon::Errors::SocketError, Errno::ECONNREFUSED
51
+ # Catch different kinds of connection refused and raise custom exception
52
+ raise Kuby::TelemachusConnectionRefused
53
+ end
54
+
55
+ def supported_version?
56
+ version >= MIN_TELEMACHUS_VERSION
57
+ end
58
+
59
+ def uri
60
+ @uri ||= "http://#{@host}:#{@port}/#{@path}"
61
+ end
62
+ end
@@ -0,0 +1,3 @@
1
+ module Kuby
2
+ VERSION = "0.1.0"
3
+ end
data/lib/kuby.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'kuby/version'
2
+ require 'kuby/link'
3
+
4
+ module Kuby
5
+ class UnsupportedTelemachusVersion < StandardError; end
6
+ class ConnectionNotEstablished < StandardError; end
7
+ class TelemachusConnectionRefused < StandardError; end
8
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyClass
4
+ end
5
+
6
+ describe Kuby::Link::ApiMethods do
7
+ subject { DummyClass.new }
8
+
9
+ before do
10
+ subject.extend Kuby::Link::ApiMethods
11
+ subject.stub(:api_get)
12
+ end
13
+
14
+ describe '#version' do
15
+ it 'implements the a.version call' do
16
+ subject.should_receive(:api_get).with('a.version')
17
+
18
+ subject.version
19
+ end
20
+
21
+ it 'returns a Gem::Version instance' do
22
+ expect(subject.version).to be_an_instance_of Gem::Version
23
+ end
24
+
25
+ it 'sets the version to the returned version' do
26
+ subject.stub(:api_get).and_return('1.2.3.4')
27
+
28
+ expect(subject.version.to_s).to eq '1.2.3.4'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,155 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyClass
4
+ end
5
+
6
+ describe Kuby::Link::FlightMethods do
7
+ subject { DummyClass.new }
8
+
9
+ before do
10
+ subject.extend Kuby::Link::FlightMethods
11
+ subject.stub(:api_get)
12
+ end
13
+
14
+ describe '#abort' do
15
+ it 'implements the f.abort call' do
16
+ subject.should_receive(:api_get).with('f.abort')
17
+
18
+ subject.abort
19
+ end
20
+ end
21
+
22
+ (1..10).each do |group_no|
23
+ describe "#actiongroup_#{group_no}" do
24
+ it "implements the f.ag#{group_no} call" do
25
+ subject.should_receive(:api_get).with("f.ag#{group_no}")
26
+
27
+ subject.send("actiongroup_#{group_no}")
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#brake' do
33
+ it 'implements the f.brake call' do
34
+ subject.should_receive(:api_get).with('f.brake')
35
+
36
+ subject.brake
37
+ end
38
+ end
39
+
40
+ describe '#set_throttle' do
41
+ it 'implements the f.setThrottle call' do
42
+ subject.should_receive(:api_set).with('f.setThrottle', 0.5)
43
+
44
+ subject.set_throttle(0.5)
45
+ end
46
+
47
+ context 'throttle is larger than 1' do
48
+ it 'normalizes to 1.0' do
49
+ subject.should_receive(:api_set).with('f.setThrottle', 1.0)
50
+
51
+ subject.set_throttle(123)
52
+ end
53
+ end
54
+
55
+ context 'throttle is not a float or int' do
56
+ it 'raises an ArgumentError' do
57
+ expect {
58
+ subject.set_throttle('a')
59
+ }.to raise_error ArgumentError
60
+ end
61
+ end
62
+
63
+ context 'throttle is smaller than 0' do
64
+ it 'normalizes to 0.0' do
65
+ subject.should_receive(:api_set).with('f.setThrottle', 0.0)
66
+
67
+ subject.set_throttle(-0.4)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#stage!' do
73
+ it 'implements the f.stage call' do
74
+ subject.should_receive(:api_get).with('f.stage')
75
+
76
+ subject.stage!
77
+ end
78
+ end
79
+
80
+ describe '#throttle' do
81
+ it 'implements the f.throttle call' do
82
+ subject.should_receive(:api_get).with('f.throttle')
83
+
84
+ subject.throttle
85
+ end
86
+
87
+ it 'returns a float' do
88
+ expect(subject.throttle).to be_an_instance_of Float
89
+ end
90
+ end
91
+
92
+ describe '#throttle_down' do
93
+ it 'implements the f.throttleDown call' do
94
+ subject.should_receive(:api_get).with('f.throttleDown')
95
+
96
+ subject.throttle_down
97
+ end
98
+ end
99
+
100
+ describe '#throttle_up' do
101
+ it 'implements the f.throttleUp call' do
102
+ subject.should_receive(:api_get).with('f.throttleUp')
103
+
104
+ subject.throttle_up
105
+ end
106
+ end
107
+
108
+ describe '#throttle_full' do
109
+ it 'implements the f.throttleFull call' do
110
+ subject.should_receive(:api_get).with('f.throttleFull')
111
+
112
+ subject.throttle_full
113
+ end
114
+ end
115
+
116
+ describe '#throttle_zero' do
117
+ it 'implements the f.throttleZero call' do
118
+ subject.should_receive(:api_get).with('f.throttleZero')
119
+
120
+ subject.throttle_zero
121
+ end
122
+ end
123
+
124
+ describe '#toggle_gear' do
125
+ it 'implements the f.gear call' do
126
+ subject.should_receive(:api_get).with('f.gear')
127
+
128
+ subject.toggle_gear
129
+ end
130
+ end
131
+
132
+ describe '#toggle_light' do
133
+ it 'implements the f.light call' do
134
+ subject.should_receive(:api_get).with('f.light')
135
+
136
+ subject.toggle_light
137
+ end
138
+ end
139
+
140
+ describe '#toggle_rcs' do
141
+ it 'implements the f.rcs call' do
142
+ subject.should_receive(:api_get).with('f.rcs')
143
+
144
+ subject.toggle_rcs
145
+ end
146
+ end
147
+
148
+ describe '#toggle_sas' do
149
+ it 'implements the f.sas call' do
150
+ subject.should_receive(:api_get).with('f.sas')
151
+
152
+ subject.toggle_sas
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyClass
4
+ end
5
+
6
+ describe Kuby::Link::NavbalMethods do
7
+ subject { DummyClass.new }
8
+
9
+ before do
10
+ subject.extend Kuby::Link::NavbalMethods
11
+ subject.stub(:api_get)
12
+ end
13
+
14
+ describe '#heading' do
15
+ it 'implements the n.heading call' do
16
+ subject.should_receive(:api_get).with('n.heading')
17
+
18
+ subject.heading
19
+ end
20
+
21
+ it 'returns a float' do
22
+ expect(subject.heading).to be_an_instance_of Float
23
+ end
24
+ end
25
+
26
+ describe '#pitch' do
27
+ it 'implements the n.pitch call' do
28
+ subject.should_receive(:api_get).with('n.pitch')
29
+
30
+ subject.pitch
31
+ end
32
+
33
+ it 'returns a float' do
34
+ expect(subject.pitch).to be_an_instance_of Float
35
+ end
36
+ end
37
+
38
+ describe '#roll' do
39
+ it 'implements the n.roll call' do
40
+ subject.should_receive(:api_get).with('n.roll')
41
+
42
+ subject.roll
43
+ end
44
+
45
+ it 'returns a float' do
46
+ expect(subject.roll).to be_an_instance_of Float
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyClass
4
+ end
5
+
6
+ describe Kuby::Link::PausedMethods do
7
+ subject { DummyClass.new }
8
+
9
+ before do
10
+ subject.extend Kuby::Link::PausedMethods
11
+ subject.stub(:api_get)
12
+ end
13
+
14
+ describe '#paused?' do
15
+ it 'implements the p.paused call' do
16
+ subject.should_receive(:api_get).with('p.paused')
17
+
18
+ subject.paused?
19
+ end
20
+
21
+ context 'ret is non-zero' do
22
+ before do
23
+ subject.stub(:api_get).and_return '1'
24
+ end
25
+
26
+ it 'returns true' do
27
+ expect(subject).to be_paused
28
+ end
29
+ end
30
+
31
+ context 'ret is zero' do
32
+ before do
33
+ subject.stub(:api_get).and_return '0'
34
+ end
35
+
36
+ it 'returns false' do
37
+ expect(subject).to_not be_paused
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '#pause_state' do
43
+ context 'not paused' do
44
+ before do
45
+ subject.stub(:api_get).and_return '0'
46
+ end
47
+
48
+ it 'returns :not_paused' do
49
+ expect(subject.pause_state).to be :not_paused
50
+ end
51
+ end
52
+
53
+ context 'flight paused' do
54
+ before do
55
+ subject.stub(:api_get).and_return '1'
56
+ end
57
+
58
+ it 'returns :flight_paused' do
59
+ expect(subject.pause_state).to be :flight_paused
60
+ end
61
+ end
62
+
63
+ context 'out of power' do
64
+ before do
65
+ subject.stub(:api_get).and_return '2'
66
+ end
67
+
68
+ it 'returns :out_of_power' do
69
+ expect(subject.pause_state).to be :out_of_power
70
+ end
71
+ end
72
+
73
+ context 'antenna disabled' do
74
+ before do
75
+ subject.stub(:api_get).and_return '3'
76
+ end
77
+
78
+ it 'returns :antenna_disabled' do
79
+ expect(subject.pause_state).to be :antenna_disabled
80
+ end
81
+ end
82
+
83
+ context 'vessel without antenna' do
84
+ before do
85
+ subject.stub(:api_get).and_return '4'
86
+ end
87
+
88
+ it 'returns :vessel_wo_antenna' do
89
+ expect(subject.pause_state).to be :vessel_wo_antenna
90
+ end
91
+ end
92
+
93
+ context 'unknown pause state' do
94
+ before do
95
+ subject.stub(:api_get).and_return '5'
96
+ end
97
+
98
+ it 'returns :unknown_pause_state' do
99
+ expect(subject.pause_state).to be :unknown_pause_state
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,205 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyClass
4
+ end
5
+
6
+ describe Kuby::Link::VesselMethods do
7
+ subject { DummyClass.new }
8
+
9
+ before do
10
+ subject.extend Kuby::Link::VesselMethods
11
+ subject.stub(:api_get)
12
+ end
13
+
14
+ describe '#altitude' do
15
+ it 'implements the v.altitude call' do
16
+ subject.should_receive(:api_get).with('v.altitude')
17
+
18
+ subject.altitude
19
+ end
20
+
21
+ it 'returns a float' do
22
+ expect(subject.altitude).to be_an_instance_of Float
23
+ end
24
+ end
25
+
26
+ describe '#height' do
27
+ it 'implements the v.heightFromTerrain call' do
28
+ subject.should_receive(:api_get).with('v.heightFromTerrain')
29
+
30
+ subject.height
31
+ end
32
+
33
+ it 'returns a float' do
34
+ expect(subject.height).to be_an_instance_of Float
35
+ end
36
+ end
37
+
38
+ describe '#terrain_height' do
39
+ it 'implements the v.terrainHeight call' do
40
+ subject.should_receive(:api_get).with('v.terrainHeight')
41
+
42
+ subject.terrain_height
43
+ end
44
+
45
+ it 'returns a float' do
46
+ expect(subject.terrain_height).to be_an_instance_of Float
47
+ end
48
+ end
49
+
50
+ describe '#mission_time' do
51
+ it 'implements the v.missionTime call' do
52
+ subject.should_receive(:api_get).with('v.missionTime')
53
+
54
+ subject.mission_time
55
+ end
56
+
57
+ it 'returns a float' do
58
+ expect(subject.mission_time).to be_an_instance_of Float
59
+ end
60
+ end
61
+
62
+ describe '#surface_velocity' do
63
+ it 'implements the v.surfaceVelocity call' do
64
+ subject.should_receive(:api_get).with('v.surfaceVelocity')
65
+
66
+ subject.surface_velocity
67
+ end
68
+
69
+ it 'returns a float' do
70
+ expect(subject.surface_velocity).to be_an_instance_of Float
71
+ end
72
+ end
73
+
74
+ describe '#surface_velocity_x' do
75
+ it 'implements the v.surfaceVelocityx call' do
76
+ subject.should_receive(:api_get).with('v.surfaceVelocityx')
77
+
78
+ subject.surface_velocity_x
79
+ end
80
+
81
+ it 'returns a float' do
82
+ expect(subject.surface_velocity_x).to be_an_instance_of Float
83
+ end
84
+ end
85
+
86
+ describe '#surface_velocity_y' do
87
+ it 'implements the v.surfaceVelocityy call' do
88
+ subject.should_receive(:api_get).with('v.surfaceVelocityy')
89
+
90
+ subject.surface_velocity_y
91
+ end
92
+
93
+ it 'returns a float' do
94
+ expect(subject.surface_velocity_y).to be_an_instance_of Float
95
+ end
96
+ end
97
+
98
+ describe '#surface_velocity_z' do
99
+ it 'implements the v.surfaceVelocityz call' do
100
+ subject.should_receive(:api_get).with('v.surfaceVelocityz')
101
+
102
+ subject.surface_velocity_z
103
+ end
104
+
105
+ it 'returns a float' do
106
+ expect(subject.surface_velocity_z).to be_an_instance_of Float
107
+ end
108
+ end
109
+
110
+ describe '#angular_velocity' do
111
+ it 'implements the v.angularVelocity call' do
112
+ subject.should_receive(:api_get).with('v.angularVelocity')
113
+
114
+ subject.angular_velocity
115
+ end
116
+
117
+ it 'returns a float' do
118
+ expect(subject.angular_velocity).to be_an_instance_of Float
119
+ end
120
+ end
121
+
122
+ describe '#orbital_velocity' do
123
+ it 'implements the v.orbitalVelocity call' do
124
+ subject.should_receive(:api_get).with('v.orbitalVelocity')
125
+
126
+ subject.orbital_velocity
127
+ end
128
+
129
+ it 'returns a float' do
130
+ expect(subject.orbital_velocity).to be_an_instance_of Float
131
+ end
132
+ end
133
+
134
+ describe '#surface_speed' do
135
+ it 'implements the v.surfaceSpeed call' do
136
+ subject.should_receive(:api_get).with('v.surfaceSpeed')
137
+
138
+ subject.surface_speed
139
+ end
140
+
141
+ it 'returns a float' do
142
+ expect(subject.surface_speed).to be_an_instance_of Float
143
+ end
144
+ end
145
+
146
+ describe '#vertical_speed' do
147
+ it 'implements the v.verticalSpeed call' do
148
+ subject.should_receive(:api_get).with('v.verticalSpeed')
149
+
150
+ subject.vertical_speed
151
+ end
152
+
153
+ it 'returns a float' do
154
+ expect(subject.vertical_speed).to be_an_instance_of Float
155
+ end
156
+ end
157
+
158
+ describe '#atmospheric_density' do
159
+ it 'implements the v.atmosphericDensity call' do
160
+ subject.should_receive(:api_get).with('v.atmosphericDensity')
161
+
162
+ subject.atmospheric_density
163
+ end
164
+
165
+ it 'returns a float' do
166
+ expect(subject.atmospheric_density).to be_an_instance_of Float
167
+ end
168
+ end
169
+
170
+ describe '#lat' do
171
+ it 'implements the v.lat call' do
172
+ subject.should_receive(:api_get).with('v.lat')
173
+
174
+ subject.lat
175
+ end
176
+ end
177
+
178
+ describe '#long' do
179
+ it 'implements the v.long call' do
180
+ subject.should_receive(:api_get).with('v.long')
181
+
182
+ subject.long
183
+ end
184
+ end
185
+
186
+ describe '#dynamic_pressure' do
187
+ it 'implements the v.dynamicPressure call' do
188
+ subject.should_receive(:api_get).with('v.dynamicPressure')
189
+
190
+ subject.dynamic_pressure
191
+ end
192
+
193
+ it 'returns a float' do
194
+ expect(subject.dynamic_pressure).to be_an_instance_of Float
195
+ end
196
+ end
197
+
198
+ describe '#name' do
199
+ it 'implements the v.name call' do
200
+ subject.should_receive(:api_get).with('v.name')
201
+
202
+ subject.name
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kuby::Link do
4
+ subject { Kuby::Link.new }
5
+
6
+ describe '#initialize' do
7
+ context 'without options' do
8
+ it 'sets the host to the default' do
9
+ expect(subject.host).to eq '127.0.0.1'
10
+ end
11
+
12
+ it 'sets the port to default' do
13
+ expect(subject.port).to eq 8085
14
+ end
15
+ end
16
+
17
+ context 'with host' do
18
+ subject { Kuby::Link.new(host: 'kerbalhost.com') }
19
+
20
+ it 'sets the host to the given value' do
21
+ expect(subject.host).to eq 'kerbalhost.com'
22
+ end
23
+ end
24
+
25
+ context 'with port' do
26
+ subject { Kuby::Link.new(port: 1234) }
27
+
28
+ it 'sets the port to the given value' do
29
+ expect(subject.port).to eq 1234
30
+ end
31
+ end
32
+ end
33
+
34
+ describe '#connect!' do
35
+ context 'unsupported version' do
36
+ before do
37
+ stub_request(:get, /ret=a.version\z/).to_return({status: 200, body: '{"ret":"1.4.5.0"}'})
38
+ end
39
+
40
+ it 'raises a Kuby::UnsupportedTelemachusVersion exception' do
41
+ expect {
42
+ subject.connect!
43
+ }.to raise_error Kuby::UnsupportedTelemachusVersion
44
+ end
45
+ end
46
+
47
+ context 'connection refused' do
48
+ before do
49
+ stub_request(:get, /.+/).to_raise(Errno::ECONNREFUSED)
50
+ end
51
+
52
+ it 'raises a Kuby::TelemachusConnectionRefused exception' do
53
+ expect {
54
+ subject.connect!
55
+ }.to raise_error Kuby::TelemachusConnectionRefused
56
+ end
57
+ end
58
+
59
+ context 'connection ok' do
60
+ it 'returns true' do
61
+ expect(subject.connect!).to be_true
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ $LOAD_PATH.unshift File.dirname(__FILE__)
3
+
4
+ require 'rubygems'
5
+ require 'rspec'
6
+ require 'webmock/rspec'
7
+ require 'kuby'
8
+
9
+ RSpec.configure do |config|
10
+ config.before(:each) do
11
+ stub_request(:get, /ret=a.version\z/).to_return({status: 200, body: '{"ret":"1.4.6.0"}'})
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kuby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ralph Rooding
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: excon
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: multi_json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: webmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Crash your Kerbals using Ruby!
98
+ email:
99
+ - ralph@izerion.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .rvmrc
106
+ - .travis.yml
107
+ - Gemfile
108
+ - Guardfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - kuby.gemspec
113
+ - lib/kuby.rb
114
+ - lib/kuby/link.rb
115
+ - lib/kuby/link/api_methods.rb
116
+ - lib/kuby/link/flight_methods.rb
117
+ - lib/kuby/link/navbal_methods.rb
118
+ - lib/kuby/link/paused_methods.rb
119
+ - lib/kuby/link/vessel_methods.rb
120
+ - lib/kuby/version.rb
121
+ - spec/kuby/link/api_methods_spec.rb
122
+ - spec/kuby/link/flight_methods_spec.rb
123
+ - spec/kuby/link/navbal_methods_spec.rb
124
+ - spec/kuby/link/paused_methods_spec.rb
125
+ - spec/kuby/link/vessel_methods_spec.rb
126
+ - spec/kuby/link_spec.rb
127
+ - spec/spec_helper.rb
128
+ homepage: https://github.com/rrooding/kuby
129
+ licenses: []
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 2.0.6
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: Crash your Kerbals using Ruby!
151
+ test_files:
152
+ - spec/kuby/link/api_methods_spec.rb
153
+ - spec/kuby/link/flight_methods_spec.rb
154
+ - spec/kuby/link/navbal_methods_spec.rb
155
+ - spec/kuby/link/paused_methods_spec.rb
156
+ - spec/kuby/link/vessel_methods_spec.rb
157
+ - spec/kuby/link_spec.rb
158
+ - spec/spec_helper.rb