Showing results for png declaration form
GitHub Repo
https://github.com/Thejudokay/Ayuda-Como-Evitar-Que-Un-JFrame-Se-Abra-Varias-Veces
Thejudokay/Ayuda-Como-Evitar-Que-Un-JFrame-Se-Abra-Varias-Veces
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package Formularios; import java.awt.Dimension; import java.awt.Toolkit; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import javax.swing.ImageIcon; import javax.swing.JOptionPane; public class IngresoDeClientes extends javax.swing.JFrame { Connection con; CallableStatement st; ResultSet r; public IngresoDeClientes() { initComponents(); this.inhabilitar(); //Inicio Del Codigo Para El Icono De Programa this.setTitle("Formulario Para El Ingreso De Clientes"); Dimension d=Toolkit.getDefaultToolkit().getScreenSize(); this.setSize((int) d.getWidth() , (int) d.getHeight()); setIconImage(new ImageIcon(getClass().getResource("/Imagenes/Iconocrediya.png")).getImage()); this.setLocationRelativeTo(null); this.setResizable(true); this.inhabilitar(); // Fin Del Codigo Para El Icono De Programa //Inicio Del Codigo Para La Conexion De Programa try{ Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); con=DriverManager.getConnection("jdbc:sqlserver://DIOSTEBENDIGA:1433;databaseName=BFCLIENTES","sa","123456"); JOptionPane.showMessageDialog(null,"Conexion De Base De Datos Exitosa"); }catch(Exception ex){JOptionPane.showMessageDialog(null, "Error De Conexion Con La Base De Datos", "Error De Comunicacion", JOptionPane.WARNING_MESSAGE);} //Fin Del Codigo Para La Conexion De Programa jdbc:sqlserver://DIOSTEBENDIGA:1433;databaseName=BFCLIENTES // jdbc:sqlserver://DIOSTEBENDIGA:1433;databaseName=BFCLIENTES } public class View_Principal extends javax.swing.JFrame { } public void inhabilitar(){ BTINuevoIngreso.setEnabled(true); BTIGuardar.setEnabled(false); BTIModificar.setEnabled(false); BTIConsultar.setEnabled(false); BTILimpiar.setEnabled(false); BTICancelar.setEnabled(false); BTIMenuPrincipal.setEnabled(true); //Caja De Texto JTICliente.setEnabled(false); JTIIdentificacion.setEnabled(false); JTIValor.setEnabled(false); JTICuota.setEnabled(false); JTIPago.setEnabled(false); JTIPorcentaje.setEnabled(false); JTIPago.setEnabled(false); JTIFechaDeInicio.setEnabled(false); JTIFechaFinal.setEnabled(false); JTITelefono.setEnabled(false); JTIObservaciones.setEnabled(false); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jPanel1 = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); jLabel5 = new javax.swing.JLabel(); jLabel6 = new javax.swing.JLabel(); jLabel7 = new javax.swing.JLabel(); jLabel8 = new javax.swing.JLabel(); jLabel9 = new javax.swing.JLabel(); jLabel10 = new javax.swing.JLabel(); JTITelefono = new javax.swing.JTextField(); JTIPorcentaje = new javax.swing.JTextField(); JTIValor = new javax.swing.JTextField(); JTIIdentificacion = new javax.swing.JTextField(); JTICliente = new javax.swing.JTextField(); JTIObservaciones = new javax.swing.JTextField(); JTIPago = new javax.swing.JComboBox<>(); JTICuota = new javax.swing.JTextField(); JTIFechaDeInicio = new javax.swing.JTextField(); jLabel11 = new javax.swing.JLabel(); JTIFechaFinal = new javax.swing.JTextField(); jPanel4 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); jTable1 = new javax.swing.JTable(); jPanel6 = new javax.swing.JPanel(); BTINuevoIngreso = new javax.swing.JButton(); BTIGuardar = new javax.swing.JButton(); BTIModificar = new javax.swing.JButton(); BTIConsultar = new javax.swing.JButton(); BTICancelar = new javax.swing.JButton(); BTISalir1 = new javax.swing.JButton(); BTIMenuPrincipal = new javax.swing.JButton(); BTILimpiar = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { formWindowClosing(evt); } }); jPanel1.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 204, 255), 2, true)); jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 204, 255), 2, true), "Registro De Cliente", javax.swing.border.TitledBorder.RIGHT, javax.swing.border.TitledBorder.TOP, new java.awt.Font("Times New Roman", 3, 14))); // NOI18N jLabel2.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel2.setText("Cliente"); jLabel3.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel3.setText("Identificacion"); jLabel4.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel4.setText("Valor Prestado"); jLabel5.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel5.setText("Cuota"); jLabel6.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel6.setText("Porcentaje"); jLabel7.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel7.setText("Pago"); jLabel8.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel8.setText("Fecha De Inicio"); jLabel9.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel9.setText("Telefono"); jLabel10.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel10.setText("Observaciones"); JTITelefono.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { JTITelefonoActionPerformed(evt); } }); JTIIdentificacion.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { JTIIdentificacionActionPerformed(evt); } }); JTIIdentificacion.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { JTIIdentificacionKeyTyped(evt); } }); JTICliente.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { JTIClienteActionPerformed(evt); } }); JTIPago.setFont(new java.awt.Font("Times New Roman", 2, 14)); // NOI18N JTIPago.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Diario", "Semanal", "Quincenal", "Mensual" })); JTIPago.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); jLabel11.setFont(new java.awt.Font("Times New Roman", 3, 14)); // NOI18N jLabel11.setText("Fecha Final"); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel3)) .addGap(18, 18, Short.MAX_VALUE) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(JTICliente, javax.swing.GroupLayout.DEFAULT_SIZE, 173, Short.MAX_VALUE) .addComponent(JTIIdentificacion, javax.swing.GroupLayout.DEFAULT_SIZE, 173, Short.MAX_VALUE))) .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel4) .addComponent(jLabel5)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(JTIValor, javax.swing.GroupLayout.DEFAULT_SIZE, 173, Short.MAX_VALUE) .addComponent(JTICuota))) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel6) .addComponent(jLabel7) .addComponent(jLabel8)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(JTIFechaDeInicio) .addComponent(JTIPorcentaje, javax.swing.GroupLayout.DEFAULT_SIZE, 173, Short.MAX_VALUE) .addComponent(JTIPago, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel11) .addGap(54, 54, 54) .addComponent(JTIFechaFinal)) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel9) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(JTITelefono, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel10) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 46, Short.MAX_VALUE) .addComponent(JTIObservaciones, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(JTICliente, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(JTIIdentificacion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel3)) .addGap(18, 18, 18) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel4) .addComponent(JTIValor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(JTICuota, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel5)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(JTIPorcentaje, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel6)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(JTIPago, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel7)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel8) .addComponent(JTIFechaDeInicio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel11) .addComponent(JTIFechaFinal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel9) .addComponent(JTITelefono, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel10) .addComponent(JTIObservaciones, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 204, 255), 2, true), "Personal Registrado", javax.swing.border.TitledBorder.RIGHT, javax.swing.border.TitledBorder.TOP, new java.awt.Font("Times New Roman", 3, 14))); // NOI18N jTable1.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null}, {null, null, null, null, null, null, null, null, null} }, new String [] { "Cliente", "Identificacion", "Valor Prestado", "Cuota", "Porcentaje", "Pago", "Fecha", "Telefono", "Observaciones" } )); jScrollPane1.setViewportView(jTable1); javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1) .addContainerGap()) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addContainerGap()) ); jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 204, 255), 2, true), "Botones De Accion", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.TOP, new java.awt.Font("Times New Roman", 3, 14))); // NOI18N BTINuevoIngreso.setFont(new java.awt.Font("Times New Roman", 3, 18)); // NOI18N BTINuevoIngreso.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Imagenes/Nuevo.png"))); // NOI18N BTINuevoIngreso.setText("Nuevo"); BTINuevoIngreso.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); BTINuevoIngreso.setFocusable(false); BTINuevoIngreso.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); BTINuevoIngreso.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); BTINuevoIngreso.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); BTINuevoIngreso.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { BTINuevoIngresoActionPerformed(evt); } }); BTIGuardar.setFont(new java.awt.Font("Times New Roman", 3, 18)); // NOI18N BTIGuardar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Imagenes/Ingresar.png"))); // NOI18N BTIGuardar.setText("Ingresar"); BTIGuardar.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); BTIGuardar.setFocusable(false); BTIGuardar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); BTIGuardar.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); BTIGuardar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); BTIGuardar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { BTIGuardarActionPerformed(evt); } }); BTIModificar.setFont(new java.awt.Font("Times New Roman", 3, 18)); // NOI18N BTIModificar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Imagenes/Modificar.png"))); // NOI18N BTIModificar.setText("Modificar"); BTIModificar.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); BTIModificar.setFocusable(false); BTIModificar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); BTIModificar.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); BTIModificar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); BTIConsultar.setFont(new java.awt.Font("Times New Roman", 3, 18)); // NOI18N BTIConsultar.setIcon(new javax.swing.ImageIcon("D:\\Software De Programacion\\Iconos\\Botones\\Buscar.png")); // NOI18N BTIConsultar.setText("Consultar"); BTIConsultar.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); BTIConsultar.setFocusable(false); BTIConsultar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); BTIConsultar.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); BTIConsultar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); BTIConsultar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { BTIConsultarActionPerformed(evt); } }); BTICancelar.setFont(new java.awt.Font("Times New Roman", 3, 18)); // NOI18N BTICancelar.setIcon(new javax.swing.ImageIcon("D:\\Software De Programacion\\Iconos\\Botones\\Cancelar.png")); // NOI18N BTICancelar.setText("Cancelar"); BTICancelar.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); BTICancelar.setFocusable(false); BTICancelar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); BTICancelar.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); BTICancelar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); BTICancelar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { BTICancelarActionPerformed(evt); } }); BTISalir1.setFont(new java.awt.Font("Times New Roman", 3, 18)); // NOI18N BTISalir1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Imagenes/BSalir.png"))); // NOI18N BTISalir1.setText("Salir"); BTISalir1.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); BTISalir1.setFocusable(false); BTISalir1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); BTISalir1.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); BTISalir1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); BTISalir1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { BTISalir1ActionPerformed(evt); } }); BTIMenuPrincipal.setFont(new java.awt.Font("Times New Roman", 3, 18)); // NOI18N BTIMenuPrincipal.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Imagenes/BMenuPrincipal.png"))); // NOI18N BTIMenuPrincipal.setText("Menu"); BTIMenuPrincipal.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); BTIMenuPrincipal.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); BTIMenuPrincipal.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); BTIMenuPrincipal.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); BTIMenuPrincipal.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { BTIMenuPrincipalActionPerformed(evt); } }); BTILimpiar.setFont(new java.awt.Font("Times New Roman", 3, 18)); // NOI18N BTILimpiar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Imagenes/Limpiar.png"))); // NOI18N BTILimpiar.setText("Limpiar"); BTILimpiar.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); BTILimpiar.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); BTILimpiar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); BTILimpiar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { BTILimpiarActionPerformed(evt); } }); javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); jPanel6.setLayout(jPanel6Layout); jPanel6Layout.setHorizontalGroup( jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel6Layout.createSequentialGroup() .addGap(14, 14, 14) .addComponent(BTINuevoIngreso, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(BTIGuardar, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(BTIModificar, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(BTIConsultar, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 10, Short.MAX_VALUE) .addComponent(BTILimpiar, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(BTICancelar, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(BTIMenuPrincipal, javax.swing.GroupLayout.PREFERRED_SIZE, 137, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(BTISalir1, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); jPanel6Layout.setVerticalGroup( jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel6Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(BTISalir1) .addComponent(BTIMenuPrincipal) .addComponent(BTICancelar) .addComponent(BTILimpiar) .addComponent(BTIConsultar) .addComponent(BTIModificar) .addComponent(BTIGuardar) .addComponent(BTINuevoIngreso)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jLabel1.setFont(new java.awt.Font("Times New Roman", 3, 24)); // NOI18N jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); jLabel1.setText("Formulario Para El Ingreso De Nuevos Clientes - CREDIYA"); jLabel1.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 204, 255), 2, true), "Sistema De Prestamos CREDIYA", javax.swing.border.TitledBorder.RIGHT, javax.swing.border.TitledBorder.TOP, new java.awt.Font("Times New Roman", 3, 14), new java.awt.Color(0, 204, 255))); // NOI18N jLabel1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(4, 4, 4) .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// </editor-fold> private void JTITelefonoActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: } private void JTIIdentificacionActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: } private void JTIClienteActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: } private void BTINuevoIngresoActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: BTINuevoIngreso.setEnabled(true); BTIGuardar.setEnabled(true); BTIModificar.setEnabled(true); BTIConsultar.setEnabled(true); BTILimpiar.setEnabled(true); BTICancelar.setEnabled(true); BTIMenuPrincipal.setEnabled(true); //Caja De Texto JTICliente.setEnabled(true); JTIIdentificacion.setEnabled(true); JTIValor.setEnabled(true); JTICuota.setEnabled(true); JTIPorcentaje.setEnabled(true); JTIPago.setEnabled(true); JTIFechaDeInicio.setEnabled(true); JTIFechaFinal.setEnabled(true); JTITelefono.setEnabled(true); JTIObservaciones.setEnabled(true); } private void BTISalir1ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: if (JOptionPane.showConfirmDialog(rootPane, "¿Desea Salir Del Sistema?", "Salida Del Sistema", JOptionPane.YES_NO_CANCEL_OPTION) == JOptionPane.YES_OPTION) System.exit(0); } private void BTIConsultarActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: ConsultaDeClientes obj=new ConsultaDeClientes(); obj.setVisible(true); JOptionPane.showMessageDialog(null, "Formulario Para La Consulta De Clientes"); } private void BTIGuardarActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: String Nom=this.JTICliente.getText(); int Ident=Integer.parseInt(this.JTIIdentificacion.getText()); int Val=Integer.parseInt(this.JTIValor.getText()); int Cuo=Integer.parseInt(this.JTIPago.getActionCommand()); int Porc=Integer.parseInt(this.JTIPorcentaje.getText()); String Pag=this.JTIPago.getActionCommand(); String FecI=this.JTIFechaDeInicio.getText();//JTIFechaDeInicio String FecF=this.JTIFechaFinal.getText();//JTIFechaFinal String Tel=this.JTITelefono.getText(); String Obs=this.JTIObservaciones.getText(); if (JTICliente.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese El Nombre Del Cliente","Error",JOptionPane.ERROR_MESSAGE); } else if (JTIIdentificacion.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese Numero De Identificacion","Error",JOptionPane.ERROR_MESSAGE); } else if (JTIValor.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese Valor Del Prestamo","Error",JOptionPane.ERROR_MESSAGE); } else if (JTIPago.getActionCommand().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese El Numero De Cuotas","Error",JOptionPane.ERROR_MESSAGE); } else if (JTIPorcentaje.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese El Valor Del Porcentaje","Error",JOptionPane.ERROR_MESSAGE); } else if (JTIPago.getActionCommand().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese El Tipo De Pago","Error",JOptionPane.ERROR_MESSAGE); } else if (JTIFechaDeInicio.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese La Fecha Inicial Del Prestamo ","Error",JOptionPane.ERROR_MESSAGE); } else if (JTIFechaFinal.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese La Fecha Final Del Prestamo ","Error",JOptionPane.ERROR_MESSAGE); } else if (JTITelefono.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese Un Numero Telefonico O Celular","Error",JOptionPane.ERROR_MESSAGE); } else if (JTIObservaciones.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Por Favor Ingrese Una Observacion","Error",JOptionPane.ERROR_MESSAGE); } else { try{ st=con.prepareCall("{call Guardar (?,?,?,?,?,?,?,?,??)}"); st.setString(1, Nom); st.setInt(2, Ident); st.setInt(3, Val); st.setInt(4, Cuo); st.setInt(5, Porc); st.setString(6, Pag); st.setString(7, FecI); st.setString(8, FecF); st.setString(9, Tel); st.setString(10, Obs); int rta=st.executeUpdate(); if(rta==1) { JOptionPane.showMessageDialog(null, "Datos Ingresados Correctamente"); } //este es el error que sale osea que no esta mandando para la base de datos //y en caso como me lo estas describiendome tiene que salir el mensaje este y me sale es el de }catch (Exception ex){JOptionPane.showMessageDialog(null, "No Se Guardo Correctamente", "Error De Comunicacion", JOptionPane.WARNING_MESSAGE);} } } private void BTIMenuPrincipalActionPerformed(java.awt.event.ActionEvent evt) { Menu obj=new Menu(); obj.setVisible(true); JOptionPane.showMessageDialog(null, "Menu Principal CREDIYA"); } private void BTICancelarActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: //Codigo De Limpieza JTICliente.setText(""); JTIIdentificacion.setText(""); JTIValor.setText(""); JTICuota.setActionCommand(""); JTIPorcentaje.setText(""); JTIPago.setActionCommand(""); JTIFechaDeInicio.setText(""); JTIFechaFinal.setText(""); JTITelefono.setText(""); JTIObservaciones.setText(""); //Fin //Codigo Para Cancelar BTINuevoIngreso.setEnabled(true); BTIGuardar.setEnabled(false); BTIModificar.setEnabled(false); BTIConsultar.setEnabled(false); BTILimpiar.setEnabled(false); BTICancelar.setEnabled(true); BTIMenuPrincipal.setEnabled(true); //Cajas de texto JTICliente.setEnabled(false); JTIIdentificacion.setEnabled(false); JTIValor.setEnabled(false); JTICuota.setEnabled(false); JTIPorcentaje.setEnabled(false); JTIPago.setEnabled(false); JTIFechaDeInicio.setEnabled(false); JTIFechaFinal.setEnabled(false); JTITelefono.setEnabled(false); JTIObservaciones.setEnabled(false); } private void BTILimpiarActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: JTICliente.setText(""); JTIIdentificacion.setText(""); JTIValor.setText(""); JTICuota.setActionCommand(""); JTIPorcentaje.setText(""); JTIPago.setActionCommand(""); JTIFechaDeInicio.setText(""); JTIFechaFinal.setText(""); JTITelefono.setText(""); JTIObservaciones.setText(""); } //metodo que al cerrar la ventana ejecuta el codigo contenido //en el cuerpo private void formWindowClosing(java.awt.event.WindowEvent evt) { // TODO add your handling code here: //permite asignar un nuevo valor a la variable de control directamente //sin necesidad de instanciar un objeto de la clase Menu } private void JTIIdentificacionKeyTyped(java.awt.event.KeyEvent evt) { // TODO add your handling code here: } /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(IngresoDeClientes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(IngresoDeClientes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(IngresoDeClientes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(IngresoDeClientes.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new IngresoDeClientes().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JButton BTICancelar; private javax.swing.JButton BTIConsultar; private javax.swing.JButton BTIGuardar; private javax.swing.JButton BTILimpiar; private javax.swing.JButton BTIMenuPrincipal; private javax.swing.JButton BTIModificar; private javax.swing.JButton BTINuevoIngreso; private javax.swing.JButton BTISalir1; private javax.swing.JTextField JTICliente; private javax.swing.JTextField JTICuota; private javax.swing.JTextField JTIFechaDeInicio; private javax.swing.JTextField JTIFechaFinal; private javax.swing.JTextField JTIIdentificacion; private javax.swing.JTextField JTIObservaciones; private javax.swing.JComboBox<String> JTIPago; private javax.swing.JTextField JTIPorcentaje; private javax.swing.JTextField JTITelefono; private javax.swing.JTextField JTIValor; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel10; private javax.swing.JLabel jLabel11; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JLabel jLabel7; private javax.swing.JLabel jLabel8; private javax.swing.JLabel jLabel9; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel4; private javax.swing.JPanel jPanel6; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTable jTable1; // End of variables declaration private static class DatosDeIngreso { private void setCliente(String text) { } private void setObservaciones(String text) { } private void Almacenar() { } private void setFecha(String Fecha) { } private void setPago(String text) { } } }
GitHub Repo
https://github.com/Kechisgift/Graviton-
Kechisgift/Graviton-
<!-- markdownlint-disable no-inline-html --> <!-- markdownlint-disable ol-prefix --> # GRAVITON (aka the TEAL Blackbox Toolkit): Program Reporting and Testing via Dry Runs <img width="345" alt="http://cds.cern.ch/record/2315186/files/scoap3-fulltext.pdf" src="https://user-images.githubusercontent.com/291133/160721859-21a3560a-0a82-4249-aa54-5ede4c60f8d2.png"> **NOTE: to get math formulas to render here using Chrome, add the [xhub extension](https://chrome.google.com/webstore/detail/xhub/anidddebgkllnnnnjfkmjcaallemhjee/related) and reload** **DISCLAIMER**: Graviton is subject to change and makes no backwards compatability guarantees. ## Blackbox Testing Howto ### What is TEAL Blackbox Testing? TEAL Blackbox Testing lets you gain confidence that your Algorand smart contracts are correct by writing assertions and and analyzing results via dry runs. ### Why Blackbox Testing? Here are some use cases: * by allowing you to assert that certain invariants hold over a large set of inputs you gain greater confidence that your TEAL programs and AVM smart contracts work as designed * when tweaking, refactoring or optimizing your TEAL source, ensure that no regressions have occured * allows AVM developers to practice the art of TTDD (TEAL Test Driven Development) ## Simple TEAL Blackbox Toolkit Example: Program for $`x^2`$ Consider this [TEAL program](./tests/teal/lsig_square.teal) for computing $`x^2`$: ```plain #pragma version 6 arg 0 btoi callsub square_0 return // square square_0: store 0 load 0 pushint 2 // 2 exp retsub ``` We'd like to write some unit tests to validate its correctness and make **assertions** about the: * program's opcode cost * program's stack * stack's height * scratch variables * final log message (this is especially useful for [ABI-compliant programs](https://developer.algorand.org/docs/get-details/dapps/smart-contracts/ABI/)) * status (**PASS** or **REJECT**) * error conditions that are and aren't encountered Even better, before making fine-grained assertions we'd like to get a sense of what the program is doing on a large set of inputs and discover _experimentally_ these **program invariants**. Let's go through how we can do this: * start by making basic assertions and validate them using dry runs (see "**Basic Assertions**" section below) * execute the program on a sequence of inputs and explore the results (see "**EDRA: Exploratory Dry Run Analysis**" section below) * create invariants for the entire sequence and assert that the invariants hold (see "**Advanced: Asserting Invariants on a Dry Run Sequence**" section below) > Becoming a TEAL Blackbox Toolkit Ninja involves 10 steps as described below ### Dry Run Environment Setup **STEP 1**. Start with a running local node and make note of Algod's port number (for our [standard sandbox](https://github.com/algorand/sandbox) this is `4001`) **STEP 2**. Set the `ALGOD_PORT` value in [tests/clients.py](./tests/clients.py#L7) to this port number. (The port is already pre-set to `4001` because [graviton](https://github.com/algorand/graviton)'s [CI process](https://en.wikipedia.org/wiki/Continuous_integration) uses the standad sandbox) ### TEAL Program for Testing: Logic Sig v. App **STEP 3**. Next, you'll need to figure out if your TEAL program should be a Logic Signature or an Application. Each of these program _modes_ has its merits, but we won't get into the pros/cons here. From a Blackbox Test's perspective, the main difference is how external arguments are handled. Logic sigs rely on the [arg opcode](https://developer.algorand.org/docs/get-details/dapps/avm/teal/opcodes/#arg-n) while apps rely on [txna ApplicationArgs i](https://developer.algorand.org/docs/get-details/dapps/avm/teal/opcodes/#txna-f-i). In our $`x^2`$ **logic sig** example, you can see on [line 2](./tests/teal/lsig_square.teal#L2) that the `arg` opcode is used. Because each argument opcode (`arg` versus `ApplicationArgs`) is mode-exclusive, any program that takes input will execute succesfully in _one mode only_. **STEP 4**. Write the TEAL program that you want to test. You can inline the test as described here or follow the approach of `./tests/integration/blackbox_test.py` and save under `./tests/teal`. So following the inline appraoch we begin our TEAL Blackbox script with an <a name="teal">inline teal source variable</a>: ```python teal = """#pragma version 6 arg 0 btoi callsub square_0 return // square square_0: store 0 load 0 pushint 2 // 2 exp retsub""" ``` ### The TEAL Blackbox Toolkit's Utitlity Classes The TEAL Blackbox Toolkit comes with the following main classes: * `DryRunExecutor` - executes dry run's for apps and logic sigs for one or more inputs * `DryRunInspector` - encapsulates a dry run's result for a single input and allows inspecting and making assertions about it * `Invariant` - class for asserting invariants about a _sequence_ of dry run executions in a declarative fashion ### Basic Assertions When executing a dry run using `DryRunExecutor` you'll get back `DryRunInspector` objects. Such objects have **assertable properties** which can be used to validate the dry run. **STEP 4**. Back to our $`x^2`$ example, and assuming the `teal` variable is defined [as above](#teal). You can run the following: ```python from graviton.blackbox import DryRunExecutor from tests.clients import get_algod algod = get_algod() x = 9 args = (x,) inspector = DryRunExecutor.dryrun_logicsig(algod, teal, args) assert inspector.status() == "PASS" assert inspector.stack_top() == x**2 ``` Here we have executed a dry run on input $`x=9`$, then asserted that: * the program status was `PASS` * the program exited with the top of its stack containing $`x^2 = 9^2 = 81`$ Some available _assertable properties_ are: * `stack_top()` * `last_log()` * `cost()` * `status()` * `final_scratch()` * `error()` * `max_stack_height()` See the [DryRunInspector class comment](./graviton/blackbox.py#L387) for more assertable properties and details. ### Printing out the TEAL Stack Trace for a Failing Assertion **STEP 5**. The `DryRunInspector`'s `report()` method lets you print out a handy report in the case of a failing assertion. Let's intentionally break the test case above by claiming that $`x^2 = x^3`$ for $`x=2`$ and print out this _report_ when our silly assertion fails. ```python from graviton.blackbox import DryRunExecutor from tests.clients import get_algod algod = get_algod() x = 2 args = (x,) inspector = DryRunExecutor.dryrun_logicsig(algod, teal, args) # This one's ok expected, actual = "PASS", inspector.status() assert expected == actual, inspector.report( args, f"expected {expected} but got {actual}" ) # This one's absurd! x^3 != x^2 expected, actual = x**3, inspector.stack_top() assert expected == actual, inspector.report( args, f"expected {expected} but got {actual}" ) ``` If we run the test (e.g. with `pytest`) we'll see a printout such as: ```sh AssertionError: =============== <<<<<<<<<<<expected 8 but got 4>>>>>>>>>>> =============== App Trace: step | PC# | L# | Teal | Scratch | Stack --------+-------+------+-------------------+-----------+---------------------- 1 | 1 | 1 | #pragma version 6 | | [] 2 | 2 | 2 | arg_0 | | [0x0000000000000002] 3 | 3 | 3 | btoi | | [2] 4 | 7 | 6 | label1: | | [2] 5 | 9 | 7 | store 0 | 0->2 | [] 6 | 11 | 8 | load 0 | | [2] 7 | 13 | 9 | pushint 2 | | [2, 2] 8 | 14 | 10 | exp | | [4] 9 | 6 | 4 | callsub label1 | | [4] 10 | 15 | 11 | retsub | | [4] =============== MODE: ExecutionMode.Signature TOTAL COST: None =============== FINAL MESSAGE: PASS =============== Messages: ['PASS'] Logs: [] =============== -----BlackBoxResult(steps_executed=10)----- TOTAL STEPS: 10 FINAL STACK: [4] FINAL STACK TOP: 4 MAX STACK HEIGHT: 2 FINAL SCRATCH: {0: 2} SLOTS USED: [0] FINAL AS ROW: {'steps': 10, ' top_of_stack': 4, 'max_stack_height': 2, 's@000': 2} =============== Global Delta: [] =============== Local Delta: [] =============== TXN AS ROW: {' Run': 0, ' cost': None, ' last_log': '`None', ' final_message': 'PASS', ' Status': 'PASS', 'steps': 10, ' top_of_stack': 4, 'max_stack_height': 2, 's@000': 2, 'Arg_00': 2} =============== <<<<<<<<<<<expected 8 but got 4>>>>>>>>>>> =============== assert 8 == 4 ``` In particular, we can: * Track the program execution by viewing its **App Trace** * 2 was assigned to **scratch slot #0** at step 5 * the stack ended up with **4** on top * the run **PASS**'ed * Read the message parameter that was provided and which explains in English what went wrong: `expected 8 but got 4` ### EDRA: Exploratory Dry Run Analysis Let's expand our investigation from a single dry-run to multiple runs or a **run sequence**. We'll observe how _assertable properties_ depend on inputs and conjecture some program invariants. To aid in the investigation we'll generate a report in CSV format (Comma Separated Values) where: * columns represent _assertable properties_ of dry-runs, and * rows represents dry-run executions for specific inputs **STEP 6**. Back to our $`x^2`$ example, here's how to generate a report with 1 row for each of the inputs `0, 1, ... , 15`: ```python from graviton.blackbox import DryRunExecutor, DryRunInspector from tests.clients import get_algod algod = get_algod() inputs = [(x,) for x in range(16)] run_results = DryRunExecutor.dryrun_logicsig_on_sequence(algod, teal, inputs) csv = DryRunInspector.csv_report(inputs, run_results) print(csv) ``` Note that each element in the `inputs` array `(x,)` is itself a tuple as `args` given to a dry run execution need to be of type `Sequence` (remember, that these will be passed to a TEAL program which may take one, several, or no inputs at all). At this point, you'll be able to look at your [dry run sequence results](./graviton/blackbox.py#L752) and conduct some analysis. For the $`x^2`$ example, after loading the CSV in Google sheets and reformating a bit it will look like: <img width="465" alt="image" src="https://user-images.githubusercontent.com/291133/158812699-318169e2-487c-4dac-b97b-a9db8148b638.png"> Pointing out some interesting results: * column `D` **Arg 00** has the input $`x`$ (it's the argument at index 0) * column `A` contains the **Run** number * column `E` **top of stack** is the value at program's termination, i.e. $`x^2`$ * column `B` **Status** of each runs **PASS**es _except for **Run 1** with **Arg 00** = 0_. (The first run **REJECT**s because $`0^2 = 0`$ and TEAL programs reject when the top of the stack is 0) * column `G` shows scratch slot **s@000** which stores the value of $`x`$ (except for the case $`x = 0`$ in which appears empty; in fact, slots always default to the zero value and an **<a name="0val-artifact">artifact</a>** of dry-runs is that they do not report when 0-values get stored into previously empty slots as no state change actually occurs) * column `F` **max stack height** is always 2. The final observation makes sense because there is no branching or looping in the program. **STEP 7**. We can re-cast the observed effects in `Columns E, B, G, F` as **invariants** written in Python as follows: * `inspector.stack_top() == x ** 2` * `inspector.max_stack_height() == 2` * `inspector.status() == ("REJECT" if x == 0 else "PASS")` * `inspector.final_scratch() == ({} if x == 0 else {0: x})` ### Advanced: Asserting Invariants on a Dry Run Sequence The final and most advanced topic we'll cover is how to assert that invariants hold on a sequence of inputs. Lets take the information we gleaned in our EDRA CSV report, and create an integration test out of it. There are two ways to achieve this goal: * Procedural invariant assertions * Declarative invariant assertions #### Procedural Blackbox Dry Run Sequence Assertions **STEP 8**. The procedural approach takes the _invariants_ and simply asserts them inside of a for loop that iterates over the inputs and dry runs. One can call each dry run execution independently, or use `DryRunExecutor`'s convenience methods `dryrun_app_on_sequence()` and `dryrun_logicsig_on_sequence()`. For example, let's assert that the above invariants hold for all $`x \leq 100`$: ```python from graviton.blackbox import DryRunExecutor from tests.clients import get_algod algod = get_algod() inputs = [(x,) for x in range(101)] dryrun_results = DryRunExecutor.dryrun_logicsig_on_sequence(algod, teal, inputs) for i, inspector in enumerate(dryrun_results): args = inputs[i] x = args[0] assert inspector.stack_top() == x**2 assert inspector.max_stack_height() == 2 assert inspector.status() == ("REJECT" if x == 0 else "PASS") assert inspector.final_scratch() == ({} if x == 0 else {0: x}) ``` #### Declarative Blackbox Dry Run Sequence Assertions **STEP 9**. The TEAL Blackbox Toolkit also allows for declarative style test writing. Let's define some invariants for a particular sequence of `lsig_square` TEAL program dry runs: ```python scenario = { "inputs": [(i,) for i in range(100)], "invariants": { DRProp.stackTop: lambda args: args[0] ** 2, DRProp.maxStackHeight: 2, DRProp.status: lambda i: "REJECT" if i[0] = 0 else "PASS", DRProp.finalScratch: lambda args: ({} if args[0] else {0: args[0]}), }, } ``` In the parlance of the TEAL Blackbox Toolkit, a set of such declarative assertions is called a **test scenario**. Scenarios are dict's containing two keys `inputs` and `invariants` and follow [certain conventions](./graviton/invariant.py#L101). In particular: * **inputs** gives a list of tuples, each tuple representing the `args` to be fed into a single dry run execution * **invariants** gives a dict that maps [DryRunProperty](./graviton/blackbox.py#L25)'s to an invariant _predicate_ In English, letting $`x`$ be the input variable for our square function, the above **test scenario**: * provides a list of 100 tuples of the form $`(x)`$ that will serve as args. * IE: $`(0), (1), (2), ... , (99)`$ * establishes 4 different _invariants_ as follows: * the **stack's top** will contain $`x^2`$ * the **max stack height** during execution is always 2 * the executions' **status** is **PASS** except for the case $`x=0`$ * the **final scratch** will have $`x`$ stored at slot `0` except for that strange $`x=0`$ case (recall the [0-val scratch slot artifact](#0val-artifact)) Declarative invariants make use of the following: * `DryRunProperty` (aka `DRProp`): an enum that acts as a key in a scenario's assertions dict * class `Invariant` * its constructor takes in a predicate (there are [4 kinds of predicates](#predicate)) and returns a callable that is used for runtime assertions * method `inputs_and_assertions()` validates a scenario and extracts out its assertions * method `dryrun_assert()` evaluates the dry-run sequence using the constructed `SequenceAssertion` To employ the declarative test scenario above write the following: ```python from graviton.blackbox import ( DryRunExecutor, DryRunProperty as DRProp, ExecutionMode, ) from graviton.invariant import Invariant from tests.clients import get_algod algod = get_algod() scenario = { "inputs": [(i,) for i in range(100)], "invariants": { DRProp.stackTop: lambda args: args[0] ** 2, DRProp.maxStackHeight: 2, DRProp.status: lambda args: "REJECT" if args[0] == 0 else "PASS", DRProp.finalScratch: lambda args: ({0: args[0]} if args[0] else {}), }, } # Validate the scenario and dig out inputs/invariants: inputs, invariants = Invariant.inputs_and_invariants( scenario, ExecutionMode.Signature ) # Execute the dry runs and obtain a sequence of DryRunInspectors: inspectors = DryRunExecutor.dryrun_logicsig_on_sequence(algod, teal, inputs) # Invariant assertions on sequence: for dr_property, invariant in invariants.items(): invariant.validates(dr_property, inputs, inspectors) ``` **STEP 10**. _**Deep Dive into Invariants via Exercises**_ Four kinds of <a name="predicate">predicates</a> are used to define _invariants_: 1. _simple python types_ - these are useful in the case of _constant_ invariants. In the above `maxStackHeight` is asserted to _**ALWAYS**_ equal 2 by using `2` in the declaration: `DRProp.maxStackHeight: 2` 2. _1-variable functions_ -these are useful when you have a python "simulator" for the invariant. In the above `stackTop` is asserted to be $`x^2`$ by using a lambda expression for $`x^2`$ in the declaration: `DRProp.stackTop: lambda args: args[0] ** 2` 3. _dictionaries_ of type `Dict[Tuple, Any]` - these are useful when you want to assert a discrete set of input-output pairs. For example, if you have 4 inputs that you want to assert are being squared, you could use ```python DRProp.stackTop: { (2,): 4, (7,): 49, (13,): 169, (11,): 121, } ``` >Note that this case illustrates why each `args` container should be a tuple intead of a list. In order to specify a map from args to expected, we need to make `args` a key in a dictionary. Python dictionary keys must be hashable and lists are _not hashable_ while tuples _are_ hashable, hence the tuple-requirement. 4. _2-variable functions_ -these are useful when your assertion is more subtle than out-and-out equality. For example, suppose you want to assert that the `cost` of each run is _between_ $`2n \pm 5`$ where $`n`$ is the first arg of the input. Then you could declare: `DRProp.cost: lambda args, actual: 2*args[0] - 5 <= actual <= 2*args[0] + 5` #### **EXERCISE A** Convert each of the lambda expressions used above to dictionaries that assert the same thing. #### **EXERCISE B** Use 2-variable functions in order to _ignore_ the weird $`x=0`$ cases above. #### _PARTIAL SOLUTIONS to EXERCISES_ **Exercise A Partial Solution**. For `DRProp.status`'s declaration you could define the `dict` using dictionary comprehension syntax as follows: ```python DRProp.status: {(x,): "PASS" if x else "REJECT" for x in range(100)}, ``` **Exercise B Partial Solution**. For `DRProp.status`'s declaration you could ignore the case $`x=0`$ as follows: ```python DRProp.status: lambda args, actual: "PASS" == actual if args[0] else True, ``` ## Slow and Bad Fibonacci - Another Example Report [This](https://docs.google.com/spreadsheets/d/1ax-jQdYCkKT61Z6SPeGm5BqAMybgkWJa-Dv0yVjgFSA/edit?usp=sharing) is an example of `app_slow_fibonacci.teal`'s Dryrun stats: <img width="1231" alt="image" src="https://user-images.githubusercontent.com/291133/158705149-302d755f-afcc-4380-976a-ca14800c138f.png"> A few items to take note of: * $`n`$ is given by **Arg_00** * the app was **REJECT**ed for $`n = 0`$ because `fibonacci(0) == 0` is left at the top of the stack * the app was **REJECT**ed for $`n > 7`$ because of exceeding budget * the app **errored** only for $`n > 16`$ because of exceeding _dynamic_ budget * the **cost** is growing exponentially (poor algorithm design) * the **top of stack** contains `fibonacci(n)` except in the error case * the **final_log** contains `hex(fibonacci(n))` except in the error and reject cases * **max stack height** is $`2n`$ except for $`n=0`$ and the error case * you can see the final values of scratch slots **s@000** and **s@001** which are respectively $`n`$ and `fibonacci(n)` Here's an example of how [invariants can be asserted](https://github.com/algorand/graviton/blob/a8c7eab729a36503948849674ea55995d5fc4ec1/tests/integration/blackbox_test.py#L315) on this function.
GitHub Repo
https://github.com/ktczakutnyi/Software-I-C482