Brett Giles avatar Brett Giles committed abdc93b

Increased test coverage to 95 % as measured by simplecov

Likely is 100%, due to simplecov not seeming to work with combo of Cucumber/FEST/MonkeyBars.

This finishes this branch.

Comments (0)

Files changed (45)

GUI/spec/communications/compiler_server_connection_spec.rb

       @cmp.failure_message.should =~ /Semantic Error/
     end
     it "signals a warning when the code has a balance creation error" do
-      fname = "#{TEST_QP_PATH}invalidbalance.qpl"
+      fname = "#{TEST_QP_PATH}/invalidbalance.qpl"
       @cmp.compile fname
       @cmp.failed.should be_false
       @cmp.failure_message.should =~ /Semantic Warning/
         end
       end
     end
+    
+    it "writes a .qpo file with the same name as the original .qpl file with the corresponding QPO code when using compile_and_write_qpo" do
+      fname = "#{TEST_QP_PATH}/min.qpl"
+      begin
+        File.delete("#{TEST_QP_PATH}/min.qpo")
+      rescue
+      end
+      @cmp.compile_and_write_qpo fname
+      @cmp.failed.should be_false
+      @cmp.failure_message.should == ""
+      File.exist?("#{TEST_QP_PATH}/min.qpo").should be_true
+      File.open("#{TEST_QP_PATH}/min.reference.qpo") do |ref_compile|
+        ref_data = ref_compile.read
+        File.open("#{TEST_QP_PATH}/min.qpo") do |new_compile|
+          new_data = new_compile.read
+          new_data.should == ref_data
+        end
+      end
+    end
     it "writes a .qpo file with the same name as the original .qpl file when imports are involved" do
       fname = "#{TEST_QP_PATH}/importer.qpl"
       begin
         end
       end
     end
+    it "sets failed to true if the desired qpl file is not existant" do
+      @cmp.send_included_file "<getFirst>GarbageFileThatDoesNotExist</getFirst>"
+      @cmp.failed?.should be_true
+    end
+    it "sets failure message to the name of the file if the desired qpl file is not existant" do
+      @cmp.send_included_file "<getFirst>GarbageFileThatDoesNotExist</getFirst>"
+      @cmp.failure_message.should =~ /GarbageFileThatDoesNotExist/
+    end
+    it "sets the success or fail message to '...successful...' if failed is false, and adds any failure message" do
+      @cmp.failed = false
+      @cmp.failure_message="testing"
+      @cmp.success_or_fail_message("file_name").should == "Compile of file_name was successful\ntesting"
+    end
+    it "sets the success or fail message to '...unsuccessful...' if failed is true, and adds any failure message" do
+      @cmp.failed = true
+      @cmp.failure_message="testing"
+      @cmp.success_or_fail_message("file_name").should == "Compile of file_name was unsuccessful\ntesting"
+    end
   end
 end

GUI/spec/communications/connection_spec.rb

+require 'spec/spec_helper'
+
+describe Connection do
+  before :each do
+    @c = Connection.instance
+  end
+  after :each do
+    @c.close_down
+  end
+  describe "_make_connection" do
+    it "should connect to the default web server when the port is set to 80" do
+      @c.port=80
+      @c._make_connection.should be_true
+    end
+    it "should be false when trying to connect to  port 20 (normally unused)" do
+      @c.port = 20
+      @c._make_connection.should be_false
+    end
+  end
+  describe "_start_up_the_executable_in_a_process" do
+    it "should raise an error if the executable is not found" do
+      @c.port = 768
+      expect {
+        @c.connect
+      }.to raise_error ServerProcessNotFound, /no process/
+    end
+  end
+  describe "connect" do
+    it "should successfully connect to the compiler server on 7683" do
+      @c.port = 7683
+      @c.connect_to = "lqpl-compiler-server"
+      @c.connect
+      @c.connected?.should be_true
+    end
+    it "should raise an error if the port is incorrect" do
+      @c.port = 76
+      @c.connect_to = "lqpl-compiler-server"
+      expect {
+        @c.connect
+      }.to raise_error ServerProcessNotFound, /76/
+    end
+    it "should raise an error if the connect to can not be found" do
+      @c.port = 768
+      @c.connect_to = "junkjunkjunk"
+      expect {
+        @c.connect
+      }.to raise_error ServerProcessNotFound, /junk/
+    end
+  end
+    
+end

GUI/spec/controller/application_controller_spec.rb

 require 'spec/spec_helper'
 
 describe ApplicationController do
-  describe "class methods" do
-    describe "controller_from_name" do
-      it "should return ClassicalStack controller for ['anything','Classical','Stack']" do
-        ApplicationController::controller_from_name(["junk", "Classical", "Stack"]).should == ClassicalStackController
-      end
-      it "should return Dump controller for ['anything','Dump']" do
-        ApplicationController::controller_from_name(["junk", "Dump"]).should == DumpController
-      end
-      it "should return Executable Code controller for ['anything','Executing','Code']" do
-        ApplicationController::controller_from_name(["junk", "Executing", "Code"]).should == ExecutableCodeController
-      end
-      it "should return QuantumStack controller for ['anything','Quantum','Stack']" do
-        ApplicationController::controller_from_name(["junk", "Quantum", "Stack"]).should == QuantumStackController
-      end
-      it "should return stacktranslation controller for ['anything','Stack','Translation']" do
-        ApplicationController::controller_from_name(["junk", "Stack", "Translation"]).should == StackTranslationController
-      end
-      it "should return nil for ['anything','something']" do
-        ApplicationController::controller_from_name(["junk", "somethin"]).should be_nil
-      end
+  describe "lqpl_emulator_server_connection" do
+    before :each do
+      @ac = ApplicationController.instance
+      LqplEmulatorServerConnection.instance.close_down()
+    end
+    it "should return a connected instance with no args" do
+      l = @ac.lqpl_emulator_server_connection
+      l.should_not be_nil
+      l.should be_connected
+    end
+    it "should return an unconnected instance with connect arg (1st) false" do
+      l = @ac.lqpl_emulator_server_connection false
+      l.should_not be_nil
+      l.should_not be_connected
     end
   end
+      
 end

GUI/spec/controller/classical_stack_controller_spec.rb

   it "should raise an error when created with junk" do
     expect { @c.set_classical_stack_data("junk")}. to raise_error   ParserError, /junk/
   end
-
+  
+  it "should return false for update_on_lqpl_model_trim" do
+    @c.update_on_lqpl_model_trim.should be_false
+  end
   it "should create a classical stack when given the correct input" do
     @c.set_classical_stack_data("<Classical>"+cint(-27)+CIBT+cint(40)+CIBF+"</Classical>")
     @c.get_classical_stack_data.should == "<html>-27<br />true<br />40<br />false</html>"

GUI/spec/controller/dump_controller_spec.rb

     @c.set_dump_data("<Dump>"+DCALL+"</Dump>")
     @c.get_dump_data.should == "<html><ol><li>Return to Ret(5). CS=[]</li></ol></html>"
   end
-
+  
+  it "should return true for update_on_lqpl_model_trim" do
+    @c.update_on_lqpl_model_trim.should be_true
+  end
   # it "should ask the sc for the dump when given a depth and recursion" do
   #     sc = double('server_connection')
   #     sc.should_receive(:connected?).and_return(true)

GUI/spec/controller/executable_code_controller_spec.rb

+require 'spec/spec_helper'
+
+
+describe ExecutableCodeController do
+  before(:each) do
+    @c = ExecutableCodeController.instance
+  end
+  it "should return false for update_on_lqpl_model_trim" do
+    @c.update_on_lqpl_model_trim.should be_false
+  end
+end

GUI/spec/controller/lqpl_controller_spec.rb

+require 'spec/spec_helper'
+
+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
+    LqplController.instance
+  end
+end
+
+class Loader < 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 initialize(lqplinst)
+    super()
+    @l = lqplinst
+  end
+  def executeInEDT
+    @l.load()
+  end
+end
+
+class Drunner < 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 initialize(lqplinst)
+    super()
+    @l = lqplinst
+  end
+  def executeInEDT
+    @l.load()
+    @l.file_compile_action_performed
+  end
+end
+
+# FailOnThreadViolationRepaintManager.install()
+# 
+# robot = BasicRobot.robot_with_current_awt_hierarchy
+      
+describe LqplController do
+  before :each do
+    @l = GuiActionRunner.execute(AppStarter.new) #LqplController.instance
+  end
+  describe "load" do
+    before (:each) do
+      GuiActionRunner.execute(Loader.new(@l)) 
+    end
+    it "sets up the cmp and ensures it is connected" do
+      @l.cmp.should_not be_nil
+      @l.cmp.should be_connected
+    end
+    it "ensures the server connection is connected" do
+      @l.lqpl_emulator_server_connection.should be_connected
+    end
+    it "sets up the subcontrollers" do
+      @l.sub_controllers.size.should == 5
+    end
+    it "sets each sub controller to a non-nil value" do
+        @l.sub_controllers.each { |c|   c.should_not be_nil }
+    end
+    it "sets up the dialogs" do
+      @l.dialogs.size.should == 2
+    end
+    it "sets each dialog to a non-nil value" do
+      @l.dialogs.each { |d|  d.should_not be_nil }
+    end
+  end
+  describe "file_exit" do
+    it "closes the server connection" do
+      GuiActionRunner.execute(Loader.new(@l)) 
+      @l.file_exit_action_performed()
+      @l.cmp.should_not be_connected
+      @l.lqpl_emulator_server_connection(false).should_not be_connected
+    end
+  end
+  describe "all_controllers_dispose" do
+    before :each do
+      GuiActionRunner.execute(Loader.new(@l)) 
+      d1=double("dialog1")
+      d1.should_receive(:dispose)
+      d2=double("dialog2")
+      d2.should_receive(:dispose)
+      s1=double("sub1")
+      s1.should_receive(:dispose)
+      s2=double("sub2")
+      s2.should_receive(:dispose)
+      @l.dialogs = [d1,d2]
+      @l.sub_controllers = [s1,s2]
+    end
+    after(:each) do
+      @l.dialogs = []
+      @l.sub_controllers = []
+    end
+    it "should send 'dispose' to each member of the dialogs and subcontrollers" do
+      @l.all_controllers_dispose
+    end
+  end
+  describe "close" do
+    before :each do
+      GuiActionRunner.execute(Loader.new(@l)) 
+      d1=double("dialog1")
+      d1.should_receive(:dispose)
+      d2=double("dialog2")
+      d2.should_receive(:dispose)
+      s1=double("sub1")
+      s1.should_receive(:dispose)
+      s2=double("sub2")
+      s2.should_receive(:dispose)
+      @l.dialogs = [d1,d2]
+      @l.sub_controllers = [s1,s2]
+    end
+    after(:each) do
+      @l.dialogs = []
+      @l.sub_controllers = []
+    end
+    it "should send 'dispose' to each member of the dialogs and subcontrollers" do
+      @l.close
+    end
+    it "closes the server connection" do
+      @l.close()
+      @l.cmp.should_not be_connected
+      @l.lqpl_emulator_server_connection(false).should_not be_connected
+    end
+  end
+  
+  describe "sub_controllers_open" do
+    before :each do
+      s1=double("sub1")
+      s1.should_receive(:open)
+      s2=double("sub2")
+      s2.should_receive(:open)
+      @l.sub_controllers = [s1,s2]
+    end
+    after(:each) do
+      @l.dialogs = []
+      @l.sub_controllers = []
+    end
+    it "should send 'open' to each member of the subcontrollers" do
+      @l.open_sub_panels
+    end
+  end
+  
+  describe "update_sub_model_data" do
+    before :each do
+      s1=double("sub1")
+      s1.should_receive(:set_data_from_lqpl_model)
+      s2=double("sub2")
+      s2.should_receive(:set_data_from_lqpl_model)
+      @l.sub_controllers = [s1,s2]
+    end
+    after(:each) do
+      @l.dialogs = []
+      @l.sub_controllers = []
+    end
+    it "should send 'set_data_from_lqpl_model' to each member of the subcontrollers" do
+      @l.update_sub_model_data
+    end
+  end
+  
+  describe "trim_button_action_performed" do
+    before :each do
+      s1=double("sub1")
+      s1.should_receive(:set_data_from_lqpl_model)
+      s1.should_receive(:update_on_lqpl_model_trim).and_return(true)
+      s2=double("sub2")
+      s2.should_receive(:update_on_lqpl_model_trim).and_return(false)
+      s2.should_not_receive(:set_data_from_lqpl_model)
+      @l.sub_controllers = [s1,s2]
+    end
+    after(:each) do
+      @l.dialogs = []
+      @l.sub_controllers = []
+    end
+    it "should send 'set_data_from_lqpl_model' to sub1 and not to sub2" do
+      @l.trim_button_action_performed
+    end
+  end
+  
+  # describe "file_compile_action_performed" do
+  #     it "should setup the model messages" do
+  #       GuiActionRunner.execute(Drunner.new(@l)) 
+  #       #fc = WindowFinder.findDialog("dialog1").with_timeout(200).using(robot)
+  #       fc =JFileChooserFixture.new(robot)#, @l.qpl_dialog) #   $qe_frame.file_chooser()
+  # 
+  #       #fc.select_file_in_project_directory("",file)
+  # 
+  #       fc.cancel()
+  #       #fc.button(JButtonMatcher.with_text("Cancel")).click
+  #       @l.model.messages_text.should_not be_nil
+  #     end
+  #   end
+end

GUI/spec/controller/panel_controller_spec.rb

+require 'spec/spec_helper'
+
+describe PanelController do
+  describe "class methods" do
+    describe "controller_from_name" do
+      it "should return ClassicalStack controller for ['anything','Classical','Stack']" do
+        PanelController::controller_from_name(["junk", "Classical", "Stack"]).should == ClassicalStackController
+      end
+      it "should return Dump controller for ['anything','Dump']" do
+        PanelController::controller_from_name(["junk", "Dump"]).should == DumpController
+      end
+      it "should return Executable Code controller for ['anything','Executing','Code']" do
+        PanelController::controller_from_name(["junk", "Executing", "Code"]).should == ExecutableCodeController
+      end
+      it "should return QuantumStack controller for ['anything','Quantum','Stack']" do
+        PanelController::controller_from_name(["junk", "Quantum", "Stack"]).should == QuantumStackController
+      end
+      it "should return stacktranslation controller for ['anything','Stack','Translation']" do
+        PanelController::controller_from_name(["junk", "Stack", "Translation"]).should == StackTranslationController
+      end
+      it "should return nil for ['anything','something']" do
+        PanelController::controller_from_name(["junk", "somethin"]).should be_nil
+      end
+    end
+  end
+  describe "instance methods" do
+    before :each do
+      @pm = PanelController.instance
+    end
+    it "should return false for update_on_lqpl_model_trim" do
+      @pm.update_on_lqpl_model_trim.should be_false
+    end
+  end
+end

GUI/spec/controller/quantum_stack_controller_spec.rb

   before(:each) do
     @d = QuantumStackController.instance
   end
-
+  
+  it "should return true for update_on_lqpl_model_trim" do
+    @d.update_on_lqpl_model_trim.should be_true
+  end
   # it "should set the server_connection when given an sc" do
   # 
   #     sc = double('server_connection')

GUI/spec/controller/stack_translation_controller_spec.rb

     @d.set_stack_translation_data(P1)
     @d.get_stack_translation_text.should == "<html><ol><li>p=>1</li></ol></html>"
   end
-
+  
+  it "should return false for update_on_lqpl_model_trim" do
+    @d.update_on_lqpl_model_trim.should be_false
+  end
   # it "should set the server_connection when given an sc" do
   # 
   #     sc = double('server_connection')

GUI/spec/misc/exit_handler_spec.rb

+require 'spec/spec_helper'
+
+describe ExitHandler do
+  describe "close_servers" do
+    it "should close the compiler server connection" do
+      ExitHandler.instance.close_servers
+      CompilerServerConnection.instance.connected?.should be_false
+    end
+    
+    it "should close the emulator server connection" do
+      ExitHandler.instance.close_servers
+      LqplEmulatorServerConnection.instance.connected?.should be_false
+    end
+  end
+  describe "handleQuitRequestWith" do
+    before (:each) do
+      @qr=double("quit_response")
+      @qr.should_receive(:performQuit)
+    end
+    it "should call performQuit on the quit response" do
+      ExitHandler.instance.handleQuitRequestWith(nil,@qr)
+    end
+    it "should close the compiler server  connection" do
+      ExitHandler.instance.handleQuitRequestWith(nil,@qr)
+      CompilerServerConnection.instance.connected?.should be_false
+    end
+    
+    it "should close the emulator server connection" do
+      ExitHandler.instance.handleQuitRequestWith(nil,@qr)
+      LqplEmulatorServerConnection.instance.connected?.should be_false
+    end
+  end
+end

GUI/spec/model/executable_code_model_spec.rb

       it "should return the nil by default" do
         @ecm.the_code.should be_nil
       end
+      it "should return the value set into the_code_was_updated" do
+        @ecm.the_code_was_updated = false
+        @ecm.the_code_was_updated?.should be_false
+        @ecm.the_code_was_updated = true
+        @ecm.the_code_was_updated?.should be_true
+      end
+      
     end
     describe "the_code_pointer" do
       before(:each) do

GUI/spec/model/lqpl_model_spec.rb

       LqplModel::symbol_for_view_menu_item(['whatever','X', 'Y']).should == :view_menu_x_y_text=
     end
   end
+  describe "instance methods" do
+    before :each do
+      @lm = LqplModel.new
+    end
+    describe "enable_view_menu_items" do
+      before :each do
+        @lm.enable_view_menu_items
+      end
+      it "sets view_menu_stack_translation_enabled to true" do
+        @lm.view_menu_stack_translation_enabled.should be_true
+      end
+      it "sets view_menu_dump_enabled to true" do
+        @lm.view_menu_dump_enabled.should be_true
+      end
+      it "sets view_menu_executing_code_enabled to true" do
+        @lm.view_menu_executing_code_enabled.should be_true
+      end
+      it "sets view_menu_classical_stack_enabled to true" do
+        @lm.view_menu_classical_stack_enabled.should be_true
+      end
+    end
+    describe "set_title_and_enable" do
+      before :each do
+        @lm.set_title_and_enable("test")
+      end
+      it "should set the title to 'Quantum Emulator - <arg>" do
+        @lm.frame_title.should == 'Quantum Emulator - test'
+      end
+      it "should set the go button to enabled" do
+        @lm.go_enabled.should be_true
+      end
+      it "should set the step button to enabled" do
+        @lm.step_enabled.should be_true
+      end
+      it "should set the spinner panel to visible" do
+        @lm.spinner_panel_visible.should be_true
+      end
+      it "should set the button panel to visible" do
+        @lm.button_panel_visible.should be_true
+      end
+      it "should set the message to '<arg> was loaded.'" do
+        @lm.messages_text.should == 'test was loaded.'
+      end
+    end
+    describe "toggle_view_menu" do
+      it "should switch 'hide' to 'show' and back" do
+        @lm.toggle_view_menu(["Hide","Dump"])
+        @lm.view_menu_dump_text.should == "Show Dump"
+        @lm.toggle_view_menu(["Show","Dump"])
+        @lm.view_menu_dump_text.should == "Hide Dump"
+      end
+    end
+  end
 end

GUI/spec/painting/canvas_size_spec.rb

       it "should have a default vertical node sep of 50.0" do
         CanvasSize.node_separation(:vertical).should == 50.0
       end
+      
+      it "should return vertical node sep of 50.0 for unknown args" do
+        CanvasSize.node_separation(:whatever).should == 50.0
+      end
+    end
+    describe "vertical_node_separation" do
+      it "should return node_separation(:vertical)" do
+        CanvasSize.vertical_node_separation.should == CanvasSize.node_separation(:vertical)
+      end
     end
     describe "total_widths" do
       it "should give 0 for []" do

GUI/spec/parsers/quantum_stack_parser_spec.rb

 
 
 describe QuantumStackParser do
+  describe "class method" do
+    describe "initial_qstack_regexp" do
+      it "should equal the embeddable with a ^ at the start" do
+        QuantumStackParser.initial_qstack_regexp.source.should == "^" + QuantumStackParser.embeddable_top_level_regexp.source
+      end
+    end
+  end
   describe "multiple substack layers" do
     it "should correctly parse an item with no substacks" do
       q = QuantumStackParser.new QSVAL5

GUI/spec/spec_helper.rb

 require 'java'
 
 require 'simplecov'
-SimpleCov.start
+SimpleCov.start do
+  add_filter "GUI/spec"
+end
 
 # Override at_exit so that rspec actually terminates properly. 
 # puts did not seem to work consistently, so using err.println
   java.lang.System.exit(status)
 end
 
-where_am_i = File.expand_path(File.dirname(__FILE__))
-$LOAD_PATH << where_am_i+"/../src"
+project_dir_array = File.expand_path(File.dirname(__FILE__)).split(File::SEPARATOR)
+
+project_dir = project_dir_array.reverse.drop(2).reverse.join(File::SEPARATOR)
+%w{src lqpl_gui lib/java lib/ruby devlib/java}.each do |dir|
+  $LOAD_PATH << project_dir+"/GUI/"+ dir
+end
+$LOAD_PATH << project_dir+"/out/lqpl_gui"
 
 # java classpath
-$CLASSPATH << where_am_i+"/../lib/java/jruby-complete.jar"
-$CLASSPATH << where_am_i+"/../devlib/java/jemmy-2.3.0.0.jar"
-$CLASSPATH << where_am_i+"/../lib/java/forms_rt.jar"
-$CLASSPATH << where_am_i+"/../lib/java/monkeybars-1.1.1.jar"
-$CLASSPATH << where_am_i+"/../../out/lqpl_gui"
+$CLASSPATH << project_dir+"/GUI/lib/java/jruby-complete.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 << project_dir+"/GUI/devlib/java/" + jar+".jar"
+end
+
+
+require "fest-swing-1.2.jar"
+
+$CLASSPATH << project_dir+"/GUI/lib/java/forms_rt.jar"
+$CLASSPATH << project_dir+"/GUI/lib/java/monkeybars-1.1.1.jar"
+$CLASSPATH << project_dir+"/out/lqpl_gui"
+
+%w{BasicRobot}.each do |c|
+  java_import "org.fest.swing.core."+c
+end
+
+%w{GuiActionRunner GuiQuery GuiTask FailOnThreadViolationRepaintManager}.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
 
-TEST_QP_PATH = where_am_i+"/../testdata/qplprograms/"
+%w{JButton JLabel Frame Dialog}.each do |c|
+  java_import "org.fest.swing.core.matcher."+c+"Matcher"
+end
+TEST_QP_PATH = project_dir+"/GUI/testdata/qplprograms"
 
 require 'config/platform'
 require 'manifest'
 
+class DoDrawing
+  include Drawing
+  attr_accessor :gc
+  attr_accessor :bi
+  def initialize
+    @bi = BufferedImage.new(500,500,BufferedImage::TYPE_4BYTE_ABGR)
+    @gc = @bi.create_graphics
+  end
+end
+
+def get_sample_data_at_point(rstr,x,y)
+  s=[]
+  [0,1,2,3].each do |i|
+    s<< rstr.getSample(x,y,i)
+  end
+  s
+end
+
+def check_some_point_is_black(img,start_x,start_y,end_x,end_y)
+  rstr = img.data(Rectangle.new(start_x,start_y,end_x+1,end_y+1))
+      
+  xs = Range.new(start_x,end_x)
+  ys = Range.new(start_y,end_y)
+  (xs.any? do |x|
+     ys.any? {|y| get_sample_data_at_point(rstr,x,y)[3] == 255}
+   end).should == true
+end
+
+def check_raster_point_is_black(rstr,x,y)
+  s=get_sample_data_at_point(rstr,x,y)
+  
+  s[3].should == 255
+end
+
+def check_raster_point_is_grey(rstr,x,y)
+  s=get_sample_data_at_point(rstr,x,y)
+  s[3].should > 50
+end
+
+def check_raster_point_is_white(rstr,x,y)
+  s=get_sample_data_at_point(rstr,x,y)
+  s[3].should == 0
+end
+
+def check_raster_point_is_green(rstr,x,y)
+  s=get_sample_data_at_point(rstr,x,y)
+  
+  s[1].should_not == 0
+  s[0].should == 0
+  s[2].should == 0
+  s[3].should_not == 0
+end
+

GUI/spec/specdata/quantum_stack_data.rb

 DIAGS=[[true,QSQBZero], [true,QSVAL5], [false,AL1WITHBOTTOM]]
 
 QS3LEVEL = make_multi_sstacks("<Qstack><int>3</int><bool>True</bool>",
-  "<Classical><cint>27</cint><cint>5</cint></Classical></Qstack>",
+  "<Classical><cint>27</cint><cint>5</cint><cint>7</cint></Classical></Qstack>",
   QSQBZero,3)

GUI/spec/utility/drawing_spec.rb

+require 'spec/spec_helper'
+
+class DoDrawing
+  include Drawing
+  attr_accessor :gc
+  attr_accessor :bi
+  def initialize
+    @bi = BufferedImage.new(500,500,BufferedImage::TYPE_4BYTE_ABGR)
+    @gc = @bi.create_graphics
+  end
+end
+
+
+
+describe Drawing do
+  before :each do
+    @d = DoDrawing.new
+  end
+  describe "mid_point" do
+    it "returns (10,10) for points (0,0) and 20,20" do
+      @d.mid_point(Point.new(0,0),Point.new(20,20)).should == Point.new(10,10)
+    end
+  end
+  describe "get_string_size" do
+    it "returns a size for a regular string 'ab' w=15, h>15" do
+      s=@d.get_string_size(@d.gc,"ab")
+      s.width.should == 15.0
+      s.height.should > 15.0
+    end
+    it "returns a size for an attributed string of w=9, h>9" do
+      ab = java.text.AttributedString.new("ab");
+      ab.add_attribute(java.text.AttributedCharacterIterator::Attribute::LANGUAGE, 
+          java.util.Locale.new("en"))
+      s=@d.get_string_size(@d.gc,ab.iterator)
+      s.width.should == 9.0
+      s.height.should > 9.0  
+    end  
+  end
+  describe "draw_black_line" do
+    it "should fill in pixels on a line when drawing from 1,1 to 1,10 and nowhere else" do
+      @d.draw_black_line(@d.gc, Point.new(1,1), Point.new(1,10))
+      rstr = @d.bi.data(Rectangle.new(0,0,6,11))
+      check_raster_point_is_black(rstr,1,3)
+      check_raster_point_is_black(rstr,1,9)
+      check_raster_point_is_white(rstr,2,2)
+    end
+  end
+  describe "draw_text_to_left_of_point" do
+    it "should darken a pixel just to the left of the point" do
+      @d.draw_text_to_left_of_point(@d.gc,"N",Point.new(50,50))
+      
+      rstr = @d.bi.data(Rectangle.new(0,0,60,60))
+      check_raster_point_is_grey(rstr,48,48)
+    end
+  end
+  
+  describe "draw_text_to_right_of_point" do
+    it "should darken a pixel just to the right of the point" do
+      @d.draw_text_to_right_of_point(@d.gc,"N",Point.new(50,50))
+      
+      rstr = @d.bi.data(Rectangle.new(0,0,70,70))
+      
+      check_raster_point_is_grey(rstr,51,48)
+    end
+  end
+  describe "draw_text_centered_point" do
+    it "should darken a pixel to the left and the right of the point" do
+      @d.draw_text_centered_at_point(@d.gc,"Z",Point.new(50,50))
+      
+      rstr = @d.bi.data(Rectangle.new(0,0,70,70))
+      
+      check_raster_point_is_grey(rstr,51,49)
+      check_raster_point_is_grey(rstr,49,49)
+    end
+  end
+  
+  describe "draw_text_centered_between" do
+    it "should darken a pixel to the left and the right of the midpoint" do
+      @d.draw_text_centered_between(@d.gc,"Z",Point.new(40,50),Point.new(60,50))
+      
+      rstr = @d.bi.data(Rectangle.new(0,0,70,70))
+      
+      check_raster_point_is_grey(rstr,51,49)
+      check_raster_point_is_grey(rstr,49,49)
+    end
+  end
+  describe "draw_sized_text" do
+    it "should darken a pixel to the left and the right of the midpoint with :centered" do
+      @d.draw_sized_text(@d.gc,10,"Z",Point.new(40,50),Point.new(60,50),:centered)
+      
+      rstr = @d.bi.data(Rectangle.new(0,0,70,70))
+      
+      check_raster_point_is_grey(rstr,51,49)
+      check_raster_point_is_grey(rstr,49,49)
+    end
+    it "should darken a pixel to the right of the midpoint with :right" do
+      @d.draw_sized_text(@d.gc,10,"Z",Point.new(40,50),Point.new(60,50),:centered)
+      
+      rstr = @d.bi.data(Rectangle.new(0,0,70,70))
+      
+      check_raster_point_is_grey(rstr,51,49)
+    end
+    it "should darken a pixel to the left  of the midpoint with :left" do
+      @d.draw_sized_text(@d.gc,10,"Z",Point.new(40,50),Point.new(60,50),:left)
+      
+      rstr = @d.bi.data(Rectangle.new(0,0,70,70))
+      
+      check_raster_point_is_grey(rstr,49,49)
+    end
+  end
+  describe "draw_colour_filled_shape" do
+    it "should fill with the requested colour" do
+      @d.draw_colour_filled_shape(@d.gc,Ellipse2D::Double.new(20, 20,10,10), Color.green)
+      rstr = @d.bi.data(Rectangle.new(0,0,30,30))
+      check_raster_point_is_green(rstr,25,25)
+    end
+    it "should edge with black" do
+      @d.draw_colour_filled_shape(@d.gc,Ellipse2D::Double.new(20, 20,10,10), Color.green)
+      rstr = @d.bi.data(Rectangle.new(0,0,40,40))
+      check_raster_point_is_black(rstr,25,20)
+    end
+  end
+end

GUI/spec/utility/monkey/point_spec.rb

+require 'spec/spec_helper'
+
+describe Point do
+  describe "copy_with_x_and_y_offset" do
+    it "copies as is with nil offsets" do
+      p = Point.new(10,10).copy_with_x_and_y_offset(nil,nil)
+      p.x.should == 10
+      p.y.should == 10
+    end
+    it "adds the x offset to the base x point" do
+      p = Point.new(10,10).copy_with_x_and_y_offset(5,nil)
+      p.x.should == 15
+      p.y.should == 10
+    end
+    it "adds the y offset to the base y point" do
+      p = Point.new(10,10).copy_with_x_and_y_offset(nil,5)
+      p.x.should == 10
+      p.y.should == 15
+    end
+    it "adds the both  offsets when given" do
+      p = Point.new(10,10).copy_with_x_and_y_offset(5,8)
+      p.x.should == 15
+      p.y.should == 18
+    end
+  end
+end
+      

GUI/spec/view/descriptor_painter_spec.rb

 require 'src/panels/quantum_stack/quantum_stack_model'
 require 'src/panels/quantum_stack/quantum_stack_painter'
 
+
+
+
 describe AbstractDescriptorPainter do
+  before(:each) do
+    m=double("model_elelment")
+    m.stub(:name).and_return("Z")
+    m.stub(:value).and_return("Z")
+    m.stub(:length).and_return(0)
+    @adp=AbstractDescriptorPainter.new(m)
+  end
+  describe "model element" do
+    it "should assign the model element to whatever object is passed in" do
+      @adp.model_element= 5
+      @adp.model_element.should == 5
+    end
+  end
+  it "should return an ellipse as its shape" do
+    @adp.my_shape(Point.new(10,10)).class.should == Ellipse2D::Double
+  end
+  it "should raise a runtime exception for colour" do
+    expect {
+      @adp.my_colour
+    }.to raise_error RuntimeError,/abstract/
+  end
+  it "should have a nil image of the model" do
+    @adp.image_of_model.should be_nil
+  end
+  describe "drawing items" do
+    before :each do
+      @d=DoDrawing.new
+    end
+    it "should draw the name to the left of the point with paint_name" do
+      @adp.paint_name(@d.gc,Point.new(30,20)) # subtracts node size from x rl point is 20,20
+      rstr = @d.bi.data(Rectangle.new(0,0,30,30))
+      check_raster_point_is_grey(rstr,19,19)
+    end
+    it "should draw the Value centered on the point with paint_value" do
+      @adp.paint_value(@d.gc,Point.new(20,10)) # adds node size to y real point is 20,20
+      rstr = @d.bi.data(Rectangle.new(0,0,30,30))
+      check_raster_point_is_grey(rstr,19,19)
+      check_raster_point_is_grey(rstr,21,19)
+    end
+    it "show throw an exception for paintModelAtPoint" do
+      expect {
+        @adp.paintModelAtPoint(@d.gc,Point.new(20,20))
+      }.to raise_error RuntimeError,/abstract/
+    end
+    it "show throw an exception for paintModel" do
+      expect {
+        @adp.paintModel(@d.gc)
+      }.to raise_error RuntimeError,/paintModel/
+    end
+  end
 end
 
 describe ClassicalDescriptorPainter do
   it "should have the colour green" do
     @sd.my_colour.should == Color.green
   end
+  describe "painting" do
+    before (:each) do
+      m=double("model_elelment")
+      m.stub(:name).and_return("Z")
+      m.stub(:value).and_return("Z")
+      m.stub(:length).and_return(0)
+      @sd = DescriptorPainterFactory.make_painter(AbstractDescriptorModel.make_instance "<Classical><cint>1</cint><cbool>True</cbool><cint>14</cint></Classical>")
+      @sd.model_element= m
+      
+      @d=DoDrawing.new
+    end
+    
+    it "should draw the name to the left of the point with paint_model_at_point" do
+      @sd.paint_model_at_point(@d.gc,Point.new(30,20)) # subtracts node size from x rl point is 20,20
+      rstr = @d.bi.data(Rectangle.new(0,0,30,30))
+      check_raster_point_is_grey(rstr,19,19)
+    end
+    it "should draw the Value centered on the point with paint_value" do
+      @sd.paint_model_at_point(@d.gc,Point.new(20,10)) # adds node size to y real point is 20,20
+      rstr = @d.bi.data(Rectangle.new(0,0,30,30))
+      check_raster_point_is_grey(rstr,19,19)
+      check_raster_point_is_grey(rstr,21,19)
+    end
+    
+    it "should draw a green circle centered on the point with paint_value" do
+      @sd.paint_model_at_point(@d.gc,Point.new(20,20)) # adds node size to y real point is 20,20
+      rstr = @d.bi.data(Rectangle.new(0,0,30,30))
+      check_raster_point_is_green(rstr,20,20)
+    end
+  end
 end
 
 describe DataDescriptorPainter do
   it "should have the colour magenta" do
     @sd.my_colour.should == Color.magenta
   end
+  
+  it "should return a Rectangle as its shape" do
+    @sd.my_shape(Point.new(10,10)).class.should == Rectangle2D::Double
+  end
 end
 
 describe QubitDescriptorPainter do

GUI/spec/view/quantum_stack_painter_spec.rb

 require 'src/panels/quantum_stack/quantum_stack_model'
 require 'src/panels/quantum_stack/quantum_stack_painter'
 
+      
 describe QuantumStackPainter do
+  before :each do
+    st = double("StackTranslation")
+    st.stub(:reverse_lookup, :nil? => false) do |val|
+      case val
+      when "1" then "@p"
+      when "2" then "@q"
+      when "3" then "superreallylongnametoforceleftbigger"
+      else val
+      end
+    end
+    
+    @d=DoDrawing.new
+    qh = QuantumStackModel.new
+    qh.stack_translation = st
+    qh.quantum_stack = QSQBHAD
+    @qshad = QuantumStackPainter.new(qh)
+    qv = QuantumStackModel.new
+    qv.stack_translation = st
+    qv.quantum_stack = QSVAL5
+    @qsval = QuantumStackPainter.new(qv)
+    qb = QuantumStackModel.new
+    qb.stack_translation = st
+    qb.quantum_stack = "<bottom/>"
+    @qsb = QuantumStackPainter.new(qb)
 
-
-  describe "get_preferred_size_of_model" do
-
-    it "should cache the size after the first call"
-    it "should check if the model element is bottom and return "
-    it "should request the size of all substacks on the first call when not bottom"
-    it "should request the size of the descriptor on the first call when not bottom"
-
+    qi = QuantumStackModel.new
+    qi.stack_translation = st
+    qi.quantum_stack = QSINT
+    @qsint = QuantumStackPainter.new(qi)
+    
+    qj = QuantumStackModel.new
+    qj.stack_translation = st
+    qj.quantum_stack = C1WITHBOTTOM
+    @qsi_ss_bottom = QuantumStackPainter.new(qj)
+    
+    qk = QuantumStackModel.new
+    qk.stack_translation = st
+    qk.quantum_stack = QS3LEVEL
+    @qsi_three_ss = QuantumStackPainter.new(qk)
+    
+    qb = QuantumStackModel.new
+    qb.stack_translation = st
+    qb.quantum_stack = "<bottom/>"
+    @qbottom = QuantumStackPainter.new(qb)
+    
+  end
+  describe "substack_label_placement" do
+    it "returns :right for a single substack, index 0" do
+      @qsi_ss_bottom.substack_label_placement(0).should == :right
+    end
+    it "returns :left for ind =0 with 4 substacks" do
+      @qshad.substack_label_placement(0).should == :left
+    end
+    it "returns :left for ind =1 with 4 substacks" do
+      @qshad.substack_label_placement(1).should == :left
+    end
+    it "returns :right for ind =2 with 4 substacks" do
+      @qshad.substack_label_placement(2).should == :right
+    end
+    it "returns :left for ind =3 with 4 substacks" do
+      @qshad.substack_label_placement(3).should == :right
+    end
+    
+    it "returns :left for ind =0 with 3 substacks" do
+      @qsi_three_ss.substack_label_placement(0).should == :left
+    end
+    it "returns :right for ind =1 with 3 substacks" do
+      @qsi_three_ss.substack_label_placement(1).should == :right
+    end
+    it "returns :right for ind =2 with 3 substacks" do
+      @qsi_three_ss.substack_label_placement(2).should == :right
+    end
+  end
+  describe "substack_label" do
+    it "returns the string '27' for index 0 of qsi_three_ss" do
+      @qsi_three_ss.substack_label(0).should == "27"
+    end
+    it "returns the string '5' for index 1 of qsi_three_ss" do
+      @qsi_three_ss.substack_label(1).should == "5"
+    end
+    it "returns the string '7' for index 2 of qsi_three_ss" do
+      @qsi_three_ss.substack_label(2).should == "7"
+    end
+    it "returns 'Nil for model descriptor' for stack==bottom" do
+      @qbottom.substack_label(0).should == 'Nil for model descriptor'
+    end
+  end
+  describe "sub_stack_sizes" do
+    before :each do
+    end
+    it "should return an empty array when no substacks" do
+      @qsb.sub_stack_sizes(@d.gc).should == []
+    end
+    it "should return an array of len 4 when there are four substacks" do
+      @qshad.sub_stack_sizes(@d.gc).length.should == 4
+    end
+  end
+  describe "paint_substack" do
+    it "should put a black line at the top point to the paint point" do
+      @qsi_ss_bottom.paint_substack(@d.gc,0,Point.new(10,10),Point.new(10,30))
+      rstr = @d.bi.data(Rectangle.new(0,0,30,30))
+      check_raster_point_is_black(rstr,10,11)
+      check_raster_point_is_black(rstr,10,20)
+      check_raster_point_is_black(rstr,10,29)
+    end
   end
   
-  describe "sizing" do
-    before(:each) do
-      st = double("StackTranslation")
-      st.stub(:reverse_lookup, :nil? => false) do |val|
-        case val
-        when "1" then "@p"
-        when "2" then "@q"
-        when "3" then "superreallylongnametoforceleftbigger"
-        else val
-        end
-      end
-      qh = QuantumStackModel.new
-      qh.stack_translation = st
-      qh.quantum_stack = QSQBHAD
-      @qshad = QuantumStackPainter.new(qh)
-      qv = QuantumStackModel.new
-      qv.stack_translation = st
-      qv.quantum_stack = QSVAL5
-      @qsval = QuantumStackPainter.new(qv)
-      qb = QuantumStackModel.new
-      qb.stack_translation = st
-      qb.quantum_stack = "<bottom/>"
-      @qsb = QuantumStackPainter.new(qb)
-
-      qi = QuantumStackModel.new
-      qi.stack_translation = st
-      qi.quantum_stack = QSINT
-      @qsint = QuantumStackPainter.new(qi)
-      @g = BufferedImage.new(500,500,BufferedImage::TYPE_INT_RGB).graphics
-
+  describe "paint_substacks" do
+    it "should put a black line at the top point to the paint point" do
+      @qsi_ss_bottom.paint_substacks(Point.new(10,10),@d.gc)
+      rstr = @d.bi.data(Rectangle.new(0,0,30,30))
+      check_raster_point_is_black(rstr,10,11)
+      check_raster_point_is_black(rstr,10,20)
+      check_raster_point_is_black(rstr,10,29)
+    end
+  end
+  describe "paintModel" do
+    it "should set some item to black with paintModelAtPoint" do
+      @qsval.paintModelAtPoint(@d.gc,Point.new(10,10))
+      check_some_point_is_black(@d.bi,0,0,20,20)
+    end
+    
+    it "should set some item to black with paintModel" do
+      @qsval.paintModel(@d.gc)
+      check_some_point_is_black(@d.bi,0,0,40,40)
     end
+  end
+  describe "imageOfModel" do
+    it "should return an imageicon of the paint" do
+      @qsval.imageOfModel.class.should == ImageIcon
+    end
+  end
+  describe "sizing" do
     describe "bottom element size" do
       before (:each) do
-        @bottom_size = @qsb.bottom_element_size(@g)
+        @bottom_size = @qsb.bottom_element_size(@d.gc)
       end
       it "should have a left width of 6" do
         @bottom_size.left_width.should == 6.0
     end
     describe "model paint size" do
       it "should have a preferred size of width > 160 and height > 60 for the hadamard qbit" do
-        ps = @qshad.model_paint_size(@g)
+        ps = @qshad.model_paint_size(@d.gc)
         ps.left_width.should > 80.0
         ps.right_width.should > 80.0
         ps.height.should > 60.0
       end
       it "should have a preferred size of width >= 25 and height >= 28 for the value of 0.5 only" do
-        ps = @qsval.model_paint_size(@g)
+        ps = @qsval.model_paint_size(@d.gc)
         ps.left_width.should > 12.5
         ps.right_width.should > 12.5
         ps.height.should > 28.0
       end
       it "should have a preferred size > 10, 15 for bottom" do
-        ps = @qsb.model_paint_size(@g)
+        ps = @qsb.model_paint_size(@d.gc)
         ps.left_width.should > 5.0
         ps.right_width.should > 5.0
         ps.height.should > 15.0
       end
       it "should have a left size bigger than right width for qsint" do
-        @qsint.model_paint_size(@g).left_width > @qsint.model_paint_size(@g).right_width
+        @qsint.model_paint_size(@d.gc).left_width > @qsint.model_paint_size(@d.gc).right_width
       end
       it "should have a left size ~= right for the had qubit" do
-        (@qsval.model_paint_size(@g).left_width -  @qsval.model_paint_size(@g).right_width).abs.should < 2
+        (@qsval.model_paint_size(@d.gc).left_width -  @qsval.model_paint_size(@d.gc).right_width).abs.should < 2
       end
     end
   end

GUI/src/application_controller.rb

   # in your application
 
   attr_reader :lqpl_emulator_server_connection
-  @@controllers={}
+ 
 
-  java_signature "void lqpl_emulator_server_connection(Object)"
-  # def lqpl_emulator_server_connection=(sc)
-  #    @lqpl_emulator_server_connection = sc
-  #    @lqpl_emulator_server_connection.connect if !@lqpl_emulator_server_connection.connected?
-  #  end
-
-  # doing a suspenders and belt here - will assume default SC if there isn't one.
   java_signature "Object lqpl_emulator_server_connection()"
-  def lqpl_emulator_server_connection
-    @lqpl_emulator_server_connection = LqplEmulatorServerConnection.instance if !@lqpl_emulator_server_connection
-    @lqpl_emulator_server_connection.connect if !@lqpl_emulator_server_connection.connected?
+  def lqpl_emulator_server_connection(connect=true)
+    @lqpl_emulator_server_connection = LqplEmulatorServerConnection.instance if connect && !@lqpl_emulator_server_connection 
+    @lqpl_emulator_server_connection.connect if connect && !@lqpl_emulator_server_connection.connected?
     @lqpl_emulator_server_connection
   end
 
   def toggle_visibility
     visible? ? hide : show
   end
-  
-  def self.controller_from_name(name_array)
-    name_array.collect(&:to_sym).inject(nil){|memo, n| memo || @@controllers[n]}
-  end
-
-end
-
-class DumpController < ApplicationController
-  @@controllers[:Dump] = DumpController
-end
-
-class ClassicalStackController < ApplicationController
-  @@controllers[:Classical] = ClassicalStackController
-end
-
-class QuantumStackController < ApplicationController
-  @@controllers[:Quantum] = QuantumStackController
-end
-
-class ExecutableCodeController < ApplicationController
-  @@controllers[:Executing] = ExecutableCodeController
-end
 
-class StackTranslationController < ApplicationController
-  @@controllers[:Translation] = StackTranslationController
 end
-  

GUI/src/application_model.rb

-class ModelCreateError < RuntimeError 
-end
+class ModelCreateError < RuntimeError ; end
 
 class ApplicationModel
 end

GUI/src/com/drogar/lqpl/Main.java

             mainRubyFile = parts[1].replaceAll(" ", "");
         }
     }
-
       runtime.evalScriptlet("require '" + mainRubyFile + "'");
   }
 

GUI/src/communications/compiler_server_connection.rb

     nums = vstring[/(\d+,)+\d+/].gsub(/,/,'.')
     return nums
   end
+  
+  def failed?
+    @failed
+  end
 end

GUI/src/communications/connection.rb

 
   attr_accessor :port
   attr_accessor :connect_to
+  attr_accessor :my_path
 
   def initialize(port=nil)
     @port = port
     @connection = nil
     @process = nil
+    _set_up_my_path
   end
 
   java_signature "boolean is_connected()"
 
   def connect
     res = _make_connection
-    jar_path = _set_up_jar_path
     
     # puts " will try from #{jar_path}"
     if !res
         begin
           # Assume executables just below jar path 
           # Works for bundled executables.
-          _start_up_the_executable_in_a_process("#{jar_path}bin/#{@connect_to}")
+          _start_up_the_executable_in_a_process("#{@my_path}bin/#{@connect_to}")
         rescue => e1
           begin
             # assume one further .. and then over to out/bin 
             # works for rspec and cucumber 
-            _start_up_the_executable_in_a_process("#{jar_path}../out/bin/#{@connect_to}")
+            _start_up_the_executable_in_a_process("#{@my_path}../out/bin/#{@connect_to}")
           rescue => e2
             raise ServerProcessNotFound, "There was no process found on port #{@port}. Please start '#{@connect_to}'."
           end
     end
   end
   
-  def _set_up_jar_path
-    jar_path= File.expand_path(__FILE__)[Regexp.new /.*?jar!/]
-    if jar_path
-      jar_path=jar_path[5,jar_path.length - 18] #remove 'file:' from front, lqpl_gui.jar! from back
+  def _set_up_my_path
+    @my_path= File.expand_path(__FILE__)[Regexp.new /.*?jar!/]
+    if @my_path
+      #:nocov:
+      @my_path=@my_path[5,jar_path.length - 18] #remove 'file:' from front, lqpl_gui.jar! from back
+      #:nocov:
     else
-      jar_path = File.expand_path(File.dirname(__FILE__))+"/../../"
+      @my_path = File.expand_path(File.dirname(__FILE__))+"/../../"
     end
-    jar_path
   end
   
   def _start_up_the_executable_in_a_process(executable)

GUI/src/config/platform.rb

  yield if RbConfig::CONFIG["host_os"] =~ /darwin/i
 end
 
+#:nocov:
 def on_win
   yield if  RbConfig::CONFIG["host_os"] =~ /^win|mswin/i 
 end
 def not_on_mac
   yield if  !(RbConfig::CONFIG["host_os"] =~ /darwin/i)
 end
-  
+#:nocov: 
 on_mac do
   testing = java.lang.System.get_property("com.drogar.testing.fest")
   if !testing or testing != "true"

GUI/src/lqpl/lqpl_controller.rb

   set_view 'LqplView'
   set_close_action :close
   
+  attr_accessor :cmp
+  attr_accessor :sub_controllers
+  attr_accessor :dialogs
+  attr_accessor :qpl_dialog
+  
   def self.set_file_menu_actions
     { "the_menu.file_compile" => "file_compile", 
       "the_menu.file_load" => "file_load",
       Application.application.quit_handler = ExitHandler.instance
     end
   
+  #:nocov:
     not_on_mac do
       { "the_menu.file_exit" => "file_exit",
         "the_menu.help_about" => "help_about"}.each do |k,v|
           add_listener :type => :action, :components => {k => v}
       end
     end
+    #:nocov:
   end
       
   set_file_menu_actions
 
   def file_compile_action_performed
     chooser = JFileChooser.lqpl_source_file_opener
+    puts "running compile chooser"
     if chooser.show_open_dialog(self.my_frame) == JFileChooser::APPROVE_OPTION
       @cmp.compile_and_write_qpo chooser.get_selected_file.get_absolute_path
       model.messages_text = @cmp.success_or_fail_message(chooser.get_selected_file.name)
   end
 
   def file_load_action_performed
-    chooser = JFileChooser.lqpl_assembled_file_opener
-    if chooser.show_open_dialog(nil) == JFileChooser::APPROVE_OPTION
-      load_file chooser.selected_file.absolute_path
-      model.set_title_and_enable chooser.selected_file.name
+    @qpl_dialog = JFileChooser.lqpl_assembled_file_opener
+    if @qpl_dialog.show_open_dialog(nil) == JFileChooser::APPROVE_OPTION
+      load_file @qpl_dialog.selected_file.absolute_path
+      model.set_title_and_enable @qpl_dialog.selected_file.name
       initialize_sub_controllers
     else
       model.messages_text =  "QPO file load cancelled."
 
   def view_sub_panel_action_performed(e)
     command_and_sub_panel = e.action_command.scan(/\w+/)
-    ApplicationController.controller_from_name(command_and_sub_panel).instance.toggle_visibility
+    PanelController::controller_from_name(command_and_sub_panel).instance.toggle_visibility
     model.toggle_view_menu(command_and_sub_panel)
     update_view
   end
   end
 
   def step_button_action_performed
-    sc = LqplEmulatorServerConnection.instance
-    res = sc.do_step(model.step_spinner,model.recursion_spinner)
+    res = self.lqpl_emulator_server_connection.do_step(model.step_spinner,model.recursion_spinner)
     enable_and_update !(res =~ /executed/)
   end
 
 
   def trim_button_action_performed
     model.messages_text = self.lqpl_emulator_server_connection.do_trim
-    QuantumStackController.instance.set_data_from_lqpl_model(model)
-    DumpController.instance.set_data_from_lqpl_model(model)
+    @sub_controllers.each {|sc| sc.set_data_from_lqpl_model(model) if sc.update_on_lqpl_model_trim}
     update_view
   end
 end

GUI/src/lqpl/lqpl_menu.rb

     menu_file.add(@file_load);
     menu_file.add(@file_compile);
     menu_file.add(@file_simulate);
-
+    #:nocov:
     not_on_mac do
       @file_exit = JMenuItem.new("Exit")
       menu_file.add(@file_exit)
     end
+    #:nocov:
     menu_file
   end
 
     menu_view
   end
   
+    #:nocov:
   def init_help_menu mbar
     not_on_mac do
       menu_help = JMenu.new("Help")
       mbar.add(menu_help)
     end
   end
+    #:nocov:
 
 end
-
 $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
 require 'manifest'
 

GUI/src/manifest.rb

 # Monkeybars to operate.
 
 require 'resolver'
-
+#:nocov:
 def monkeybars_jar path
   Dir.glob(path).select { |f| f =~ /(monkeybars-)(.+).jar$/}.first
 end
     end
     add_to_classpath mbj
 end
+#:nocov:
 
 
 require 'monkeybars'
 require 'dialogs/parsers/simulate_results_parser'
 require 'painting/canvas_size'
 require 'application_model'
+require 'panels/panel_controller'
 
 %w{server_process_not_found invalid_input}.each do |f|
   require "exceptions/"+f

GUI/src/panels/classical_stack/classical_stack_controller.rb

-class ClassicalStackController < ApplicationController
+class ClassicalStackController < PanelController
   set_model 'ClassicalStackModel'
   set_view 'ClassicalStackView'
   set_close_action :hide

GUI/src/panels/dump/dump_controller.rb

-class DumpController < ApplicationController
+class DumpController < PanelController
   set_model 'DumpModel'
   set_view 'DumpView'
   set_close_action :hide
   def get_dump_data
     model.text
   end
+  
+  def update_on_lqpl_model_trim
+    true
+  end
 end

GUI/src/panels/executable_code/executable_code_controller.rb

-class ExecutableCodeController < ApplicationController
+class ExecutableCodeController < PanelController
   set_model 'ExecutableCodeModel'
   set_view 'ExecutableCodeView'
   set_close_action :hide

GUI/src/panels/panel_controller.rb

+class PanelController < ApplicationController
+  
+  @@controllers={}
+  def self.controller_from_name(name_array)
+    name_array.collect(&:to_sym).inject(nil){|memo, n| memo || @@controllers[n]}
+  end
+
+  def update_on_lqpl_model_trim
+    false
+  end
+  
+end
+
+
+class DumpController < PanelController
+  @@controllers[:Dump] = DumpController
+end
+
+class ClassicalStackController < PanelController
+  @@controllers[:Classical] = ClassicalStackController
+end
+
+class QuantumStackController < PanelController
+  @@controllers[:Quantum] = QuantumStackController
+end
+
+class ExecutableCodeController < PanelController
+  @@controllers[:Executing] = ExecutableCodeController
+end
+
+class StackTranslationController < PanelController
+  @@controllers[:Translation] = StackTranslationController
+end
+  

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

     raise ModelCreateError
   end
 
-
-  
-  def length
-    return @value.length
-  end
-
   def substack_labels
     nil
   end

GUI/src/panels/quantum_stack/quantum_stack_controller.rb

-class QuantumStackController < ApplicationController
+class QuantumStackController < PanelController
   set_model 'QuantumStackModel'
   set_view 'QuantumStackView'
 
     model.quantum_stack =  lqpl_emulator_server_connection.get_qstack tree_depth,recursion_depth
     update_view
   end
+    
+  def update_on_lqpl_model_trim
+    true
+  end
 end

GUI/src/panels/quantum_stack/quantum_stack_painter.rb

   end
 
   def substack_label(index)
-    d = @model_element.descriptor.substack_labels
+    d = @model_element.descriptor.substack_labels if @model_element.descriptor
     return d[index].to_s if d
     "Nil for model descriptor"
     #"#{@model_element.descriptor.substack_labels[index]}"

GUI/src/panels/stack_translation/stack_translation_controller.rb

-class StackTranslationController < ApplicationController
+class StackTranslationController < PanelController
   set_model 'StackTranslationModel'
   set_view 'StackTranslationView'
   set_close_action :hide

GUI/src/resolver.rb

+
 module Monkeybars
   class Resolver
     IN_FILE_SYSTEM = :in_file_system
     # Returns a const value indicating if the currently executing code is being run from the file system or from within a jar file.
     def self.run_location
       if File.expand_path(__FILE__) =~ /\.jar\!/
+        #:nocov:#
         IN_JAR_FILE
+        #:nocov:#
       else
         IN_FILE_SYSTEM
       end
   def add_to_classpath(path)
     $CLASSPATH << get_expanded_path(path)
   end
-  
+  #:nocov:#
   def add_to_load_path(path)
     $LOAD_PATH << get_expanded_path(path)
   end
-  
+  #:nocov:#
   private
   def get_expanded_path(path)
     resolved_path = File.expand_path(File.dirname(__FILE__) + "/" + path.gsub("\\", "/"))

GUI/src/utility/drawing.rb

 module Drawing
   def draw_text_centered_at_point(g,text, point)
       text_bounds = get_string_size(g,text)
-      g.draw_string(text, point.x-(text_bounds.width*0.5), point.y+(text_bounds.height * 0.5))
+      g.draw_string(text, point.x-(text_bounds.width*0.5), point.y)
   end
 
   def draw_text_centered_between(g,text, point1, point2)
-      draw_centered_text(g,text,mid_point(point1, point2))
+      draw_text_centered_at_point(g,text,mid_point(point1, point2))
   end
   
   def mid_point(point1, point2)
+One of the goals of this project is to have a full suite of automated tests.
+
+In the JRuby portion of this, we use FEST for testing of the swing components, Cucumber
+to run "acceptance" tests and rspec to run unit tests. In each of those, we use ruby's
+'simplecov' gem to determine test coverage. However, there are a few issues with these
+combinations:
+
+ - With Cucumber, FEST and simplecov, the coverage analysis is incomplete. Only the static
+   portions of the code are recorded. Accordingly, even though many items are actually exercised
+   (e.g., the opening of file dialogs in lqpl_controller), they are not recorded.
+
+ - With rspec, FEST and simplecov, the coverage analysis is complete, but FEST will not drive
+   any items that are opened. Hence, we can not add unit tests for methods such as the opening
+   of the file dialogs in lqpl_controller.
+
+ - Some items are only run on Windows or Linux computers - testing is intended to be run on 
+   a Mac, therefore these are surrounded with :nocov: tags to remove them from the stats.
+
+Due to the first two points here, the coverage goal for the project GUI will only be 90%.
+
+
+In the Haskell portions, the system was completely written prior to embracing a test driven
+development strategy. Test will be retrofitted as time permits or as code changes are made.
+Hspec is used in testing the Haskell code. We intend to add in hpc for coverage in the future.

features/compile_an_lqpl_program.feature

   I want the program allow me to choose a "*.qpl" program and create a corresponding "*.qpo" file
   so I can start experimenting with LQPL
 
+	@wip
   Scenario: I compile a simple qpl program
     Given I select "Compile" from the "File" menu
     And I load "coin.qpl" from the project directory "GUI/testdata/qplprograms"

features/support/env.rb

 require 'simplecov'
-SimpleCov.start
+SimpleCov.start do
+  add_filter "features"
+  nocov_token = ":nocov:"
+end
 
 if not (defined? RUBY_ENGINE && RUBY_ENGINE == 'jruby')
   abort 'Sorry - Feature tests of LQPL requires JRuby. You appear to be running or defaulted to some other ruby engine.'
 end
 
-where_i_am = File.expand_path(File.dirname(__FILE__))
-$project_dir = where_i_am +"/../../"
+project_dir_array = File.expand_path(File.dirname(__FILE__)).split(File::SEPARATOR)
+
+project_dir = project_dir_array.reverse.drop(2).reverse.join(File::SEPARATOR)
+
 
 %w{src lqpl_gui lib/java lib/ruby devlib/java}.each do |dir|
-  $LOAD_PATH << where_i_am+"/../../GUI/"+ dir
+  $LOAD_PATH << project_dir+"/GUI/"+ dir
 end
-$LOAD_PATH << where_i_am+"/../../out/lqpl_gui"
+$LOAD_PATH << project_dir+"/out/lqpl_gui"
 
 
 require 'java'
 
-$CLASSPATH << where_i_am+"/../../out/lqpl_gui"
+$CLASSPATH << project_dir+"/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"
+  $CLASSPATH << project_dir+"/GUI/lib/java/"+jar+".jar"
 end
 
 #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"
+  $CLASSPATH << project_dir+"/GUI/devlib/java/" + jar+".jar"
 end
 
 
 require "fest-swing-1.2.jar"
 
+%w{GuiActionRunner GuiQuery GuiTask}.each do |c|
+  java_import "org.fest.swing.edt."+c
+end
+
+#
+# Thought I'd try in the EDT thread - but nope - still doesn't get to it.
+# even tried combining with AppRunner below, still doesn't
+#
+# class ScovStarter < 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
+#     SimpleCov.start do
+#       add_filter "features"
+#     end
+#   end
+# end
+# 
+# GuiActionRunner.execute(ScovStarter.new)
+
 require "monkeybars-1.1.1.jar"
 require "forms_rt.jar"
 
-ENV['PATH'] = "#{where_i_am + '/../../out/bin'}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
+ENV['PATH'] = "#{project_dir + '/out/bin'}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
 
 java.lang.System.set_property("apple.laf.useScreenMenuBar", "false")
 java.lang.System.set_property("com.drogar.testing.fest","true")
   java_import "org.fest.swing.core."+c
 end
 
-%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"
 # 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)
    hs-source-dirs:   Compiler/src,Common/src
    extensions:       CPP
 Test-Suite utility-fileprovider-spec
-    type:             exitcode-stdio-1.0
-    main-is:          Spec/Utility/FileProviderSpec.lhs
-    build-depends:    HUnit,hspec,QuickCheck,base,directory,filepath,network,parsec,process,unix
-    hs-source-dirs:   Compiler/src,Common/src
-    extensions:       FlexibleInstances,CPP
+   type:             exitcode-stdio-1.0
+   main-is:          Spec/Utility/FileProviderSpec.lhs
+   build-depends:    HUnit,hspec,QuickCheck,base,directory,filepath,network,parsec,process,unix
+   hs-source-dirs:   Compiler/src,Common/src
+   extensions:       FlexibleInstances,CPP
+   ghc-options:      -fhpc
 Executable lqpl
   Main-is:           Compiler/Main.lhs
   Build-Depends:     containers,mtl,array,directory,filepath,base,transformers,parsec,hspec
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.