funfx 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +18 -0
- data/License.txt +20 -0
- data/Manifest.txt +87 -0
- data/README.txt +48 -0
- data/Rakefile +5 -0
- data/config/hoe.rb +67 -0
- data/config/requirements.rb +15 -0
- data/ext/FunFX.swc +0 -0
- data/lib/funfx.rb +34 -0
- data/lib/funfx/browser/firewatir.rb +47 -0
- data/lib/funfx/browser/flex_app_lookup.rb +22 -0
- data/lib/funfx/browser/safariwatir.rb +47 -0
- data/lib/funfx/browser/watir.rb +41 -0
- data/lib/funfx/decoder.rb +67 -0
- data/lib/funfx/flex/element.rb +161 -0
- data/lib/funfx/flex/elements.rb +2712 -0
- data/lib/funfx/flex/flex_app_id.rb +15 -0
- data/lib/funfx/flex/tabular_data.rb +22 -0
- data/lib/funfx/meta/class_dot.erb +24 -0
- data/lib/funfx/meta/code.erb +33 -0
- data/lib/funfx/meta/generator.rb +18 -0
- data/lib/funfx/meta/parser.rb +190 -0
- data/lib/funfx/version.rb +9 -0
- data/rake_tasks/deployment.rake +34 -0
- data/rake_tasks/environment.rake +7 -0
- data/rake_tasks/generation.rake +37 -0
- data/rake_tasks/hoe_ext.rake +11 -0
- data/rake_tasks/rspec.rake +28 -0
- data/script/console +10 -0
- data/script/console.cmd +1 -0
- data/script/destroy +14 -0
- data/script/destroy.cmd +1 -0
- data/script/generate +14 -0
- data/script/generate.cmd +1 -0
- data/script/txt2html +82 -0
- data/script/txt2html.cmd +1 -0
- data/setup.rb +1585 -0
- data/spec/funfx/demo_app/accordion_spec.rb +38 -0
- data/spec/funfx/demo_app/advanced_data_grid_spec.rb +74 -0
- data/spec/funfx/demo_app/alert_spec.rb +33 -0
- data/spec/funfx/demo_app/button_bar_spec.rb +21 -0
- data/spec/funfx/demo_app/button_spec.rb +68 -0
- data/spec/funfx/demo_app/check_box_spec.rb +62 -0
- data/spec/funfx/demo_app/control_bar_spec.rb +19 -0
- data/spec/funfx/demo_app/controls_with_same_id_spec.rb +37 -0
- data/spec/funfx/demo_app/data_grid_editable_spec.rb +78 -0
- data/spec/funfx/demo_app/data_grid_spec.rb +65 -0
- data/spec/funfx/demo_app/date_chooser_spec.rb +67 -0
- data/spec/funfx/demo_app/date_field_spec.rb +36 -0
- data/spec/funfx/demo_app/form_spec.rb +22 -0
- data/spec/funfx/demo_app/grid_layout_spec.rb +23 -0
- data/spec/funfx/demo_app/h_scrollbar_spec.rb +25 -0
- data/spec/funfx/demo_app/h_slider_spec.rb +21 -0
- data/spec/funfx/demo_app/horizontal_list_spec.rb +24 -0
- data/spec/funfx/demo_app/label_spec.rb +18 -0
- data/spec/funfx/demo_app/link_bar_spec.rb +57 -0
- data/spec/funfx/demo_app/link_button_spec.rb +21 -0
- data/spec/funfx/demo_app/list_spec.rb +23 -0
- data/spec/funfx/demo_app/menu_bar_spec.rb +33 -0
- data/spec/funfx/demo_app/menu_spec.rb +27 -0
- data/spec/funfx/demo_app/numeric_stepper_spec.rb +37 -0
- data/spec/funfx/demo_app/popup_button_spec.rb +36 -0
- data/spec/funfx/demo_app/popup_menu_bar_spec.rb +42 -0
- data/spec/funfx/demo_app/progress_bar_spec.rb +24 -0
- data/spec/funfx/demo_app/radio_button_group_spec.rb +50 -0
- data/spec/funfx/demo_app/radio_button_spec.rb +26 -0
- data/spec/funfx/demo_app/record_test_spec.rb +20 -0
- data/spec/funfx/demo_app/repeater_control_spec.rb +65 -0
- data/spec/funfx/demo_app/tab_bar_spec.rb +19 -0
- data/spec/funfx/demo_app/tab_navigator_spec.rb +19 -0
- data/spec/funfx/demo_app/test_spec.rb +19 -0
- data/spec/funfx/demo_app/text_area_spec.rb +28 -0
- data/spec/funfx/demo_app/text_input_spec.rb +28 -0
- data/spec/funfx/demo_app/text_spec.rb +18 -0
- data/spec/funfx/demo_app/tile_button_spec.rb +20 -0
- data/spec/funfx/demo_app/tile_list_spec.rb +25 -0
- data/spec/funfx/demo_app/title_window_spec.rb +40 -0
- data/spec/funfx/demo_app/toggle_button_spec.rb +19 -0
- data/spec/funfx/demo_app/tree_drag_and_drop_spec.rb +39 -0
- data/spec/funfx/demo_app/tree_spec.rb +24 -0
- data/spec/funfx/demo_app/view_stack_spec.rb +27 -0
- data/spec/funfx/flex/element_spec.rb +115 -0
- data/spec/funfx/flex/flex_app_id_spec.rb +40 -0
- data/spec/funfx/meta/generator_spec.rb +16 -0
- data/spec/funfx/meta/parser_spec.rb +88 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +41 -0
- metadata +166 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
module FunFX
|
2
|
+
module Flex
|
3
|
+
module FlexAppId #:nodoc:
|
4
|
+
def full_id(flex_id)
|
5
|
+
full_id = (instance_variable_defined?(:@id_prefix)) ? "#{@id_prefix}|" : ""
|
6
|
+
full_id += flex_id
|
7
|
+
end
|
8
|
+
|
9
|
+
def automation_id(flex_id)
|
10
|
+
full_flex_id = full_id(flex_id)
|
11
|
+
"{automationID: '#{full_flex_id}'}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module FunFX
|
2
|
+
module Flex
|
3
|
+
module TabularData
|
4
|
+
def column_names
|
5
|
+
get_tabular_property_value("columnNames", Table).first
|
6
|
+
end
|
7
|
+
|
8
|
+
def values(start_index, end_index)
|
9
|
+
invoke_tabular_method("getValues", Table, start_index, end_index)
|
10
|
+
end
|
11
|
+
|
12
|
+
def num_columns
|
13
|
+
get_tabular_property_value("numColumns", Integer)
|
14
|
+
end
|
15
|
+
|
16
|
+
def num_rows
|
17
|
+
get_tabular_property_value("numRows", Integer)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
digraph G {
|
2
|
+
rankdir = BT;
|
3
|
+
|
4
|
+
fontname = "Bitstream Vera Sans"
|
5
|
+
fontsize = 8
|
6
|
+
|
7
|
+
node [
|
8
|
+
fontname = "Bitstream Vera Sans"
|
9
|
+
fontsize = 8
|
10
|
+
shape = "record"
|
11
|
+
]
|
12
|
+
|
13
|
+
edge [
|
14
|
+
fontname = "Bitstream Vera Sans"
|
15
|
+
fontsize = 8
|
16
|
+
]
|
17
|
+
|
18
|
+
<% classes.each do |klass| %>
|
19
|
+
<%= klass.name %> [
|
20
|
+
label = "{<%= klass.name %>|<%= klass.dot_property_list %>|<%= klass.dot_event_list %>}"
|
21
|
+
]
|
22
|
+
<% if klass.superclass_name %><%= klass.name %> -> <%= klass.superclass_name %><% end %>
|
23
|
+
<% end %>
|
24
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'funfx'
|
2
|
+
require 'funfx/flex/element'
|
3
|
+
require 'funfx/flex/tabular_data'
|
4
|
+
|
5
|
+
module FunFX
|
6
|
+
module Flex
|
7
|
+
module Elements
|
8
|
+
<% classes.each do |klass| -%>
|
9
|
+
|
10
|
+
class <%= klass.name %> < <%= klass.superclass_name || 'Element' %>
|
11
|
+
<% if klass.tabular? -%>
|
12
|
+
include TabularData
|
13
|
+
<% end -%>
|
14
|
+
<% klass.properties.each do |property| -%>
|
15
|
+
|
16
|
+
def <%= property.ruby_name %>
|
17
|
+
get_property_value('<%= property.name %>', <%= property.ruby_type %>)
|
18
|
+
end
|
19
|
+
<% end -%>
|
20
|
+
<% klass.events.each do |event| -%>
|
21
|
+
def <%= event.to_method %>
|
22
|
+
fire_event(<%= event.arg_list("'#{event.name}'") %>)
|
23
|
+
end
|
24
|
+
<% end -%>
|
25
|
+
end
|
26
|
+
|
27
|
+
def <%= klass.lookup_method %>(*locator_hash)
|
28
|
+
<%= klass.name %>.new(self, nil, *locator_hash)
|
29
|
+
end
|
30
|
+
<% end -%>
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'funfx/meta/parser'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module FunFX
|
5
|
+
module Meta
|
6
|
+
class Generator
|
7
|
+
def initialize(classes, template_name)
|
8
|
+
@classes, @template_name = classes, template_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate
|
12
|
+
template = ERB.new(IO.read(File.dirname(__FILE__) + "/#{@template_name}.erb"), nil, '-<>')
|
13
|
+
classes = @classes
|
14
|
+
template.result(binding)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'funfx/decoder'
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'libxml'
|
5
|
+
rescue LoadError
|
6
|
+
STDERR.puts "LibXML not installed. gem install libxml-ruby"
|
7
|
+
end
|
8
|
+
begin
|
9
|
+
require 'active_support'
|
10
|
+
rescue LoadError
|
11
|
+
STDERR.puts "activesupport not installed. gem install activesupport"
|
12
|
+
end
|
13
|
+
|
14
|
+
module FunFX
|
15
|
+
module Meta
|
16
|
+
class ClassLib
|
17
|
+
META_API = File.dirname(__FILE__) + '/../../../../flex/src/AutoQuickEnv.xml'
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@lib = Hash.new(MetaClass.new)
|
21
|
+
|
22
|
+
doc = LibXML::XML::Document.file(META_API)
|
23
|
+
doc.find('/TypeInformation/ClassInfo').map do |class_info|
|
24
|
+
klass = FlexMetaClass.new(class_info)
|
25
|
+
@lib[klass.name] = klass
|
26
|
+
end
|
27
|
+
|
28
|
+
@lib.values.each do |c|
|
29
|
+
c.link_with(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
@classes = []
|
33
|
+
object.add_children_recursive(@classes)
|
34
|
+
end
|
35
|
+
|
36
|
+
def [](name)
|
37
|
+
@lib[name]
|
38
|
+
end
|
39
|
+
|
40
|
+
def object
|
41
|
+
self[nil]
|
42
|
+
end
|
43
|
+
|
44
|
+
def classes(names = nil)
|
45
|
+
return @classes if names.nil?
|
46
|
+
return @classes.select{|c| names.index(c.name)}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class MetaClass
|
51
|
+
attr_reader :children
|
52
|
+
|
53
|
+
def initialize
|
54
|
+
@children = []
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_children_recursive(a)
|
58
|
+
@children.each do |c|
|
59
|
+
a << c
|
60
|
+
c.add_children_recursive(a)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class FlexMetaClass < MetaClass
|
66
|
+
def initialize(class_info)
|
67
|
+
super()
|
68
|
+
@class_info = class_info
|
69
|
+
end
|
70
|
+
|
71
|
+
def link_with(lib)
|
72
|
+
s = lib[superclass_name]
|
73
|
+
unless s.nil?
|
74
|
+
@superclass = s
|
75
|
+
@superclass.children << self
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def name
|
80
|
+
@class_info['Name']
|
81
|
+
end
|
82
|
+
|
83
|
+
def superclass_name
|
84
|
+
@class_info['Extends']
|
85
|
+
end
|
86
|
+
|
87
|
+
def properties
|
88
|
+
@class_info.find('Properties/Property').map do |property|
|
89
|
+
['columnNames'].include?(property['Name']) ? nil : Property.new(property, false)
|
90
|
+
end.compact
|
91
|
+
end
|
92
|
+
|
93
|
+
def events
|
94
|
+
@class_info.find('Events/Event').map do |event|
|
95
|
+
Event.new(event)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def tabular?
|
100
|
+
@class_info['SupportsTabularData'] == 'true'
|
101
|
+
end
|
102
|
+
|
103
|
+
def dot_property_list
|
104
|
+
l = properties.map{|p| p.to_dot}.join('\l')
|
105
|
+
l == "" ? l : "#{l}\\l"
|
106
|
+
end
|
107
|
+
|
108
|
+
def dot_event_list
|
109
|
+
l = events.map{|e| e.to_method.gsub(/"/, '\"')}.join('\l')
|
110
|
+
l == "" ? l : "#{l}\\l"
|
111
|
+
end
|
112
|
+
|
113
|
+
def lookup_method
|
114
|
+
name.underscore.gsub(/^flex_/, '')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class Property
|
119
|
+
def initialize(property, param)
|
120
|
+
@property, @param = property, param
|
121
|
+
end
|
122
|
+
|
123
|
+
def name
|
124
|
+
@property['Name']
|
125
|
+
end
|
126
|
+
|
127
|
+
def ruby_name
|
128
|
+
if @param
|
129
|
+
name.underscore
|
130
|
+
else
|
131
|
+
name.underscore + (ruby_type == TrueClass ? '?' : '')
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def ruby_type
|
136
|
+
type = @property.find('PropertyType').first['Type'].underscore.to_sym
|
137
|
+
Decoder.convert_type(type)
|
138
|
+
end
|
139
|
+
|
140
|
+
def default_value
|
141
|
+
default = @property['DefaultValue']
|
142
|
+
return nil if default.nil?
|
143
|
+
ruby_type.from_funfx_string(default)
|
144
|
+
end
|
145
|
+
|
146
|
+
def to_dot
|
147
|
+
"#{ruby_name} : #{ruby_type.name}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def to_arg
|
151
|
+
(default_value ? "#{ruby_name}=#{default_value.inspect}" : ruby_name)
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
class Event
|
157
|
+
def initialize(event)
|
158
|
+
@event = event
|
159
|
+
end
|
160
|
+
|
161
|
+
def name
|
162
|
+
@event['Name']
|
163
|
+
end
|
164
|
+
|
165
|
+
def ruby_name
|
166
|
+
name.underscore
|
167
|
+
end
|
168
|
+
|
169
|
+
def args
|
170
|
+
@event.find('Property').map do |property|
|
171
|
+
Property.new(property, true)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def arg_list(pre)
|
176
|
+
a = args.map{|arg| arg.ruby_name}
|
177
|
+
([pre] + a).flatten.join(", ")
|
178
|
+
end
|
179
|
+
|
180
|
+
def arg_list_with_defaults
|
181
|
+
args.map{|arg| arg.to_arg}.join(", ")
|
182
|
+
end
|
183
|
+
|
184
|
+
def to_method
|
185
|
+
arg_list = args.map{|a| a.to_arg}.join(", ")
|
186
|
+
"#{ruby_name}(#{arg_list})"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
desc 'Release the website and new gem version'
|
2
|
+
task :deploy => [:check_version, :website, :release] do
|
3
|
+
puts "Remember to create SVN tag:"
|
4
|
+
puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
|
5
|
+
"svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
|
6
|
+
puts "Suggested comment:"
|
7
|
+
puts "Tagging release #{CHANGES}"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
|
11
|
+
task :local_deploy => [:website_generate, :install_gem]
|
12
|
+
|
13
|
+
task :check_version do
|
14
|
+
unless ENV['VERSION']
|
15
|
+
puts 'Must pass a VERSION=x.y.z release version'
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
unless ENV['VERSION'] == VERS
|
19
|
+
puts "Please update your version.rb to match the release version, currently #{VERS}"
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
|
25
|
+
task :install_gem_no_doc => [:clean, :package] do
|
26
|
+
sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
|
27
|
+
end
|
28
|
+
|
29
|
+
namespace :manifest do
|
30
|
+
desc 'Recreate Manifest.txt to include ALL files'
|
31
|
+
task :refresh do
|
32
|
+
`rake check_manifest | patch -p0 > Manifest.txt`
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
namespace :generate do
|
2
|
+
desc "Generate class diagrams"
|
3
|
+
task :diagrams do
|
4
|
+
require 'funfx/meta/generator'
|
5
|
+
require 'funfx/meta/parser'
|
6
|
+
|
7
|
+
diagrams = {
|
8
|
+
:all => nil,
|
9
|
+
:first => %w{FlexMenuBar FlexLabel FlexObject},
|
10
|
+
:second => %w{FlexButton FlexRadioButton FlexPopUpButton FlexCheckBox FlexDateChooser FlexSlider},
|
11
|
+
:third => %w{FlexLabel FlexProgressBar FlexNumericStepper FlexLoader FlexRule FlexVideoDisplay},
|
12
|
+
}
|
13
|
+
|
14
|
+
lib = FunFX::Meta::ClassLib.new
|
15
|
+
diagrams.each do |file, names|
|
16
|
+
classes = lib.classes(names)
|
17
|
+
generator = FunFX::Meta::Generator.new(classes, :class_dot)
|
18
|
+
dot = "website/diagrams/#{file}.dot"
|
19
|
+
pdf = "website/diagrams/#{file}.pdf"
|
20
|
+
File.open(dot, 'wb') {|io| io.write generator.generate}
|
21
|
+
sh "dot -T pdf -o #{pdf} #{dot}"
|
22
|
+
rm dot
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Generate code"
|
27
|
+
task :code do
|
28
|
+
require 'funfx/meta/generator'
|
29
|
+
require 'funfx/meta/parser'
|
30
|
+
|
31
|
+
lib = FunFX::Meta::ClassLib.new
|
32
|
+
classes = lib.classes
|
33
|
+
generator = FunFX::Meta::Generator.new(classes, :code)
|
34
|
+
code = 'lib/funfx/flex/elements.rb'
|
35
|
+
File.open(code, 'wb') {|io| io.write generator.generate}
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
namespace :spec do
|
5
|
+
desc "Run the API specs"
|
6
|
+
Spec::Rake::SpecTask.new(:api) do |t|
|
7
|
+
t.rcov = true
|
8
|
+
t.rcov_opts = ["--exclude gems,spec"]
|
9
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
10
|
+
t.spec_files = FileList['spec/funfx/flex/**/*_spec.rb']
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Run the meta specs (code generation)"
|
14
|
+
Spec::Rake::SpecTask.new(:meta) do |t|
|
15
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
16
|
+
t.spec_files = FileList['spec/funfx/meta/**/*_spec.rb']
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Run the Demo App specs"
|
20
|
+
Spec::Rake::SpecTask.new(:demo_app) do |t|
|
21
|
+
t.rcov = true
|
22
|
+
t.rcov_opts = ["--exclude gems,spec"]
|
23
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
24
|
+
t.spec_files = FileList['spec/funfx/demo_app/**/*_spec.rb']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
task :spec => ['spec:api', 'spec:meta', 'spec:demo_app']
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/funfx.rb'}"
|
9
|
+
puts "Loading funfx gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|