shortcut 0.0.1 → 0.0.2
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.
- data/Guardfile +0 -1
- data/README.md +11 -8
- data/bin/shortcut +4 -0
- data/lib/keep_running.rb +10 -0
- data/lib/shortcut/application.rb +23 -0
- data/lib/shortcut/application_tasks/new.rb +64 -0
- data/lib/shortcut/application_tasks/templates/.travis.yml.tt +3 -0
- data/lib/shortcut/application_tasks/templates/Gemfile.tt +14 -0
- data/lib/shortcut/application_tasks/templates/LICENSE.txt.tt +22 -0
- data/lib/shortcut/application_tasks/templates/README.md.tt +30 -0
- data/lib/shortcut/application_tasks/templates/Rakefile.tt +1 -0
- data/lib/shortcut/application_tasks/templates/bin/newgem.tt +6 -0
- data/lib/shortcut/application_tasks/templates/config/launch4j.xml.tt +8 -0
- data/lib/shortcut/application_tasks/templates/gitignore.tt +17 -0
- data/lib/shortcut/application_tasks/templates/images/icons/128.png +0 -0
- data/lib/shortcut/application_tasks/templates/images/icons/16.png +0 -0
- data/lib/shortcut/application_tasks/templates/images/icons/32.png +0 -0
- data/lib/shortcut/application_tasks/templates/images/icons/64.png +0 -0
- data/lib/shortcut/application_tasks/templates/lib/newgem.rb.tt +50 -0
- data/lib/shortcut/application_tasks/templates/lib/newgem/version.rb.tt +7 -0
- data/lib/shortcut/application_tasks/templates/rspec.tt +2 -0
- data/lib/shortcut/application_tasks/templates/spec/newgem_spec.rb.tt +11 -0
- data/lib/shortcut/application_tasks/templates/spec/spec_helper.rb.tt +2 -0
- data/lib/shortcut/application_tasks/templates/test/minitest_helper.rb.tt +4 -0
- data/lib/shortcut/application_tasks/templates/test/test_newgem.rb.tt +11 -0
- data/lib/shortcut/screen.rb +1 -1
- data/lib/shortcut/version.rb +1 -1
- data/lib/shortcut/window.rb +48 -0
- data/shortcut.gemspec +3 -3
- data/spec/lib/shortcut_window_spec.rb +151 -59
- metadata +52 -36
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -4,19 +4,18 @@ Make your own Bot.
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
$ gem install shortcut
|
8
8
|
|
9
|
-
|
9
|
+
## Usage
|
10
10
|
|
11
|
-
|
11
|
+
At the command prompt, create a new Shortcut application:
|
12
12
|
|
13
|
-
$
|
13
|
+
$ shortcut new mybot
|
14
14
|
|
15
|
-
|
15
|
+
Change directory to `mybot` and start the application:
|
16
16
|
|
17
|
-
$
|
18
|
-
|
19
|
-
## Usage
|
17
|
+
$ cd mybot
|
18
|
+
$ ruby -Ilib ./bin/mybot
|
20
19
|
|
21
20
|
### Ubuntu 12.04 with Unity-2D
|
22
21
|
|
@@ -45,3 +44,7 @@ See more information about this [bug](https://bugs.launchpad.net/unity-2d/+bug/1
|
|
45
44
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
46
45
|
4. Push to the branch (`git push origin my-new-feature`)
|
47
46
|
5. Create new Pull Request
|
47
|
+
|
48
|
+
## Credits
|
49
|
+
|
50
|
+
* [Icons](http://www.iconarchive.com/show/soft-scraps-icons-by-deleket/Gear-icon.html)
|
data/bin/shortcut
ADDED
data/lib/keep_running.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
import javax.swing.SwingUtilities
|
4
|
+
|
5
|
+
# http://stackoverflow.com/questions/10108822/jruby-script-with-rubeus-and-swing-exiting-once-packaged-into-jar-using-warble
|
6
|
+
# Warbler calls System.exit() after your main script exits. This causes the Swing EventThread to exit, closing your app.
|
7
|
+
# https://github.com/jruby/warbler/blob/master/ext/JarMain.java#L131
|
8
|
+
event_thread = nil
|
9
|
+
SwingUtilities.invokeAndWait { event_thread = java.lang.Thread.currentThread }
|
10
|
+
event_thread.join
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'thor'
|
2
|
+
Dir[File.dirname(__FILE__) + '/application_tasks/*.rb'].each { |file| require file }
|
3
|
+
|
4
|
+
module Shortcut
|
5
|
+
class Application < Thor
|
6
|
+
desc "build", "Build runnable archive"
|
7
|
+
def build
|
8
|
+
exec('warble && mkdir -p pkg && mv *.jar pkg')
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "start", "Build and run application"
|
12
|
+
def start
|
13
|
+
exec('warble && mkdir -p pkg && mv *.jar pkg && java -jar pkg/*.jar')
|
14
|
+
end
|
15
|
+
|
16
|
+
method_option :test, :type => :string, :lazy_default => 'rspec', :aliases => '-t', :desc => "Generate a test directory for your application. Supports: 'rspec' (default), 'minitest'"
|
17
|
+
method_option :edit, :type => :string, :aliases => "-e",
|
18
|
+
:lazy_default => [ENV['BUNDLER_EDITOR'], ENV['VISUAL'], ENV['EDITOR']].find{|e| !e.nil? && !e.empty? },
|
19
|
+
:required => false, :banner => "/path/to/your/editor",
|
20
|
+
:desc => "Open generated gemspec in the specified editor (defaults to $EDITOR or $BUNDLER_EDITOR)"
|
21
|
+
register(Shortcut::ApplicationTasks::New, :new, "new [NAME]", "Creates a skeleton for creating a shortcut app")
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Shortcut
|
4
|
+
module ApplicationTasks
|
5
|
+
class New < Thor::Group
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
argument :name
|
9
|
+
|
10
|
+
def self.source_root
|
11
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
12
|
+
end
|
13
|
+
|
14
|
+
def skeleton
|
15
|
+
app_name = name.chomp("/") # remove trailing slash if present
|
16
|
+
namespaced_path = app_name.tr('-', '/')
|
17
|
+
target = File.join(Dir.pwd, app_name)
|
18
|
+
constant_name = app_name.split('_').map{|p| p[0..0].upcase + p[1..-1] }.join
|
19
|
+
constant_name = constant_name.split('-').map{|q| q[0..0].upcase + q[1..-1] }.join('::') if constant_name =~ /-/
|
20
|
+
constant_array = constant_name.split('::')
|
21
|
+
git_user_name = `git config user.name`.chomp
|
22
|
+
git_user_email = `git config user.email`.chomp
|
23
|
+
opts = {
|
24
|
+
:name => app_name,
|
25
|
+
:namespaced_path => namespaced_path,
|
26
|
+
:constant_name => constant_name,
|
27
|
+
:constant_array => constant_array,
|
28
|
+
:author => git_user_name.empty? ? "TODO: Write your name" : git_user_name,
|
29
|
+
:email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
|
30
|
+
:test => options[:test]
|
31
|
+
}
|
32
|
+
template("Gemfile.tt", File.join(target, "Gemfile"), opts)
|
33
|
+
template("Rakefile.tt", File.join(target, "Rakefile"), opts)
|
34
|
+
template("LICENSE.txt.tt", File.join(target, "LICENSE.txt"), opts)
|
35
|
+
template("README.md.tt", File.join(target, "README.md"), opts)
|
36
|
+
template("gitignore.tt", File.join(target, ".gitignore"), opts)
|
37
|
+
template("lib/newgem.rb.tt", File.join(target, "lib/#{namespaced_path}.rb"), opts)
|
38
|
+
template("lib/newgem/version.rb.tt", File.join(target, "lib/#{namespaced_path}/version.rb"), opts)
|
39
|
+
template("bin/newgem.tt", File.join(target, 'bin', app_name), opts)
|
40
|
+
template("config/launch4j.xml.tt", File.join(target, 'config/launch4j.xml'), opts)
|
41
|
+
case options[:test]
|
42
|
+
when 'rspec'
|
43
|
+
template("rspec.tt", File.join(target, ".rspec"), opts)
|
44
|
+
template("spec/spec_helper.rb.tt", File.join(target, "spec/spec_helper.rb"), opts)
|
45
|
+
template("spec/newgem_spec.rb.tt", File.join(target, "spec/#{namespaced_path}_spec.rb"), opts)
|
46
|
+
when 'minitest'
|
47
|
+
template("test/minitest_helper.rb.tt", File.join(target, "test/minitest_helper.rb"), opts)
|
48
|
+
template("test/test_newgem.rb.tt", File.join(target, "test/test_#{namespaced_path}.rb"), opts)
|
49
|
+
end
|
50
|
+
if options[:test]
|
51
|
+
template(".travis.yml.tt", File.join(target, ".travis.yml"), opts)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Icons
|
55
|
+
[16, 32, 64, 128].each do |size|
|
56
|
+
copy_file("images/icons/#{size}.png", File.join(target, "images/icons/#{size}.png"))
|
57
|
+
end
|
58
|
+
|
59
|
+
say "Initializating git repo in #{target}"
|
60
|
+
Dir.chdir(target) { `git init`; `git add .` }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) <%=Time.now.year%> <%=config[:author]%>
|
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.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# <%=config[:constant_name]%>
|
2
|
+
|
3
|
+
TODO: Write an app description
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
To test your application, run:
|
8
|
+
|
9
|
+
$ ruby -Ilib ./bin/<%=config[:name]%>
|
10
|
+
|
11
|
+
To make and run a Java jar:
|
12
|
+
|
13
|
+
$ shortcut build
|
14
|
+
$ java -jar pkg/<%=config[:name]%>.jar
|
15
|
+
|
16
|
+
Or you can simply run:
|
17
|
+
|
18
|
+
$ shortcut run
|
19
|
+
|
20
|
+
## Contributing
|
21
|
+
|
22
|
+
1. Fork it
|
23
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
24
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
25
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
26
|
+
5. Create new Pull Request
|
27
|
+
|
28
|
+
## Credits
|
29
|
+
|
30
|
+
* [Icons](http://www.iconarchive.com/show/soft-scraps-icons-by-deleket/Gear-icon.html)
|
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "shortcut"
|
2
|
+
require "<%=config[:namespaced_path]%>/version"
|
3
|
+
|
4
|
+
import java.awt.Dimension
|
5
|
+
import java.awt.event.KeyEvent
|
6
|
+
import javax.swing.JPanel
|
7
|
+
|
8
|
+
<%- config[:constant_array].each_with_index do |c,i| -%>
|
9
|
+
<%= ' '*i %>module <%= c %>
|
10
|
+
<%- end -%>
|
11
|
+
<%= ' '*config[:constant_array].size %>class Application < Shortcut::Window
|
12
|
+
<%= ' '*config[:constant_array].size %> title <%=config[:constant_name].inspect%>
|
13
|
+
<%= ' '*config[:constant_array].size %> always_on_top true
|
14
|
+
<%= ' '*config[:constant_array].size %> size 440, 250
|
15
|
+
<%= ' '*config[:constant_array].size %> layout BorderLayout
|
16
|
+
|
17
|
+
<%= ' '*config[:constant_array].size %> action 'some_example_action' do
|
18
|
+
<%= ' '*config[:constant_array].size %> display_info("Some example action!")
|
19
|
+
<%= ' '*config[:constant_array].size %> end
|
20
|
+
|
21
|
+
<%= ' '*config[:constant_array].size %> key_pressed KeyEvent::VK_A, 'some_example_action'
|
22
|
+
|
23
|
+
<%= ' '*config[:constant_array].size %> key_pressed KeyEvent::VK_ESCAPE do
|
24
|
+
<%= ' '*config[:constant_array].size %> display_info("Escape key pressed!")
|
25
|
+
<%= ' '*config[:constant_array].size %> end
|
26
|
+
|
27
|
+
<%= ' '*config[:constant_array].size %> key_pressed KeyEvent::VK_C do
|
28
|
+
<%= ' '*config[:constant_array].size %> display_info("This will simulate a click at position 100, 200! (uncomment code for it to work)")
|
29
|
+
<%= ' '*config[:constant_array].size %> # Uncomment the next line for it to work
|
30
|
+
<%= ' '*config[:constant_array].size %> #click(100, 200)
|
31
|
+
<%= ' '*config[:constant_array].size %> end
|
32
|
+
|
33
|
+
<%= ' '*config[:constant_array].size %> def create_components
|
34
|
+
<%= ' '*config[:constant_array].size %> # JPanel
|
35
|
+
<%= ' '*config[:constant_array].size %> panel = JPanel.new()
|
36
|
+
<%= ' '*config[:constant_array].size %> add(panel, BorderLayout::NORTH)
|
37
|
+
|
38
|
+
<%= ' '*config[:constant_array].size %> # Button
|
39
|
+
<%= ' '*config[:constant_array].size %> button = create_button('Some example button', 'some_example_action')
|
40
|
+
<%= ' '*config[:constant_array].size %> panel.add(button)
|
41
|
+
|
42
|
+
<%= ' '*config[:constant_array].size %> # Feedback text area
|
43
|
+
<%= ' '*config[:constant_array].size %> text_area = feedback_text_area("Welcome to <%=config[:constant_name]%>!")
|
44
|
+
<%= ' '*config[:constant_array].size %> scroll_pane = feedback_scroll_panel(text_area, Dimension.new(375, 125))
|
45
|
+
<%= ' '*config[:constant_array].size %> add(scroll_pane, BorderLayout::CENTER)
|
46
|
+
<%= ' '*config[:constant_array].size %> end
|
47
|
+
<%= ' '*config[:constant_array].size %>end
|
48
|
+
<%- (config[:constant_array].size-1).downto(0) do |i| -%>
|
49
|
+
<%= ' '*i %>end
|
50
|
+
<%- end -%>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require './minitest_helper'
|
2
|
+
|
3
|
+
class Test<%= config[:constant_name] %> < MiniTest::Unit::TestCase
|
4
|
+
def test_that_it_has_a_version_number
|
5
|
+
refute_nil ::<%= config[:constant_name] %>::VERSION
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_it_does_something_useful
|
9
|
+
assert false
|
10
|
+
end
|
11
|
+
end
|
data/lib/shortcut/screen.rb
CHANGED
data/lib/shortcut/version.rb
CHANGED
data/lib/shortcut/window.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
require 'java'
|
2
2
|
require 'jar/JNativeHook.jar'
|
3
3
|
|
4
|
+
import java.awt.BorderLayout
|
4
5
|
import java.awt.Color
|
5
6
|
import java.awt.event.ActionListener
|
6
7
|
import java.awt.event.InputEvent
|
7
8
|
import java.awt.event.WindowListener
|
8
9
|
import java.awt.Robot
|
10
|
+
import java.util.ArrayList
|
9
11
|
|
10
12
|
import java.io.ByteArrayInputStream
|
11
13
|
|
14
|
+
import javax.swing.ImageIcon
|
12
15
|
import javax.swing.JButton
|
13
16
|
import javax.swing.JFrame
|
14
17
|
import javax.swing.JScrollPane
|
@@ -81,12 +84,41 @@ module Shortcut
|
|
81
84
|
java.lang.System.getProperty("os.name").downcase
|
82
85
|
end
|
83
86
|
|
87
|
+
def set_window_icons
|
88
|
+
# http://www.iconarchive.com/show/oxygen-icons-by-oxygen-icons.org/Apps-accessories-calculator-icon.html
|
89
|
+
icons = ArrayList.new
|
90
|
+
[16, 32, 64, 128].each do |size|
|
91
|
+
icons.add(self.class.get_image("images/icons/#{size}.png"))
|
92
|
+
end
|
93
|
+
setIconImages(icons)
|
94
|
+
end
|
95
|
+
|
84
96
|
def run
|
97
|
+
setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
|
98
|
+
|
85
99
|
setTitle(respond_to?(:default_title) ? default_title : 'Shortcut App')
|
86
100
|
|
87
101
|
always_on_top if respond_to?(:always_on_top)
|
102
|
+
|
103
|
+
set_window_icons
|
104
|
+
|
105
|
+
if respond_to?(:shortcut_window_size)
|
106
|
+
shortcut_window_size
|
107
|
+
else
|
108
|
+
setSize(440, 250)
|
109
|
+
end
|
110
|
+
|
111
|
+
if respond_to?(:shortcut_window_layout)
|
112
|
+
shortcut_window_layout
|
113
|
+
else
|
114
|
+
setLayout(BorderLayout.new)
|
115
|
+
end
|
116
|
+
|
88
117
|
GlobalScreen.getInstance.addNativeKeyListener(self)
|
89
118
|
addWindowListener(self)
|
119
|
+
|
120
|
+
create_components if respond_to?(:create_components)
|
121
|
+
|
90
122
|
setVisible true
|
91
123
|
end
|
92
124
|
|
@@ -103,6 +135,18 @@ module Shortcut
|
|
103
135
|
end
|
104
136
|
end
|
105
137
|
|
138
|
+
def size(width, height)
|
139
|
+
send :define_method, :shortcut_window_size do
|
140
|
+
setSize(width, height)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def layout(type_class)
|
145
|
+
send :define_method, :shortcut_window_layout do
|
146
|
+
setLayout(type_class.new)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
106
150
|
def key_pressed(code, action = nil, &block)
|
107
151
|
send :define_method, "key_#{code}_pressed".to_sym do
|
108
152
|
if action
|
@@ -120,6 +164,10 @@ module Shortcut
|
|
120
164
|
self.instance_eval(&block)
|
121
165
|
end
|
122
166
|
end
|
167
|
+
|
168
|
+
def get_image(path)
|
169
|
+
ImageIcon.new(path).getImage
|
170
|
+
end
|
123
171
|
end
|
124
172
|
|
125
173
|
[:windowClosing, :windowIconified,
|
data/shortcut.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "shortcut"
|
8
8
|
spec.version = Shortcut::VERSION
|
9
9
|
spec.authors = ["Décio Ferreira"]
|
10
|
-
spec.email = ["
|
10
|
+
spec.email = ["decio.ferreira@decioferreira.com"]
|
11
11
|
spec.description = %q{Make your own Bot}
|
12
12
|
spec.summary = %q{Make your own Bot}
|
13
13
|
spec.homepage = "https://github.com/decioferreira/shortcut"
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
|
-
|
24
|
-
spec.add_development_dependency "warbler"
|
25
23
|
spec.add_development_dependency "guard-rspec"
|
24
|
+
|
25
|
+
spec.add_dependency "warbler"
|
26
26
|
end
|
@@ -6,6 +6,8 @@ require "ostruct"
|
|
6
6
|
import java.awt.Dimension
|
7
7
|
import java.awt.event.KeyEvent
|
8
8
|
|
9
|
+
import javax.swing.BoxLayout
|
10
|
+
|
9
11
|
# https://github.com/jruby/jruby/wiki/Persistence
|
10
12
|
Dimension.__persistent__ = true
|
11
13
|
|
@@ -17,6 +19,14 @@ class AlwaysOnTopTrueClass < Shortcut::Window; always_on_top true; end
|
|
17
19
|
class AlwaysOnTopFalseClass < Shortcut::Window; always_on_top false; end
|
18
20
|
class AlwaysOnTopNoneClass < Shortcut::Window; end
|
19
21
|
|
22
|
+
# Size property
|
23
|
+
class SizeClass < Shortcut::Window; size 100, 200; end
|
24
|
+
class DefaultSizeClass < Shortcut::Window; end
|
25
|
+
|
26
|
+
# Layout property
|
27
|
+
class LayoutClass < Shortcut::Window; layout BoxLayout; end
|
28
|
+
class DefaultLayoutClass < Shortcut::Window; end
|
29
|
+
|
20
30
|
# NativeKeyListener
|
21
31
|
class ListenerExampleClass < Shortcut::Window
|
22
32
|
attr_accessor :called_actions, :key_pressed_events
|
@@ -41,59 +51,59 @@ class ListenerExampleClass < Shortcut::Window
|
|
41
51
|
end
|
42
52
|
|
43
53
|
describe Shortcut::Window do
|
44
|
-
|
54
|
+
subject { Shortcut::Window.new }
|
45
55
|
|
46
56
|
it 'inherits from JFrame' do
|
47
|
-
|
57
|
+
subject.should be_a(JFrame)
|
48
58
|
end
|
49
59
|
|
50
60
|
it 'includes NativeKeyListener' do
|
51
|
-
|
61
|
+
subject.should be_a(NativeKeyListener)
|
52
62
|
end
|
53
63
|
|
54
64
|
it 'includes WindowListener' do
|
55
|
-
|
65
|
+
subject.should be_a(WindowListener)
|
56
66
|
end
|
57
67
|
|
58
68
|
describe :create_button do
|
59
69
|
let(:jbutton) { double('jbutton').as_null_object }
|
60
70
|
|
61
71
|
it 'returns an instance of JButton' do
|
62
|
-
|
72
|
+
subject.create_button('text', 'action').should be_a(JButton)
|
63
73
|
end
|
64
74
|
|
65
75
|
it 'creates a button with text' do
|
66
76
|
JButton.should_receive(:new).with('text').and_return(jbutton)
|
67
|
-
|
77
|
+
subject.create_button('text', anything())
|
68
78
|
end
|
69
79
|
|
70
80
|
it 'creates a button with action' do
|
71
81
|
JButton.should_receive(:new).and_return(jbutton)
|
72
82
|
jbutton.should_receive(:setActionCommand).with('action')
|
73
|
-
|
83
|
+
subject.create_button(anything(), 'action')
|
74
84
|
end
|
75
85
|
|
76
86
|
it 'returns the created button' do
|
77
87
|
JButton.should_receive(:new).and_return(jbutton)
|
78
|
-
|
88
|
+
subject.create_button(anything(), anything()).should eq(jbutton)
|
79
89
|
end
|
80
90
|
|
81
91
|
it 'enables the button by default' do
|
82
92
|
JButton.should_receive(:new).and_return(jbutton)
|
83
93
|
jbutton.should_receive(:setEnabled).with(true)
|
84
|
-
|
94
|
+
subject.create_button(anything(), anything())
|
85
95
|
end
|
86
96
|
|
87
97
|
it 'accepts an enabled option to disable the button' do
|
88
98
|
JButton.should_receive(:new).and_return(jbutton)
|
89
99
|
jbutton.should_receive(:setEnabled).with(false)
|
90
|
-
|
100
|
+
subject.create_button(anything(), anything(), {enabled: false})
|
91
101
|
end
|
92
102
|
|
93
103
|
it 'adds self as action listener' do
|
94
104
|
JButton.should_receive(:new).and_return(jbutton)
|
95
|
-
jbutton.should_receive(:addActionListener).with(
|
96
|
-
|
105
|
+
jbutton.should_receive(:addActionListener).with(subject)
|
106
|
+
subject.create_button(anything(), anything())
|
97
107
|
end
|
98
108
|
end
|
99
109
|
|
@@ -101,18 +111,18 @@ describe Shortcut::Window do
|
|
101
111
|
let(:robot) { double('robot') }
|
102
112
|
|
103
113
|
it 'returns an instance of Robot' do
|
104
|
-
|
114
|
+
subject.robot.should be_a(Robot)
|
105
115
|
end
|
106
116
|
|
107
117
|
it 'creates and returns a Robot' do
|
108
118
|
Robot.should_receive(:new).and_return(robot)
|
109
|
-
|
119
|
+
subject.robot.should eq(robot)
|
110
120
|
end
|
111
121
|
|
112
122
|
it 'caches result' do
|
113
123
|
Robot.should_receive(:new).once.and_return(robot)
|
114
|
-
|
115
|
-
|
124
|
+
subject.robot.should eq(robot)
|
125
|
+
subject.robot.should eq(robot)
|
116
126
|
end
|
117
127
|
end
|
118
128
|
|
@@ -120,14 +130,14 @@ describe Shortcut::Window do
|
|
120
130
|
let(:robot) { double('robot') }
|
121
131
|
|
122
132
|
before(:each) do
|
123
|
-
|
133
|
+
subject.stub(:robot) { robot }
|
124
134
|
end
|
125
135
|
|
126
136
|
it 'moves mouse to correct position, presses and releases left mouse button, all in the correct order' do
|
127
137
|
robot.should_receive(:mouseMove).with(1, 2).ordered
|
128
138
|
robot.should_receive(:mousePress).with(InputEvent::BUTTON1_MASK).ordered
|
129
139
|
robot.should_receive(:mouseRelease).with(InputEvent::BUTTON1_MASK).ordered
|
130
|
-
|
140
|
+
subject.click(1, 2)
|
131
141
|
end
|
132
142
|
end
|
133
143
|
|
@@ -135,37 +145,37 @@ describe Shortcut::Window do
|
|
135
145
|
let(:text_area) { double('text area').as_null_object }
|
136
146
|
|
137
147
|
it 'returns an instance of JTextArea' do
|
138
|
-
|
148
|
+
subject.feedback_text_area.should be_a(JTextArea)
|
139
149
|
end
|
140
150
|
|
141
151
|
it 'sets the text' do
|
142
152
|
JTextArea.should_receive(:new).and_return(text_area)
|
143
153
|
text_area.should_receive(:setText).with('Text')
|
144
|
-
|
154
|
+
subject.feedback_text_area('Text')
|
145
155
|
end
|
146
156
|
|
147
157
|
it 'disables the returned area' do
|
148
158
|
JTextArea.should_receive(:new).and_return(text_area)
|
149
159
|
text_area.should_receive(:setEditable).with(false)
|
150
|
-
|
160
|
+
subject.feedback_text_area
|
151
161
|
end
|
152
162
|
|
153
163
|
it 'sets the background white' do
|
154
164
|
JTextArea.should_receive(:new).and_return(text_area)
|
155
165
|
text_area.should_receive(:setBackground).with(Color::WHITE)
|
156
|
-
|
166
|
+
subject.feedback_text_area
|
157
167
|
end
|
158
168
|
|
159
169
|
it 'sets the foreground black' do
|
160
170
|
JTextArea.should_receive(:new).and_return(text_area)
|
161
171
|
text_area.should_receive(:setForeground).with(Color::BLACK)
|
162
|
-
|
172
|
+
subject.feedback_text_area
|
163
173
|
end
|
164
174
|
|
165
175
|
it 'caches result' do
|
166
176
|
JTextArea.should_receive(:new).once.and_return(text_area)
|
167
|
-
|
168
|
-
|
177
|
+
subject.feedback_text_area.should eq(text_area)
|
178
|
+
subject.feedback_text_area.should eq(text_area)
|
169
179
|
end
|
170
180
|
end
|
171
181
|
|
@@ -174,37 +184,37 @@ describe Shortcut::Window do
|
|
174
184
|
let(:dimension) { Dimension.new }
|
175
185
|
|
176
186
|
it 'returns an instance of JScrollPane' do
|
177
|
-
|
187
|
+
subject.feedback_scroll_panel(text_area, dimension).should be_a(JScrollPane)
|
178
188
|
end
|
179
189
|
|
180
190
|
it 'creates the scroll panel with the text_area argument' do
|
181
191
|
scroll_panel = JScrollPane.new
|
182
192
|
JScrollPane.should_receive(:new).with(text_area).and_return(scroll_panel)
|
183
|
-
|
193
|
+
subject.feedback_scroll_panel(text_area, dimension)
|
184
194
|
end
|
185
195
|
|
186
196
|
it 'sets preferred size' do
|
187
197
|
scroll_panel = JScrollPane.new
|
188
198
|
JScrollPane.should_receive(:new).with(text_area).and_return(scroll_panel)
|
189
199
|
scroll_panel.should_receive(:setPreferredSize).with(dimension)
|
190
|
-
|
200
|
+
subject.feedback_scroll_panel(text_area, dimension)
|
191
201
|
end
|
192
202
|
end
|
193
203
|
|
194
204
|
describe :display_info do
|
195
205
|
it 'append message to feedback text area' do
|
196
|
-
|
197
|
-
|
198
|
-
|
206
|
+
subject.display_info('A')
|
207
|
+
subject.display_info('B')
|
208
|
+
subject.feedback_text_area.getText.should eq("\nA\nB")
|
199
209
|
end
|
200
210
|
|
201
211
|
it 'scrolls down' do
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
212
|
+
subject.display_info('A')
|
213
|
+
subject.feedback_text_area.getCaretPosition.should eq(1)
|
214
|
+
subject.display_info('B')
|
215
|
+
subject.feedback_text_area.getCaretPosition.should eq(3)
|
216
|
+
subject.display_info('C')
|
217
|
+
subject.feedback_text_area.getCaretPosition.should eq(5)
|
208
218
|
end
|
209
219
|
end
|
210
220
|
|
@@ -222,14 +232,46 @@ describe Shortcut::Window do
|
|
222
232
|
ImageIO.should_receive(:createImageInputStream).with(input_stream).and_return(image_input_stream)
|
223
233
|
ImageIO.should_receive(:read).with(image_input_stream).and_return(image)
|
224
234
|
|
225
|
-
|
235
|
+
subject.load_image('path').should eq(image)
|
226
236
|
end
|
227
237
|
end
|
228
238
|
|
229
239
|
describe :operative_system do
|
230
240
|
it 'returns lowercased os.name property' do
|
231
241
|
java.lang.System.should_receive(:getProperty).with("os.name").and_return('Linux')
|
232
|
-
|
242
|
+
subject.operative_system.should eq('linux')
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe :get_image do
|
247
|
+
it 'returns a loaded image' do
|
248
|
+
image = double('image')
|
249
|
+
image_icon = double('image_icon')
|
250
|
+
image_icon.stub(:getImage) { image }
|
251
|
+
ImageIcon.should_receive(:new).with('image_path').and_return(image_icon)
|
252
|
+
Shortcut::Window.get_image('image_path').should be(image)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
describe :set_window_icons do
|
257
|
+
it 'adds 16x16, 32x32, 64x64, 128x128 icons' do
|
258
|
+
image_16, image_32, image_64, image_128 = double('image_16'), double('image_32'), double('image_64'), double('image_128')
|
259
|
+
|
260
|
+
Shortcut::Window.should_receive(:get_image).with('images/icons/16.png').and_return(image_16)
|
261
|
+
Shortcut::Window.should_receive(:get_image).with('images/icons/32.png').and_return(image_32)
|
262
|
+
Shortcut::Window.should_receive(:get_image).with('images/icons/64.png').and_return(image_64)
|
263
|
+
Shortcut::Window.should_receive(:get_image).with('images/icons/128.png').and_return(image_128)
|
264
|
+
|
265
|
+
array_list = double('array_list')
|
266
|
+
array_list.should_receive(:add).with(image_16)
|
267
|
+
array_list.should_receive(:add).with(image_32)
|
268
|
+
array_list.should_receive(:add).with(image_64)
|
269
|
+
array_list.should_receive(:add).with(image_128)
|
270
|
+
|
271
|
+
ArrayList.should_receive(:new).and_return(array_list)
|
272
|
+
subject.should_receive(:setIconImages).with(array_list)
|
273
|
+
|
274
|
+
subject.set_window_icons
|
233
275
|
end
|
234
276
|
end
|
235
277
|
|
@@ -246,12 +288,12 @@ describe Shortcut::Window do
|
|
246
288
|
end
|
247
289
|
|
248
290
|
it 'sets a JFrame default title of "Shortcut App"' do
|
249
|
-
|
250
|
-
|
291
|
+
subject.run
|
292
|
+
subject.getTitle.should eq('Shortcut App')
|
251
293
|
end
|
252
294
|
end
|
253
295
|
|
254
|
-
describe
|
296
|
+
describe :always_on_top do
|
255
297
|
it 'sets property to true' do
|
256
298
|
on_top_true = AlwaysOnTopTrueClass.new
|
257
299
|
on_top_true.should_receive(:setAlwaysOnTop).with(true)
|
@@ -271,43 +313,93 @@ describe Shortcut::Window do
|
|
271
313
|
end
|
272
314
|
end
|
273
315
|
|
316
|
+
describe :size do
|
317
|
+
it 'sets property' do
|
318
|
+
size_window = SizeClass.new
|
319
|
+
size_window.should_receive(:setSize).with(100, 200)
|
320
|
+
size_window.run
|
321
|
+
end
|
322
|
+
|
323
|
+
it 'does not set property and defaults to 440 by 250' do
|
324
|
+
default_size_window = DefaultSizeClass.new
|
325
|
+
default_size_window.should_receive(:setSize).with(440, 250)
|
326
|
+
default_size_window.run
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe :layout do
|
331
|
+
it 'sets property' do
|
332
|
+
box_layout = double("BoxLayout")
|
333
|
+
BoxLayout.should_receive(:new).and_return(box_layout)
|
334
|
+
|
335
|
+
layout_window = LayoutClass.new
|
336
|
+
layout_window.should_receive(:setLayout).with(box_layout)
|
337
|
+
layout_window.run
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'does not set property and defaults to border layout' do
|
341
|
+
border_layout = double("BorderLayout")
|
342
|
+
BorderLayout.should_receive(:new).and_return(border_layout)
|
343
|
+
|
344
|
+
default_layout_window = DefaultLayoutClass.new
|
345
|
+
default_layout_window.should_receive(:setLayout).with(border_layout)
|
346
|
+
default_layout_window.run
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'calls create_components before setting visibility to true' do
|
351
|
+
subject.should_receive(:create_components).ordered
|
352
|
+
subject.should_receive(:setVisible).ordered
|
353
|
+
subject.run
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'calls set_window_icons' do
|
357
|
+
subject.should_receive(:set_window_icons)
|
358
|
+
subject.run
|
359
|
+
end
|
360
|
+
|
361
|
+
it 'sets default close operation to EXIT_ON_CLOSE' do
|
362
|
+
subject.should_receive(:setDefaultCloseOperation).with(JFrame::EXIT_ON_CLOSE)
|
363
|
+
subject.run
|
364
|
+
end
|
365
|
+
|
274
366
|
it 'adds a window listener' do
|
275
|
-
|
276
|
-
|
367
|
+
subject.should_receive(:addWindowListener).with(subject)
|
368
|
+
subject.run
|
277
369
|
end
|
278
370
|
|
279
371
|
it 'adds a native key listener' do
|
280
|
-
GlobalScreen.getInstance.should_receive(:addNativeKeyListener).with(
|
281
|
-
|
372
|
+
GlobalScreen.getInstance.should_receive(:addNativeKeyListener).with(subject)
|
373
|
+
subject.run
|
282
374
|
end
|
283
375
|
|
284
376
|
it 'sets visibility to true' do
|
285
|
-
|
286
|
-
|
377
|
+
subject.should_receive(:setVisible).with(true)
|
378
|
+
subject.run
|
287
379
|
end
|
288
380
|
end
|
289
381
|
|
290
382
|
describe 'window listeners' do
|
291
383
|
[:windowOpened, :windowClosed, :windowClosing, :windowIconified,
|
292
384
|
:windowDeiconified, :windowActivated, :windowDeactivated].each do |event|
|
293
|
-
it {
|
385
|
+
it { subject.should respond_to(event).with(1).argument }
|
294
386
|
end
|
295
387
|
|
296
388
|
describe :windowOpened do
|
297
389
|
it 'requests focus in window' do
|
298
|
-
|
299
|
-
|
390
|
+
subject.should_receive(:requestFocusInWindow)
|
391
|
+
subject.windowOpened(anything())
|
300
392
|
end
|
301
393
|
|
302
394
|
it 'registers native hook' do
|
303
395
|
GlobalScreen.should_receive(:registerNativeHook)
|
304
|
-
|
396
|
+
subject.windowOpened(anything())
|
305
397
|
end
|
306
398
|
|
307
399
|
it 'handles exception when registering native hook' do
|
308
400
|
GlobalScreen.should_receive(:registerNativeHook).and_raise(NativeHookException.new('error message!'))
|
309
|
-
|
310
|
-
|
401
|
+
subject.should_receive(:display_info).with('org.jnativehook.NativeHookException: error message!')
|
402
|
+
subject.windowOpened(anything())
|
311
403
|
end
|
312
404
|
end
|
313
405
|
|
@@ -318,24 +410,24 @@ describe Shortcut::Window do
|
|
318
410
|
|
319
411
|
it 'unregisters native hook' do
|
320
412
|
GlobalScreen.should_receive(:unregisterNativeHook)
|
321
|
-
|
413
|
+
subject.windowClosed(anything())
|
322
414
|
end
|
323
415
|
|
324
416
|
it 'runs system finalization' do
|
325
417
|
java.lang.System.should_receive(:runFinalization)
|
326
|
-
|
418
|
+
subject.windowClosed(anything())
|
327
419
|
end
|
328
420
|
|
329
421
|
it 'exit system with value 0' do
|
330
422
|
java.lang.System.should_receive(:exit).with(0)
|
331
|
-
|
423
|
+
subject.windowClosed(anything())
|
332
424
|
end
|
333
425
|
end
|
334
426
|
end
|
335
427
|
|
336
428
|
describe 'native key listeners' do
|
337
429
|
[:nativeKeyReleased, :nativeKeyTyped, :nativeKeyPressed].each do |event|
|
338
|
-
it {
|
430
|
+
it { subject.should respond_to(event).with(1).argument }
|
339
431
|
end
|
340
432
|
|
341
433
|
describe :nativeKeyPressed do
|
@@ -374,7 +466,7 @@ describe Shortcut::Window do
|
|
374
466
|
end
|
375
467
|
|
376
468
|
describe :actionPerformed do
|
377
|
-
it {
|
469
|
+
it { subject.should respond_to(:actionPerformed).with(1).argument }
|
378
470
|
|
379
471
|
it 'executes block from action function' do
|
380
472
|
action_event = OpenStruct.new(getActionCommand: 'some_action')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shortcut
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,19 +9,19 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
16
|
version_requirements: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '1.3'
|
21
21
|
none: false
|
22
22
|
requirement: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
none: false
|
@@ -31,73 +31,91 @@ dependencies:
|
|
31
31
|
name: rake
|
32
32
|
version_requirements: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
|
-
- -
|
34
|
+
- - '>='
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version:
|
37
|
-
MA==
|
36
|
+
version: '0'
|
38
37
|
none: false
|
39
38
|
requirement: !ruby/object:Gem::Requirement
|
40
39
|
requirements:
|
41
|
-
- -
|
40
|
+
- - '>='
|
42
41
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
44
|
-
MA==
|
42
|
+
version: '0'
|
45
43
|
none: false
|
46
44
|
prerelease: false
|
47
45
|
type: :development
|
48
46
|
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
47
|
+
name: guard-rspec
|
50
48
|
version_requirements: !ruby/object:Gem::Requirement
|
51
49
|
requirements:
|
52
|
-
- -
|
50
|
+
- - '>='
|
53
51
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
MA==
|
52
|
+
version: '0'
|
56
53
|
none: false
|
57
54
|
requirement: !ruby/object:Gem::Requirement
|
58
55
|
requirements:
|
59
|
-
- -
|
56
|
+
- - '>='
|
60
57
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
MA==
|
58
|
+
version: '0'
|
63
59
|
none: false
|
64
60
|
prerelease: false
|
65
61
|
type: :development
|
66
62
|
- !ruby/object:Gem::Dependency
|
67
|
-
name:
|
63
|
+
name: warbler
|
68
64
|
version_requirements: !ruby/object:Gem::Requirement
|
69
65
|
requirements:
|
70
|
-
- -
|
66
|
+
- - '>='
|
71
67
|
- !ruby/object:Gem::Version
|
72
|
-
version:
|
73
|
-
MA==
|
68
|
+
version: '0'
|
74
69
|
none: false
|
75
70
|
requirement: !ruby/object:Gem::Requirement
|
76
71
|
requirements:
|
77
|
-
- -
|
72
|
+
- - '>='
|
78
73
|
- !ruby/object:Gem::Version
|
79
|
-
version:
|
80
|
-
MA==
|
74
|
+
version: '0'
|
81
75
|
none: false
|
82
76
|
prerelease: false
|
83
|
-
type: :
|
77
|
+
type: :runtime
|
84
78
|
description: Make your own Bot
|
85
79
|
email:
|
86
|
-
-
|
87
|
-
executables:
|
80
|
+
- decio.ferreira@decioferreira.com
|
81
|
+
executables:
|
82
|
+
- shortcut
|
88
83
|
extensions: []
|
89
84
|
extra_rdoc_files: []
|
90
85
|
files:
|
91
|
-
-
|
92
|
-
-
|
93
|
-
-
|
86
|
+
- .gitignore
|
87
|
+
- .rspec
|
88
|
+
- .ruby-version
|
94
89
|
- Gemfile
|
95
90
|
- Guardfile
|
96
91
|
- LICENSE.txt
|
97
92
|
- README.md
|
98
93
|
- Rakefile
|
94
|
+
- bin/shortcut
|
99
95
|
- lib/jar/JNativeHook.jar
|
96
|
+
- lib/keep_running.rb
|
100
97
|
- lib/shortcut.rb
|
98
|
+
- lib/shortcut/application.rb
|
99
|
+
- lib/shortcut/application_tasks/new.rb
|
100
|
+
- lib/shortcut/application_tasks/templates/.travis.yml.tt
|
101
|
+
- lib/shortcut/application_tasks/templates/Gemfile.tt
|
102
|
+
- lib/shortcut/application_tasks/templates/LICENSE.txt.tt
|
103
|
+
- lib/shortcut/application_tasks/templates/README.md.tt
|
104
|
+
- lib/shortcut/application_tasks/templates/Rakefile.tt
|
105
|
+
- lib/shortcut/application_tasks/templates/bin/newgem.tt
|
106
|
+
- lib/shortcut/application_tasks/templates/config/launch4j.xml.tt
|
107
|
+
- lib/shortcut/application_tasks/templates/gitignore.tt
|
108
|
+
- lib/shortcut/application_tasks/templates/images/icons/128.png
|
109
|
+
- lib/shortcut/application_tasks/templates/images/icons/16.png
|
110
|
+
- lib/shortcut/application_tasks/templates/images/icons/32.png
|
111
|
+
- lib/shortcut/application_tasks/templates/images/icons/64.png
|
112
|
+
- lib/shortcut/application_tasks/templates/lib/newgem.rb.tt
|
113
|
+
- lib/shortcut/application_tasks/templates/lib/newgem/version.rb.tt
|
114
|
+
- lib/shortcut/application_tasks/templates/rspec.tt
|
115
|
+
- lib/shortcut/application_tasks/templates/spec/newgem_spec.rb.tt
|
116
|
+
- lib/shortcut/application_tasks/templates/spec/spec_helper.rb.tt
|
117
|
+
- lib/shortcut/application_tasks/templates/test/minitest_helper.rb.tt
|
118
|
+
- lib/shortcut/application_tasks/templates/test/test_newgem.rb.tt
|
101
119
|
- lib/shortcut/errors.rb
|
102
120
|
- lib/shortcut/point.rb
|
103
121
|
- lib/shortcut/screen.rb
|
@@ -116,22 +134,20 @@ require_paths:
|
|
116
134
|
- lib
|
117
135
|
required_ruby_version: !ruby/object:Gem::Requirement
|
118
136
|
requirements:
|
119
|
-
- -
|
137
|
+
- - '>='
|
120
138
|
- !ruby/object:Gem::Version
|
121
139
|
segments:
|
122
140
|
- 0
|
123
|
-
version:
|
124
|
-
MA==
|
141
|
+
version: '0'
|
125
142
|
hash: 2
|
126
143
|
none: false
|
127
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
145
|
requirements:
|
129
|
-
- -
|
146
|
+
- - '>='
|
130
147
|
- !ruby/object:Gem::Version
|
131
148
|
segments:
|
132
149
|
- 0
|
133
|
-
version:
|
134
|
-
MA==
|
150
|
+
version: '0'
|
135
151
|
hash: 2
|
136
152
|
none: false
|
137
153
|
requirements: []
|