Brett Giles avatar Brett Giles committed b486f14 Merge

Merge branch 'develop' into feature/PrepForRspecMonkeybarsBlog

Comments (0)

Files changed (58)

GUI/.rvmrc

-rvm --create use jruby@lqplfe
   gem "rspec"
   gem "cucumber"
   gem 'simplecov'
+  gem 'flog'
+  gem 'flay'
 end
 
Add a comment to this file

GUI/devlib/java/fest-assert-1.2.jar

Binary file added.

Add a comment to this file

GUI/devlib/java/fest-reflect-1.2.jar

Binary file added.

Add a comment to this file

GUI/devlib/java/fest-swing-1.2.jar

Binary file added.

Add a comment to this file

GUI/devlib/java/fest-util-1.1.2.jar

Binary file added.

Add a comment to this file

GUI/devlib/java/jcip-annotations-1.0.jar

Binary file added.

Add a comment to this file

GUI/devlib/java/jemmy-2.3.0.0.jar

Binary file removed.

Add a comment to this file

GUI/lib/java/monkeybars-1.1.1.jar

Binary file modified.

GUI/spec/controller/classical_stack_controller_spec.rb

     @c = ClassicalStackController.instance
   end
   it "should raise an error when created with junk" do
-    expect { @c.set_classical_stack_data("junk")}. to raise_error   QuantumStackModelInvalidCreate, /junk/
+    expect { @c.set_classical_stack_data("junk")}. to raise_error   ModelCreateError, /junk/
   end
 
   it "should create a classical stack when given the correct input" do

GUI/spec/model/classical_stack_model_spec.rb

     expect {
       c=ClassicalStackModel.new
       c.classical_stack = "junk"
-    }.to raise_error  QuantumStackModelInvalidCreate, /junk/
+    }.to raise_error  ModelCreateError, /junk/
   end
   it "should set the text to each item with line returns" do
     c=ClassicalStackModel.new

GUI/spec/model/descriptor_model_spec.rb

   it "should only be created by the factory" do
     expect {
       sd = AbstractDescriptorModel.new
-    }.to raise_error(StackDescriptorModelInvalidCreate)
+    }.to raise_error(ModelCreateError)
   end
   it "should create an instance of ZeroDescriptorModel when created with  <Zero/>" do
     sd = AbstractDescriptorModel.make_instance "<Zero/>"
   it "should raise an error when the input string to the factory doesn't start with one of <Zero, <Value, <Class, <Qubi, or <Alge" do
     expect {
       sd = AbstractDescriptorModel.make_instance "somethng"
-    }.to  raise_error(StackDescriptorModelInvalidCreate)
+    }.to  raise_error(ModelCreateError)
     expect {
       sd = AbstractDescriptorModel.make_instance "ab<Zero/>"
-    }.to  raise_error(StackDescriptorModelInvalidCreate)
+    }.to  raise_error(ModelCreateError)
     expect {
       sd = AbstractDescriptorModel.make_instance "<Alg<Qubit>"
-    }.to  raise_error(StackDescriptorModelInvalidCreate)
+    }.to  raise_error(ModelCreateError)
   end
   it "should embed the incorrect value when raising a create exception" do
     expect {
       sd = AbstractDescriptorModel.make_instance "somethng"
-    }.to  raise_error(StackDescriptorModelInvalidCreate, /somethng/)
+    }.to  raise_error(ModelCreateError, /somethng/)
   end
 
 
   it  "should raise an error if constructed with something other than <ClassicalStack>list of ints or bools</ClassicalStack>" do
     expect {
       sc = AbstractDescriptorModel.make_instance "<ClassicalStack>err</ClassicalStack>"
-    }.to raise_error(StackDescriptorModelInvalidCreate, "<ClassicalStack>err</ClassicalStack>")
+    }.to raise_error(ModelCreateError, /<ClassicalStack>err<\/ClassicalStack>/)
   end
   it  "should have a length equal to the number of elements of the passed in list" do
     sd = AbstractDescriptorModel.make_instance "<ClassicalStack><cint>14</cint></ClassicalStack>"
     it "should raise an error when the list is invalid" do
       expect {
         ClassicalDescriptorModel::parse_list("invalid")
-      }.to raise_error(StackDescriptorModelInvalidCreate, "invalid")
+      }.to raise_error(ModelCreateError, "invalid")
     end
     it "should prepare a list of length 0 when there is no list" do
       ClassicalDescriptorModel::parse_list("").should == []
   it  "should raise an error if constructed with something other than <AlgebraicData>list of z,o pairs</AlgebraicData>" do
     expect {
       sc = AbstractDescriptorModel.make_instance "<AlgebraicData>err</AlgebraicData>"
-    }.to raise_error(StackDescriptorModelInvalidCreate, "<AlgebraicData>err</AlgebraicData>")
+    }.to raise_error(ModelCreateError, /<AlgebraicData>err<\/AlgebraicData>/)
   end
   it  "should have a length equal to the number of elements of the passed in list" do
     sd = AbstractDescriptorModel.make_instance "<AlgebraicData><string>Nil</string><StackAddresses></StackAddresses></AlgebraicData>"
   it  "should raise an error if constructed with something other than <Qubits>list of z,o pairs</Qubits>" do
     expect {
       sc = AbstractDescriptorModel.make_instance "<Qubits>err</Qubits>"
-    }.to raise_error(StackDescriptorModelInvalidCreate, "<Qubits>err</Qubits>")
+    }.to raise_error(ModelCreateError, /<Qubits>err<\/Qubits>/)
   end
   it  "should have a length equal to the number of elements of the passed in list" do
     sd = AbstractDescriptorModel.make_instance "<Qubits><pair><qz/><qz/></pair></Qubits>"
   it "should raise an error if constructed with something other than <Zero/>" do
     expect {
       sd = AbstractDescriptorModel.make_instance "<Zero>"
-    }.to raise_error(StackDescriptorModelInvalidCreate, "<Zero>")
+    }.to raise_error(ModelCreateError, /<Zero>/)
     expect {
       sd = ZeroDescriptorModel.new "wrong"
-    }.to raise_error(StackDescriptorModelInvalidCreate, "wrong")
+    }.to raise_error(ModelCreateError, /wrong/)
   end
   it "should have no name" do
     sd = AbstractDescriptorModel.make_instance "<Zero/>"

GUI/src/application_model.rb

+class ModelCreateError < RuntimeError 
+end
+
+class ApplicationModel
+end

GUI/src/com/drogar/lqpl/about/AboutDialog.java

     }
 
     private void onOK() {
-// add your code here
         dispose();
     }
 
-//    public static void main(String[] args) {
-//        AboutDialog dialog = new AboutDialog();
-//        dialog.pack();
-//        dialog.setVisible(true);
-//        System.exit(0);
-//    }
 
     {
 // GUI initializer generated by IntelliJ IDEA GUI Designer

GUI/src/com/drogar/lqpl/screens/QuantumEmulatorMainScreen.form

                 <constraints/>
                 <properties>
                   <editable value="false"/>
+                  <name value="messagesTextArea"/>
                 </properties>
               </component>
             </children>

GUI/src/com/drogar/lqpl/screens/QuantumEmulatorMainScreen.java

     public QuantumEmulatorMainScreen() {
         super("Quantum Emulator");
         frameTitle = "Quantum Emulator";
+        setName(frameTitle);
         setBounds(new Rectangle(10, 10, 400, 300));
         //setDefaultCloseOperation(EXIT_ON_CLOSE);
 
         setUpSpinner(recursionSpinner, 1, 1, 100000, 1);
         setUpSpinner(recursionMultiplierSpinner, 10, 1, 100000, 1);
         setUpSpinner(treeDepthSpinner, 4, 1, 100, 1);
-
         spinnerPanel.setVisible(false);
         buttonPanel.setVisible(false);
 
-        this.addWindowListener(new WindowAdapter() {
-            @Override
-            public void windowClosing(WindowEvent windowEvent) {
-                Ruby runtime = null;
-                try {
-                    runtime = Main.getRuntime();
-                } catch (Exception e) {
-                    RubyInstanceConfig config = new RubyInstanceConfig();
-                    runtime = JavaEmbedUtils.initialize(new ArrayList(0), config);
-                }
-
-                runtime.evalScriptlet("require 'exit_handler';ExitHandler.instance.close_servers");
-                System.exit(0);
-            }
-        });
+        // this.addWindowListener(new WindowAdapter() {
+        //   @Override
+        //   public void windowClosing(WindowEvent windowEvent) {
+        //     Ruby runtime = null;
+        //     try {
+        //         runtime = Main.getRuntime();
+        //     } catch (Exception e) {
+        //         RubyInstanceConfig config = new RubyInstanceConfig();
+        //         runtime = JavaEmbedUtils.initialize(new ArrayList(0), config);
+        //     }
+        // 
+        //     runtime.evalScriptlet("require 'exit_handler';ExitHandler.instance.close_servers");
+        //     System.exit(0);
+        //   }
+        //  });
 
     }
 
     public JLabel message;
 
 
-
     {
 // GUI initializer generated by IntelliJ IDEA GUI Designer
 // >>> IMPORTANT!! <<<
         messagesPanel.add(scrollPane1, BorderLayout.CENTER);
         messagesTextArea = new JTextArea();
         messagesTextArea.setEditable(false);
+        messagesTextArea.setName("messagesTextArea");
         scrollPane1.setViewportView(messagesTextArea);
         stepLabelForSpinner.setLabelFor(stepSpinner);
         recursionLabelForSpinner.setLabelFor(recursionSpinner);

GUI/src/dialogs/about/about_controller.rb

 class AboutController < ApplicationController
   set_model 'AboutModel'
   set_view 'AboutView'
-  set_close_action :exit
+  set_close_action :close
 
   def handleAbout(about_event)
     open

GUI/src/dialogs/simulate_results/simulate_results_model.rb

   end
 
   def self.result_values_to_list(rvals,stack_trans)
-    values_to_list rvals, TRIPLE_PATTERN, do |ret, rv|
+    values_to_list rvals, TRIPLE_PATTERN  do |ret, rv|
       ret << [stack_trans.reverse_lookup(rv[1]),rv[2],rv[3]]
     end
   end

GUI/src/exceptions/stack_descriptor_model_invalid_create.rb

-class StackDescriptorModelInvalidCreate < RuntimeError
-end

GUI/src/lqpl/lqpl_controller.rb

 class LqplController < ApplicationController
   set_model 'LqplModel'
   set_view 'LqplView'
-  set_close_action :exit
+  set_close_action :close
 
   {"the_menu.file_compile" => "file_compile", "the_menu.file_load" => "file_load",
     "the_menu.file_simulate" => "file_simulate","the_menu.view_classical_stack" => "view_classical_stack",
       add_listener :type => :action, :components => {k => v}
     end
 
-  case Config::CONFIG["host_os"]
+  case RbConfig::CONFIG["host_os"]
   when /darwin/i # OSX specific code
     java_import com.apple.eawt.Application
     Application.application.about_handler = AboutController.instance
     add_listener :type => :action, :components => {"the_menu.help_about" => "help_about"}
   end
 
+  def close
+    puts "Called lqpl controller close"
+    all_controllers_dispose
+    file_exit_action_performed
+    super
+  end
+  
+  def my_frame
+    @__view.the_frame
+  end
+  
   def load(*args)
     cmp = CompilerServerConnection.get_instance
     cmp.connect
     qplfiles = FileNameExtensionFilter.new("LQPL source file", ["qpl"].to_java(:string))
     chooser.set_file_filter(qplfiles)
     chooser.set_current_directory(java.io.File.new(Dir.getwd))
-    rval = chooser.show_open_dialog(nil)
+    rval = chooser.show_open_dialog(self.my_frame)
     if rval == JFileChooser::APPROVE_OPTION
       fname = chooser.get_selected_file.get_absolute_path
       cmp = CompilerServerConnection.get_instance
     update_view
   end
 
+  def all_controllers_dispose
+    AboutController.instance.dispose
+    SimulateResultsController.instance.dispose
+    ClassicalStackController.instance.dispose
+    DumpController.instance.dispose
+    ExecutableCodeController.instance.dispose
+    StackTranslationController.instance.dispose
+    QuantumStackController.instance.dispose
+  end
+  
   def file_simulate_action_performed
 
     SimulateResultsController.instance.lqpl_emulator_server_connection = LqplEmulatorServerConnection.get_instance

GUI/src/lqpl/lqpl_menu.rb

     menu_file.add(@file_compile);
     menu_file.add(@file_simulate);
 
-    case Config::CONFIG["host_os"]
+    case RbConfig::CONFIG["host_os"]
     when /darwin/i # OSX specific code
     #when /^win|mswin/i # Windows specific code
     #when /linux/i # Linux specific code
     mbar.add(menu_view);
 
 
-    case Config::CONFIG["host_os"]
+    case RbConfig::CONFIG["host_os"]
     when /darwin/i # OSX specific code
     #when /^win|mswin/i # Windows specific code
     #when /linux/i # Linux specific code

GUI/src/lqpl/lqpl_model.rb

-class LqplModel
+class LqplModel < ApplicationModel
   attr_accessor :spinner_panel_visible, :button_panel_visible
   attr_accessor :step_spinner, :recursion_spinner, :recursion_multiplier_spinner, :tree_depth_spinner
   attr_accessor :go_enabled, :step_enabled

GUI/src/lqpl/lqpl_view.rb

     @main_view_component.title = model.frame_title
   end
 
+  def the_frame
+    @main_view_component
+  end
 end
 
 case RbConfig::CONFIG["host_os"]
 when /darwin/i # OSX specific code
-  testing = java.lang.System.get_property("com.drogar.testing.jemmy")
+  testing = java.lang.System.get_property("com.drogar.testing.fest")
   if !testing or testing != "true"
     java.lang.System.set_property("apple.laf.useScreenMenuBar", "true")
   end
 
 # Set up global error handling so that it is consistantly logged or outputed
 # You will probably want to replace the puts with your application's logger
-def show_error_dialog_and_exit(exception, thread=nil)
-  puts "Error in application"
-  puts "#{exception.class} - #{exception}"
+def log_the_error(exception, thread=nil)
   rexcep = exception.exception
   if rexcep.class == ServerProcessNotFound
-    t = "Server(s) not found"
-    m = "LQPL requires the compiler server and emulator server to be installed on your path.
+    show_error_dialog("Server(s) not found",
+         "LQPL requires the compiler server and emulator server to be installed on your path.
          Please download or compile these and add them to your path, e.g., in /usr/local/bin.
-         See further details at http://pll.cpsc.ucalgary.ca/lqpl"
-    javax.swing.JOptionPane.show_message_dialog(nil, m, t, javax.swing.JOptionPane::DEFAULT_OPTION)
-    java.lang.System.exit(0)
+         See further details at http://pll.cpsc.ucalgary.ca/lqpl");
   end
   if exception.kind_of? Exception
-    puts exception.backtrace.join("\n")
     File.open("lqplEmulatorError.log", "w") do |f|
       f.puts exception.backtrace.join("\n")
     end
     exception.printStackTrace(java.io.PrintStream.new(output_stream))
     puts output_stream.to_string
   end
+  # add other error handling code goes here
+  show_error_dialog("Application Error","The application has encountered an error and must shut down.")
+  System.exit(0)
+end
 
-  # Your error handling code goes here
-
-  # Show error dialog informing the user that there was an error
-  title = "Application Error"
-  message = "The application has encountered an error and must shut down."
-
-  javax.swing.JOptionPane.show_message_dialog(nil, message, title, javax.swing.JOptionPane::DEFAULT_OPTION)
-  java.lang.System.exit(0)
+def show_error_dialog_and_exit(title, message)
+  JOptionPane.show_message_dialog(nil, message, title, JOptionPane::DEFAULT_OPTION)
+  System.exit(0)
 end
-GlobalErrorHandler.on_error {|exception, thread| show_error_dialog_and_exit(exception, thread) }
+
+GlobalErrorHandler.on_error {|exception, thread| log_the_error(exception, thread) }
 
 begin
   LqplController.instance.open
+  puts 'Returned from open/close...'
 rescue => e
-  show_error_dialog_and_exit(e)
+  show_error_dialog_and_exit("error",e.to_s)
 end

GUI/src/manifest.rb

 when Monkeybars::Resolver::IN_JAR_FILE
   # Files to be added only when run from inside a jar file
 end
+
+require 'application_model'
+require 'utility/xml_decode'
+require 'xml_based_model'
 ["server_process_not_found", "invalid_input"].each do |f|
   require "exceptions/"+f
 end
 
 require "exit_handler"
 
+java_import javax.swing.JOptionPane
+java_import java.lang.System
 
 

GUI/src/panels/classical_stack/classical_stack_model.rb

 require 'exceptions/quantum_stack_model_invalid_create'
 
-class ClassicalStackModel
-  include XmlDecode
+class ClassicalStackModel < XmlBasedModel
   attr_accessor :classical_stack_text
   attr_accessor :classical_stack
 
   end
 
   def classical_stack=(xml_input)
-    cstack_in = CSTACK_PATTERN.match xml_input
-    raise QuantumStackModelInvalidCreate, "Invalid Classical Stack: #{xml_input}" if !cstack_in
-    @classical_stack = ClassicalStackModel::classical_values_to_list(cstack_in[1])
+    @classical_stack = check_and_return_value(CSTACK_PATTERN,xml_input,
+      lambda { |m| ClassicalStackModel::classical_values_to_list m})
   end
 
   def self.classical_values_to_list(cvals)
-    values_to_list cvals, CLASSICALVALUES_PATTERN, do | ret, cv|
+    values_to_list cvals, CLASSICALVALUES_PATTERN  do | ret, cv|
       ret << cv[2].to_i if cv[2]
       ret << (cv[4] == "True" or cv[4] == "true") if cv[4]
     end

GUI/src/panels/dump/dump_model.rb

 require "panels/dump/dump_call_model"
 require "panels/dump/dump_split_model"
 
-class DumpModel
-  include XmlDecode
+class DumpModel <XmlBasedModel
+
   attr_accessor :dump
+  
   def dump=(in_xml)
-
-    m = DUMP_PATTERN.match in_xml
-    raise QuantumStackModelInvalidCreate, "Invalid dump: #{in_xml}" if !m
-    @dump = DumpModel.dump_values_to_list m[1]
+    @dump = check_and_return_value(DUMP_PATTERN,in_xml,
+    lambda { |m| DumpModel::dump_values_to_list m})
   end
 
   def text=(whatev)
   end
 
   def self.dump_values_to_list(dumpvals)
-    values_to_list dumpvals, DUMPVALUES_PATTERN, do |ret, dv|
+    values_to_list dumpvals, DUMP_LIST_PATTERN  do |ret, dv|
       ret << DumpCallModel.new(dv[1]) if dv[1]
       ret << DumpSplitModel.new(dv[2]) if dv[2]
     end
   end
-  DUMPVALUES_PATTERN = Regexp.new /(<DumpCall>.*?<\/DumpCall>)|(<DumpSplit>.*?<\/DumpSplit>)/
+  DUMP_LIST_PATTERN = Regexp.new /(<DumpCall>.*?<\/DumpCall>)|(<DumpSplit>.*?<\/DumpSplit>)/
   DUMP_PATTERN= Regexp.new /<Dump>(.*?)<\/Dump>/
 end

GUI/src/panels/dump/dump_split_model.rb

-class DumpSplitModel
+class DumpSplitModel <XmlBasedModel
 
   def initialize(inx)
     self.dumpsplit=inx
 
   def dumpsplit=(in_xml)
     m = DS_PATTERN.match in_xml
-    raise QuantumStackModelInvalidCreate, "Invalid dump split: #{in_xml}" if !m
+    raise ModelCreateError, "Invalid dump split: #{in_xml}" if !m
     @ds_text= m[0]
   end
 

GUI/src/panels/executable_code/executable_code_model.rb

 
   def self.instructions_to_list(instructions)
     count = 0
-    values_to_list instructions, INSTRUCTIONS_PATTERN, do |ret, ins|
+    values_to_list instructions, INSTRUCTIONS_PATTERN  do |ret, ins|
       ret << sprintf("%3d  %s",count,ins[1])
       count += 1
     end

GUI/src/panels/quantum_stack/descriptor/abstract_descriptor_model.rb

-
-
-
-class AbstractDescriptorModel
-  include XmlDecode
+class AbstractDescriptorModel <XmlBasedModel
   attr_accessor :value
   attr_accessor :name
 
     when /^<Clas/ then ClassicalDescriptorModel.new in_string
     when /^<Qubi/ then QubitDescriptorModel.new in_string
     when /^<Alge/ then DataDescriptorModel.new in_string
-    else raise StackDescriptorModelInvalidCreate, in_string
+    else raise ModelCreateError, in_string
     end
   end
 
   def initialize
-    raise StackDescriptorModelInvalidCreate
+    raise ModelCreateError
   end
 
+
+  
   def length
     return @value.length
   end

GUI/src/panels/quantum_stack/descriptor/classical_descriptor_model.rb

   LIST_PATTERN = Regexp.new /^(<cint>(-?\d+)<\/cint>)|(<cbool>(True|False)<\/cbool>)/
 
   def initialize(in_string)
-    matc = PATTERN.match in_string
-    raise StackDescriptorModelInvalidCreate, in_string if ! matc
-    @value = ClassicalDescriptorModel::parse_list matc[1]
+    @value = check_and_return_value(PATTERN,in_string,
+      lambda { |m| ClassicalDescriptorModel::parse_list m})
   end
 
   def self.parse_list(sub_string)
-    r = values_to_list sub_string, LIST_PATTERN, do |ret, md|
+    r = values_to_list sub_string, LIST_PATTERN do |ret, md|
       ret << md[2].to_i if md[2]
       ret << (md[4] == 'True') if md[4]
     end
-    raise StackDescriptorModelInvalidCreate, sub_string if sub_string and sub_string.length > 0 and r.length == 0
+    raise ModelCreateError, sub_string if sub_string and sub_string.length > 0 and r.length == 0
     r
   end
 

GUI/src/panels/quantum_stack/descriptor/data_descriptor_model.rb

   # match 2
 
   def initialize(in_string)
-    matc = PATTERN.match in_string
-    raise StackDescriptorModelInvalidCreate, in_string if ! matc
-    @value = DataDescriptorModel::parse_pairs matc[1]
+    @value = check_and_return_value(PATTERN,in_string,
+      lambda { |m| DataDescriptorModel::parse_pairs m})
   end
 
 
 
 
   def self.parse_address_list(addresses_string)
-    r = values_to_list addresses_string, LIST_PATTERN, do |rval, md|
+    r = values_to_list addresses_string, LIST_PATTERN do |rval, md|
       elem = md[2].to_i
       raise InvalidInput, "StackAddress '#{elem}' duplicated for single constructor" if rval.include? elem
       rval << elem

GUI/src/panels/quantum_stack/descriptor/qubit_descriptor_model.rb

   # match 2 and 5
 
   def initialize(in_string)
-    matc = PATTERN.match in_string
-    raise StackDescriptorModelInvalidCreate, in_string if !matc
-    @value = QubitDescriptorModel::parse_list matc[1]
+    @value = check_and_return_value(PATTERN,in_string,
+      lambda { |m| QubitDescriptorModel::parse_list m})
   end
 
   def length
 
   def self.parse_list(qubit_string)
     raise InvalidInput, "Must have qubit indicators" if !qubit_string or qubit_string.length == 0
-    r = values_to_list qubit_string, LIST_PATTERN, do |rval,md|
+    r = values_to_list qubit_string, LIST_PATTERN  do |rval,md|
       elem = [self.translate_qubit(md[2]), self.translate_qubit(md[5])]
       raise InvalidInput, "#{elem} duplicated in qubit" if rval.include? elem
       rval << elem

GUI/src/panels/quantum_stack/descriptor/value_descriptor_model.rb

 
   def initialize(in_string)
     matc = PATTERN.match in_string
-    raise StackDescriptorInvalidCreate, in_string if ! matc
+    raise ModelCreateError, in_string if ! matc
     @value = matc[2]
     @name = nil
   end

GUI/src/panels/quantum_stack/descriptor/zero_descriptor_model.rb

 class ZeroDescriptorModel <AbstractDescriptorModel
 
   def initialize(in_string="<Zero/>")
-    raise StackDescriptorModelInvalidCreate, in_string if in_string != "<Zero/>"
+    raise ModelCreateError, in_string if in_string != "<Zero/>"
     @value = "0"
   end
 

GUI/src/panels/quantum_stack/quantum_stack_model.rb

 require "panels/quantum_stack/descriptor/qubit_descriptor_model"
 require "panels/quantum_stack/descriptor/data_descriptor_model"
 
-class QuantumStackModel
+class QuantumStackModel < XmlBasedModel
 
   attr_accessor :substacks
   attr_accessor :descriptor

GUI/src/panels/quantum_stack/quantum_stack_painter.rb

   attr :model_element
 
   def initialize(model_element)
-    @model_element = model_element
-
-    @descriptor_painter = DescriptorPainterFactory.make_painter(model_element.descriptor)
-    @sstack_painters = @model_element.substacks.collect {|s| QuantumStackPainter.new(s)}
+    self.model_element=model_element
   end
 
   def model_element=(model)
   # end of painter interface
 
   def model_paint_size(g)
+    #todo - refactor to make "size" a class
     return @preferred_size if @preferred_size
     if model_element.bottom?
       dim= get_string_size(g,"...")

GUI/src/panels/stack_translation/stack_translation_model.rb

 require 'exceptions/quantum_stack_model_invalid_create'
 
-class StackTranslationModel
+class StackTranslationModel < XmlBasedModel
   attr_accessor :stack_translation
   attr_accessor :text
 

GUI/src/utility/drawing.rb

   end
 
   def draw_text_centered_between(g,text, point1, point2)
-      point = Point.new((point1.x + point2.x) / 2, (point1.y + point2.y) / 2)
-      draw_centered_text(g,text,point)
+      draw_centered_text(g,text,mid_point(point1, point2))
+  end
+  
+  def mid_point(point1, point2)
+    Point.new((point1.x + point2.x) / 2, (point1.y + point2.y) / 2)
   end
 
   def draw_sized_text(g,size,text, point1, point2,reference)
-    point = Point.new((point1.x + point2.x) / 2, (point1.y + point2.y) / 2)
+    point = mid_point(point1, point2)
     atext = AttributedString.new(text)
     atext.add_attribute(TextAttribute::SIZE, size, 0, text.length)
     case reference
     when :left then draw_text_to_left_of_point(g,atext.iterator,Point.new(point.x,point.y))
     when :right then draw_text_to_right_of_point(g,atext.iterator,point)
-    else draw_text_centered_between(g,atext.iterator,point1,point2)
+    else draw_text_centered_at_point(g,atext.iterator,point)
     end
   end
 
   def get_string_size(g,text)
     case text
     when AttributedCharacterIterator then
-      this_font = g.font.derive_font(8.0)
+      this_font = g.font.java_send :deriveFont, [Java::float], 8.0
       this_font.get_string_bounds(text,0, text.end_index, g.font_render_context)
     else g.font.get_string_bounds(text,g.font_render_context)
     end

GUI/src/xml_based_model.rb

+class XmlBasedModel <ApplicationModel
+  include XmlDecode
+  attr_accessor :value
+  attr_accessor :name
+
+
+  def check_and_return_value(pattern,in_string,data_parser)
+    matched = pattern.match in_string
+    raise ModelCreateError, "Invalid input for #{self.class}: #{in_string}" if ! matched
+    data_parser.call matched[1]
+  end
+
+end

features/compile_an_lqpl_program.feature

+
 Feature: We can load and compile lqpl code
 
   As a researcher
 
   Scenario: I compile a simple qpl program
     Given I select "Compile" from the "File" menu
-    And I load "coin.qpl" from the directory "testdata/qplprograms"
-    Then "coin.qpo" should be created in "testdata/qplprograms" and be equal to "coin.reference.qpo"
+    And I load "coin.qpl" from the project directory "GUI/testdata/qplprograms"
+    Then "coin.qpo" should be created in the project directory "GUI/testdata/qplprograms" and be equal to "coin.reference.qpo"
     Then the messages field should contain:
       |partial|
       |Compile of coin.qpl was successful|
-
+  
   Scenario: I try to compile a qpl program with syntax errors
     Given I select "Compile" from the "File" menu
-    And I load "invalidsyntax.qpl" from the directory "testdata/qplprograms"
+    And I load "invalidsyntax.qpl" from the project directory "GUI/testdata/qplprograms"
     Then the messages field should contain:
       |partial|
       |invalidsyntax.qpl was unsuccessful|
 
   Scenario: I try to compile a qpl program with syntax errors
     Given I select "Compile" from the "File" menu
-    And I load "invalidsemantics.qpl" from the directory "testdata/qplprograms"
+    And I load "invalidsemantics.qpl" from the project directory "GUI/testdata/qplprograms"
     Then the messages field should contain:
       |partial|
       |invalidsemantics.qpl was unsuccessful|
 
   Scenario: I compile a qpl program with warnings errors
     Given I select "Compile" from the "File" menu
-    And I load "invalidbalance.qpl" from the directory "testdata/qplprograms"
+    And I load "invalidbalance.qpl" from the project directory "GUI/testdata/qplprograms"
     Then the messages field should contain:
       |partial|
       |invalidbalance.qpl was successful|

features/load_an_assembled_qpo.feature

   As a researcher
   I want the program allow me to choose a "*.qpo" program and load it to the server so I can execute it.
 
-  Background:
-    When I select "Load" from the "File" menu
-    And I load "coin.reference.qpo" from the directory "testdata/qplprograms"
-
+	Background:
+	  When I select "Load" from the "File" menu
+    And I load "coin.reference.qpo" from the project directory "GUI/testdata/qplprograms"
+    
 
   Scenario:
     Then the main frame's title should be "Quantum Emulator - coin.reference.qpo"

features/show_and_hide_frames.feature

   As a researcher
   I want the program allow me to show only what i want.
 
-  Background:
-    When I select "Load" from the "File" menu
-    And I load "coin.reference.qpo" from the directory "testdata/qplprograms"
+	Background:
+	  When I select "Load" from the "File" menu
+    And I load "coin.reference.qpo" from the project directory "GUI/testdata/qplprograms"
 
   Scenario:
     Then the frame "Executing Code" should be visible
     When I select "Show Executing Code" from the "View" menu
     Then the frame "Executing Code" should be visible
 
+
   Scenario:
     Then the frame "Stack Translation" should be visible
     When I select "Hide Stack Translation" from the "View" menu
     When I select "Show Stack Translation" from the "View" menu
     Then the frame "Stack Translation" should be visible
 
+
   Scenario:
     Then the frame "Dump" should be visible
     When I select "Hide Dump" from the "View" menu
     When I select "Show Dump" from the "View" menu
     Then the frame "Dump" should be visible
 
+
   Scenario:
     Then the frame "Classical Stack" should be visible
     When I select "Hide Classical Stack" from the "View" menu

features/show_simulate_results.feature

 
   Background:
     When I select "Load" from the "File" menu
-    And I load "coin.reference.qpo" from the directory "testdata/qplprograms"
+    And I load "coin.reference.qpo" from the project directory "GUI/testdata/qplprograms"
 
   Scenario:
     When I click the button "Go" 1 time on the frame "Quantum Emulator"

features/step_definitions/compile_an_lqpl_program.rb

 
 Given /^the frame "([\w\s]*)" is visible$/ do |frame_name|
 
-  eval "@#{frame_name.gsub(/ /,'_')} = JFrameOperator.new frame_name"
+  eval "@#{frame_name.gsub(/ /,'_')} = FrameFixture.new frame_name"
 end
 
 Given /^I select "([a-zA-Z\s]*)" from the "([a-zA-Z]*)" menu$/ do |mitem, menu|
 
-  mbar = JMenuBarOperator.new $qe_frame.get_jmenu_bar
-  #jm = mbar.get_menu(0)
-  fmenu = JMenuOperator.new(mbar,menu)
-  fmenu.should_not be_nil
-  item_count = fmenu.get_item_count
-  ((0...item_count).any? do |i|
-    mitem == fmenu.get_item(i.to_int).get_text
-  end).should be_true
-  jmi = nil
-  (0...item_count).each do |i|
-    jmi = fmenu.get_item(i.to_int) if mitem == fmenu.get_item(i.to_int).get_text
-  end
-  fmenu_item = JMenuItemOperator.new(jmi)
-  fmenu_item.should_not be_nil
-  fmenu_item.should be_enabled
-
-  mbar.push_menu_no_block("#{menu}|#{mitem}")
-  #fmenu_item.push_no_block
+  menu_item =  $qe_frame.menu_item_with_path [menu, mitem].to_java(:string)
+  menu_item.should_not be_nil
+  menu_item.click()
+  sleep 0.25
 end
 
 
-And /^I load "([\w]*?\.qpl)" from the directory "([\w\s\/]*)"$/ do |file, dir|
-
-  fc = JFileChooserOperator.new
-  fc.get_dialog_title.should == "Open LQPL File for Compiling"
-
-  fc.get_current_directory.get_absolute_path.should ==  Dir.getwd
-  fc.is_file_selection_enabled.should == true
-  fc.is_directory_selection_enabled.should == false
-  cdir = fc.get_current_directory.get_absolute_path
-
-  if not (cdir =~ /GUI/)
-    fc.set_current_directory(java.io.File.new(cdir,"GUI"))
-  end
-  topdir = fc.get_current_directory.get_absolute_path
-
+And /^I load "([\w\.]*?\....)" from the project directory "([\w\s\/]*)"$/ do |file, dir|
 
-  dirs = dir.split("/")
-  dirs.each do |d|
-    cdir = fc.get_current_directory.get_absolute_path
-    fc.set_current_directory (java.io.File.new(cdir, d))
-  end
-  fc.get_current_directory.get_absolute_path.should ==  topdir+"/"+dir
+  fc = JFileChooserFixture.new($robot) #   $qe_frame.file_chooser()
 
+  fc.select_file_in_project_directory(dir,file)
 
-  sel_file = java.io.File.new(fc.get_current_directory.get_absolute_path,file)
-
-  fc.set_selected_file sel_file
-
-  fc.approve_selection
-
+  fc.approve
 
 end
 
 
-Then /^"([\w\s]*?\.qpo)" should be created in "([\w\s\/]*)" and be equal to "([\w\s\.]*?\.qpo)"$/ do |outfile, outdir,reference|
-  topdir = Dir.getwd
-  if not (topdir =~ /GUI/)
-    topdir = topdir + "/GUI"
-  end
-  realdir = topdir + "/" +outdir
-  theFile = realdir + "/" + outfile
-  sleep_until(10) {File.exist?(theFile)}
-  # tries = 0
-  #   while tries < 10 do # wait up to 2.5 seconds for compile to finish
-  #     sleep 0.25
-  #     break if File.exist?(theFile)
-  #     tries += 1
-  #   end
-  File.exist?(realdir + "/" + outfile).should be_true
-  File.open(realdir + "/" + outfile) do |newone|
-    result = newone.read
-    File.open(realdir + "/" + reference) do |ref|
-      refvalue = ref.read
-      result.should == refvalue
-    end
-  end
+Then /^"([\w\s]*?\.qpo)" should be created in the project directory "([\w\s\/]*)" and be equal to "([\w\s\.]*?\.qpo)"$/ do |outfile, outdir,reference|
+  the_file = File.file_in_project_subdir(outdir, outfile)
+  
+  sleep_until_file_exists(10,the_file).should be_true
+  
+  File.read(the_file).should == File.read(File.file_in_project_subdir(outdir,reference))
 end
 
 Then /^the messages field should contain:$/ do |client_message_table|
-  theTextArea = JTextAreaOperator.new($qe_frame)
-  message_texts = client_message_table.hashes.collect {|h| Regexp.new h.values[0]}
-  message_texts.each do |t|
-    theTextArea.text.should =~ t
-  end
-
+  all_text_is_in_text_component(client_message_table, JTextComponentFixture.new($robot,"messagesTextArea"))
 end

features/step_definitions/load_an_assembled_qpo.rb

 
 
-When /I load "([a-zA-Z0-9_\.]*?\.qpo)" from the directory "([\w\s\/]*)"/ do |file, dir|
-
-  fc = JFileChooserOperator.new
-  fc.get_dialog_title.should == "Load LQPO (Assembly) File"
-
-  fc.get_current_directory.get_absolute_path.should ==  Dir.getwd
-  fc.is_file_selection_enabled.should == true
-  fc.is_directory_selection_enabled.should == false
-
-  cdir = fc.get_current_directory.get_absolute_path
-  if not (cdir =~ /GUI/)
-    fc.set_current_directory(java.io.File.new(cdir,"GUI"))
-  end
-  topdir = fc.get_current_directory.get_absolute_path
-
-  dirs = dir.split("/")
-  dirs.each do |d|
-    cdir = fc.get_current_directory.get_absolute_path
-    fc.set_current_directory (java.io.File.new(cdir, d))
-  end
-  fc.get_current_directory.get_absolute_path.should ==  topdir+"/"+dir
-
-  sel_file = java.io.File.new(fc.get_current_directory.get_absolute_path,file)
-#  p sel_file
-  fc.set_selected_file sel_file
-
-  fc.approve_selection
-
-
-end
-
 Then /^the main frame.s title should be "(.*?)"$/ do |the_title|
-  $qe_frame.title.should == the_title
+  ft = GuiActionRunner.execute(TitleQuery.new($qe_frame))
+  ft.should == the_title
 end
 
 
 Then /^the button "([\w\s]*)" should appear$/ do |button_text|
-  theButton = JButtonOperator.new($qe_frame, button_text)
+  theButton = $qe_frame.button(JButtonMatcher.with_text button_text)
 
   theButton.should_not == nil
-  theButton.text.should == button_text
-  theButton.should be_visible
+  theButton.should be_edt_visible
 end
 
 Then /^the number spinner "([\w\s]*)" should appear and have value "([\d]*)"$/ do |spinner_label, spin_value|
-
-  theLabel = JLabelOperator.new($qe_frame, spinner_label)
-
-  theLabel.should_not == nil
-  theLabel.text.should == spinner_label
-  theLabel.should be_visible
-
-  theSpinner = JSpinnerOperator.new(theLabel.label_for)
+  theSpinner = spinner_for_label(spinner_label)
   theSpinner.should_not == nil
-  "#{theSpinner.value}".should == spin_value
+  theSpinner.should be_edt_visible
+  theSpinner.text.should == "#{spin_value}"
 end
 
-Then /^the frame "([\w\s]*)" should (not )?be visible$/ do |frame_name,visible|
-   set_frame_name_var(frame_name)
-   frame_op = eval(frame_name_var_string frame_name)
-   if visible == 'not '
-     sleep_until(5) {!frame_op.visible?}
-     # tries=0
-     #      while tries < 5 do
-     #        sleep 0.25
-     #        break if !frame_op.visible?
-     #      end
-     frame_op.should_not be_visible
-   else
-     sleep_until(5) {frame_op.visible?}
-     frame_op.should be_visible
-   end
+Then /^the frame "([\w\s]*)" should (be|not be) visible$/ do |frame_title,visible|
+  frame_fixture = set_and_return_frame_fixture(frame_title)
+  sleep_until_visibility(5,frame_fixture,visible).should be_true
 end
 
-Then /^I click the spinner "([\w\s]*)" (up|down) (\d)* times? on the frame "([\w\s]*)"$/ do |spinner_label, direction, count, frm|
-  theSpinner = JSpinnerOperator.new(JLabelOperator.new(eval(frame_name_var_string frm), spinner_label).label_for)
-  spin_button = theSpinner.increase_operator
-  spin_button = theSpinner.decrease_operator if direction == "down"
-  count.to_i.times {|i| spin_button.do_click}
-
+Then /^I click the spinner "([\w\s]*)" (up|down) (\d)* times? on the frame "([\w\s]*)"$/ do |spinner_label, direction, count, frame_title|
+  frame_ref=set_and_return_frame_fixture(frame_title)
+  theSpinner = spinner_for_label(spinner_label,frame_ref)
+  theSpinner.increment(count.to_i) if direction == "up"
+  theSpinner.decrement(count.to_i) if direction == "down"
+  
 end
 
-When /^I click the button "([\w\s]*)" (\d)* times? on the frame "([\w\s]*)"$/ do |button_text, count, frm|
-  theButton = JButtonOperator.new(eval(frame_name_var_string(frm)), button_text)
-  count.to_i.times {|i| theButton.do_click}
+When /^I click the button "([\w\s]*)" (\d)* times? on the frame "([\w\s]*)"$/ do |button_text, count, frame_title|
+  frame_ref=set_and_return_frame_fixture(frame_title)
+  theButton = frame_ref.button(JButtonMatcher.with_text button_text)
+  count.to_i.times {|i| theButton.click}
 
 end
 
-Then /^the selection on the frame "([\w\s]*)" should show ---(.*?)$/ do |frame_name, selec|
-
-  theTabbedPane = JTabbedPaneOperator.new(eval(frame_name_var_string(frame_name)))
-  theTextArea = JTextAreaOperator.new(theTabbedPane.selected_component.viewport.view)
-  theTextArea.selected_text.chomp.should == selec
+Then /^the selection on the frame "([\w\s]*)" should show ---(.*?)$/ do |frame_title, selection|
+  frame_ref=set_and_return_frame_fixture(frame_title)
+  
+  theTabbedPane = frame_ref.tabbed_pane
+  theTextArea = theTabbedPane.edt_selected_component.edt_viewport.edt_view
+  theTextArea.selected_text.chomp.should == selection
 
 end
 
-Then /^the button "([\w\s]*)" on the frame "([\w\s]*)" should be (dis|en)abled$/ do |button_text, frm, dis_or_en|
-  the_button = JButtonOperator.new(eval(frame_name_var_string(frm)), button_text)
-  the_button.enabled.should == (dis_or_en == 'en')
+Then /^the button "([\w\s]*)" on the frame "([\w\s]*)" should be (dis|en)abled$/ do |button_text, frame_title, dis_or_en|
+  frame_ref=set_and_return_frame_fixture(frame_title)
+  the_button = frame_ref.button(JButtonMatcher.with_text button_text)
+  the_button.edt_enabled?.should == (dis_or_en == 'en')
 end

features/step_definitions/show_simulate_results.rb

 
 
-Then /^the dialog "([\w\s]*)" should have one of:$/ do |dialog, message_text_table|
+Then /^the dialog "([\w\s]*)" should have one of:$/ do |dialog_title, message_text_table|
   # table is a Cucumber::Ast::Table
-  d_op = JDialogOperator.new(dialog)
-  message_text = message_text_table.hashes.collect {|h| h.values[0]} # just the list of values
-  check_component_contains_label(d_op,message_text).should be_true
+  dialog_fixture = WindowFinder.find_dialog(DialogMatcher.with_title (dialog_title)).using($robot)
+  the_display_area_label = dialog_fixture.label(label_matcher_with_pattern("<html>.*html>"))
   
-  theButton = JButtonOperator.new(d_op, "OK")
-  theButton.do_click
+  any_text_is_in_text_component(message_text_table, the_display_area_label).should be_true
+  
+  dialog_fixture.button().click
 end

features/support/component_query.rb

+class ComponentQuery < GuiQuery
+  # Launch the query in the Event Dispatch Thread (EDT),
+  # which is the thread reserved for user interfaces.
+  #
+  def initialize(component)
+    super()
+    @component = component.target if component.class.to_s =~ /Fixture$/
+    @component = component if component.class.to_s =~/Javax|JavaAwt/
+  end
+  
+end
+
+class LabelForQuery < ComponentQuery
+  def executeInEDT
+    @component.label_for
+  end
+end
+
+class TitleQuery < ComponentQuery
+  
+  def executeInEDT
+    @component.title
+  end
+end
+
+class OwnerQuery < ComponentQuery
+  
+  def executeInEDT
+    @component.owner
+  end
+end
+
+
+class EnabledQuery < ComponentQuery
+  
+  def executeInEDT
+    @component.is_enabled
+  end
+end
+class SelectedComponentQuery < ComponentQuery
+  
+  def executeInEDT
+    @component.selected_component
+  end
+end
+
+class SelectedTextQuery < ComponentQuery
+  
+  def executeInEDT
+    @component.selected_text
+  end
+end
+
+class ViewportQuery < ComponentQuery
+  
+  def executeInEDT
+    @component.viewport
+  end
+end
+
+
+class ViewQuery < ComponentQuery
+  
+  def executeInEDT
+    @component.view
+  end
+end
+
+class VisibleQuery < ComponentQuery
+  
+  def executeInEDT
+    @component.is_visible
+  end
+end
+
+module EDTQuery
+  
+  def edt_visible?
+    return GuiActionRunner.execute(VisibleQuery.new(self))
+  end
+  
+  def edt_enabled?
+    return GuiActionRunner.execute(EnabledQuery.new(self))
+  end
+    
+  def edt_title
+    return GuiActionRunner.execute(TitleQuery.new(self))
+  end
+  
+  def edt_label_for
+    return GuiActionRunner.execute(LabelForQuery.new(self))
+  end
+  
+  def edt_owner
+    return GuiActionRunner.execute(OwnerQuery.new(self))
+  end
+    
+  def edt_selected_text
+    return GuiActionRunner.execute(SelectedTextQuery.new(self))
+  end
+  
+  def edt_viewport
+    return GuiActionRunner.execute(ViewportQuery.new(self))
+  end
+  
+  def edt_selected_component
+    return GuiActionRunner.execute(SelectedComponentQuery.new(self))
+  end
+  
+  def edt_view
+    return GuiActionRunner.execute(ViewQuery.new(self))
+  end
+end
+    
+class ComponentFixture
+  include EDTQuery
+end
+
+class Component
+  include EDTQuery
+end
+
+  

features/support/component_searches.rb

-module ComponentSearchs
-  def check_component_contains_label(container,message_text)
-    found = false
-    container.components.each do |comp|
-      case comp
-      when javax.swing.JLabel then
-        found |= message_text.any? {|mt| comp.text =~ Regexp.new(mt)}
-      when java.awt.Container then
-        found |= check_component_contains_label(comp,message_text)
-      end
+module ComponentSearches
+
+  def spinner_for_label(label_text,frm=$qe_frame)
+    theLabel = frm.label(JLabelMatcher.with_text label_text)
+    theLabel.should_not == nil
+    theLabel.should be_edt_visible
+    label_for = theLabel.edt_label_for
+    JSpinnerFixture.new($robot,label_for) 
+  end
+  
+  def all_text_is_in_text_component(message_table,text_fixture)
+    message_table.hashes.collect {|h| Regexp.new h.values[0]}.each do |t|
+      text_fixture.text.should =~ t
+    end
+  end
+  
+  def any_text_is_in_text_component(message_table,text_fixture)
+    message_texts = message_table.hashes.collect {|h| Regexp.new h.values[0]}
+    message_texts.any? do |t|
+      text_fixture.text =~ t
     end
-    found
   end
+  
 end
 
-World(ComponentSearchs)
+World(ComponentSearches)

features/support/env.rb

   abort 'Sorry - Feature tests of LQPL requires JRuby. You appear to be running or defaulted to some other ruby engine.'
 end
 
-$LOAD_PATH << File.expand_path(File.dirname(__FILE__))+"/../../GUI/src"
-$LOAD_PATH << File.expand_path(File.dirname(__FILE__))+"/../../out/lqpl_gui"
-$LOAD_PATH << File.expand_path(File.dirname(__FILE__))+"/../../GUI/lib/java"
-$LOAD_PATH << File.expand_path(File.dirname(__FILE__))+"/../../GUI/devlib/java"
-$LOAD_PATH << File.expand_path(File.dirname(__FILE__))+"/../../GUI/lib/ruby"
+where_i_am = File.expand_path(File.dirname(__FILE__))
+$project_dir = where_i_am +"/../../"
+
+%w{src lqpl_gui lib/java lib/ruby devlib/java}.each do |dir|
+  $LOAD_PATH << where_i_am+"/../../GUI/"+ dir
+end
+$LOAD_PATH << where_i_am+"/../../out/lqpl_gui"
+
 
 require 'java'
 
-$CLASSPATH << File.expand_path(File.dirname(__FILE__))+"/../../out/lqpl_gui"
+$CLASSPATH << where_i_am+"/../../out/lqpl_gui"
 
+#runtime jars
+%w{jruby-complete forms_rt monkeybars-1.1.1}.each do |jar|
+  $CLASSPATH << where_i_am+"/../../GUI/lib/java/"+jar+".jar"
+end
 
-$CLASSPATH << File.expand_path(File.dirname(__FILE__))+"/../../GUI/lib/java/jruby-complete.jar"
-$CLASSPATH << File.expand_path(File.dirname(__FILE__))+"/../../GUI/devlib/java/jemmy-2.3.0.0.jar"
-$CLASSPATH << File.expand_path(File.dirname(__FILE__))+"/../../GUI/lib/java/forms_rt.jar"
-$CLASSPATH << File.expand_path(File.dirname(__FILE__))+"/../../GUI/lib/java/monkeybars-1.1.1.jar"
+#testing jars
+%w{fest-swing-1.2 fest-assert-1.2 fest-reflect-1.2 fest-util-1.1.2 jcip-annotations-1.0}.each do |jar|
+  $CLASSPATH << where_i_am+"/../../GUI/devlib/java/" + jar+".jar"
+end
 
 
-require "jemmy-2.3.0.0.jar"
+require "fest-swing-1.2.jar"
 
 require "monkeybars-1.1.1.jar"
 require "forms_rt.jar"
 
-ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../out/bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
+ENV['PATH'] = "#{where_i_am + '/../../out/bin'}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
 
 java.lang.System.set_property("apple.laf.useScreenMenuBar", "false")
-java.lang.System.set_property("com.drogar.testing.jemmy","true")
+java.lang.System.set_property("com.drogar.testing.fest","true")
 
 require 'manifest'
 
-java_import org.netbeans.jemmy.JemmyProperties
-java_import org.netbeans.jemmy.TestOut
-
-["JFileChooserOperator","Operator","JButtonOperator","JLabelOperator","ContainerOperator",
-  "JSpinnerOperator","JTabbedPaneOperator","JTextAreaOperator","JFrameOperator",
-  "JDialogOperator","JMenuBarOperator","JMenuOperator","JMenuItemOperator"].each do |c|
-    java_import "org.netbeans.jemmy.operators."+c
+%w{BasicRobot}.each do |c|
+  java_import "org.fest.swing.core."+c
 end
 
-java_import org.netbeans.jemmy.drivers.menus.AppleMenuDriver
+%w{GuiActionRunner GuiQuery GuiTask}.each do |c|
+  java_import "org.fest.swing.edt."+c
+end
 
+%w{Window}.each do |c|
+  java_import "org.fest.swing.finder."+c+"Finder"
+end
 
+%w{Component JMenuItem Frame JTextComponent JSpinner JLabel JButton JFileChooser}.each do |c|
+  java_import "org.fest.swing.fixture."+c+"Fixture"
+end
 
-#  java_import org.netbeans.jemmy.Timeouts
-#  btn_timeout = Timeouts.new
-#  btn_timeout.setTimeout("ComponentOperator.WaitComponentTimeout", 100)
+%w{JButton JLabel Frame Dialog}.each do |c|
+  java_import "org.fest.swing.core.matcher."+c+"Matcher"
+end
 
-java_import javax.swing.JButton
+java_import java.util.regex.Pattern
 
+java_import java.awt.Component
 
-# props = JemmyProperties.properties
-# JemmyProperties.current_keys.each {|k| puts "Prop: #{k}    =  #{JemmyProperties.get_current_property(k)}"}
 
-# testout - (in, trace out, error out, notes out)
-JemmyProperties.set_current_output(TestOut.new(java.lang.System.in, nil, java.lang.System.err, nil))
+require 'support/component_query'
 
-# amd = AppleMenuDriver.new
-#
-# JemmyProperties.set_current_property("drivers.menu.org.netbeans.jemmy.operators.JMenuOperator",amd)
-# JemmyProperties.set_current_property("drivers.menu.org.netbeans.jemmy.operators.JMenuBarOperator",amd)
 
-begin
-  puts "Starting up!!!!"
-  com.drogar.lqpl.Main.main([])
-rescue Exception => e
-  puts "Exception from main: #{e}"
+class AppStarter < GuiQuery
+  # Launch the app in the Event Dispatch Thread (EDT),
+  # which is the thread reserved for user interfaces.
+  # FEST will call this method for us before the test.
+  #
+  def executeInEDT
+    com.drogar.lqpl.Main.main([])
+  end
 end
 
-$qe_frame = JFrameOperator.new "Quantum Emulator"
+
+# consider starting up servers now and dropping during at_exit.
+
+runner = GuiActionRunner.execute(AppStarter.new)
+$robot = BasicRobot.robot_with_current_awt_hierarchy
+$qe_frame = FrameFixture.new($robot, "Quantum Emulator")
+#$owner = FrameFixture.new($robot,$qe_frame.edt_owner)
 
 at_exit {
   
-  LqplController.instance.close
+  #LqplController.instance.close
   $qe_frame.close
+  $qe_frame = nil
+  $robot.clean_up
+  $robot = nil
  
 }

features/support/file_manipulation.rb

+class JFileChooserFixture
+ def set_to_project_sub_directory(dir_string)
+   cdir = Dir.getwd
+   dirs = dir_string.split("/")
+   dirs.each do |d|
+     cdir = java.io.File.new(cdir, d)
+     set_current_directory (cdir)
+     sleep 0.1
+   end
+   cdir
+ end
+ 
+ def select_file_in_project_directory(dir_string, file_name)
+   pdir = set_to_project_sub_directory(dir_string)
+   select_file(java.io.File.new(pdir,file_name))
+ end
+end
+
+class File
+  def self.file_in_project_subdir(subdir,file)
+    File.join(Dir.getwd,subdir,file)
+  end
+end

features/support/fixture_matches.rb

+module FixtureMatchers
+  def label_matcher_with_pattern(p)
+    JLabelMatcher.with_text(Pattern.compile(p))
+  end
+end
+
+World(FixtureMatchers)

features/support/frame_addon_module.rb

+module FrameAddon
+  def frame_ref_var_string(frame_title)
+    return  "$qe_frame" if frame_title == "Quantum Emulator" 
+    
+    "@#{frame_title.downcase.gsub(/ /,'_')}"
+  end
+
+
+
+  def set_and_return_frame_fixture(frame_title)
+    return $qe_frame if frame_title == "Quantum Emulator"
+
+    fnvs = frame_ref_var_string(frame_title)
+    eval "#{fnvs} = WindowFinder.find_frame(FrameMatcher.with_title (\"#{frame_title}\")).using($robot)"
+    eval fnvs
+  end
+  
+end
+
+World(FrameAddon)

features/support/frame_set_methods.rb

-module JemmyFrameSetup
-  def frame_name_var_string(frame_name)
-    case frame_name
-    when "Quantum Emulator" then "$qe_frame"
-    else "@#{frame_name.downcase.gsub(/ /,'_')}"
-    end
-  end
-
-  def set_frame_name_var(frame_name)
-    case frame_name
-    when "Quantum Emulator" then return
-    else fnvs = frame_name_var_string(frame_name)
-      eval "#{fnvs} = JFrameOperator.new frame_name"
-    end
-  end
-end
-
-World(JemmyFrameSetup)

features/support/hooks.rb

+# 
+# Before do
+# 
+# end
+# 
+# After do
+# end
 
-Before do
+# TODO - reconsider trying this (Around) again if there is a way to cleanly stop / start the 
+# system while testing.
+#
+# java_import java.awt.event.InputEvent
+# java_import java.awt.event.KeyEvent
 
-end
-
-After do
-end
+# Around do |sc, blk|
+# 
+#   runner = GuiActionRunner.execute(AppStarter.new)
+#   $robot = BasicRobot.robot_with_current_awt_hierarchy
+#   $qe_frame = FrameFixture.new($robot, "Quantum Emulator")
+#   blk.call
+#   $robot.press_modifiers(InputEvent::META_MASK)
+#   $robot.press_key(KeyEvent::VK_Q)
+#   $robot.release_key(KeyEvent::VK_Q)
+# #  $qe_frame.close
+#   
+#   $robot.clean_up
+#   $robot = nil
+# 
+#   $qe_frame = nil
+#   #LqplController.instance.close
+#   runner = nil
+#   sleep 2
+# end

features/support/race_conditions.rb

     count = 0
     while count < tries
       sleep 0.25
-      break if condition.call
+      return true if condition.call
       count += 1
     end
+    return false
+  end
+  
+  def sleep_until_not(tries, &condition)
+    sleep_until(tries) {!condition.call}
+  end
+  
+  def sleep_until_file_exists(tries,file_name)    
+    sleep_until(tries) {File.exist?(file_name)}
+  end
+  
+  def sleep_until_visibility(tries,component,condition)
+    sleep_until(tries) {component.edt_visible? == condition}
   end
 end
 

features/support/transforms.rb

+Transform /^be|not be$/ do |s|
+  s == 'be'
+end

notesOnConvertingToFest.txt

+Had to "name" all the swing items I wanted to find for testing.
+
+Import the base and then extend those with desired methods (e.g., componentfixture...)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.