def fields(self, fields): fields.text_input_field = Field(label='A TextInput') fields.password_field = Field(label='A PasswordInput') fields.text_area_field = Field(label='A TextArea') fields.text_input_without_label = Field(label='A TextInput without a label') fields.cue_field = Field(label='A TextInput in a CueInput') fields.choice_field = ChoiceField([Choice(False, BooleanField(label='None selected')), ChoiceGroup('Numbers', [Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))]), ChoiceGroup('Colours', [Choice('r', Field(label='Red')), Choice('g', Field(label='Green'))]) ], label='A SelectInput') fields.multi_choice_field = MultiChoiceField([Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))], label='A SelectInput allowing multiple choices') fields.another_multi_choice_field = MultiChoiceField([Choice('a', Field(label='Newton')), Choice('b', Field(label='Archimedes')), Choice('c', Field(label='Einstein')), ], default=['a', 'c'], label='A CheckboxInput allowing multiple choices') fields.boolean_field = BooleanField(label='A CheckboxInput to toggle') fields.radio_choice_field = ChoiceField([Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))], label='A RadioButtonSelectInput') fields.fuzzy_date_field = DateField(label='A fuzzy TextInput for a Date')
def test_namespaces(): ExecutionContext().install() state_dict = {} a = Field() a.bind('x', a) # Case: namespaces change the name of the Field b = a.in_namespace('deeper') assert a.name == 'x' assert b.name == 'deeper-x' # Case: namespaces can be nested c = b.in_namespace('even') assert c.name == 'even-deeper-x' # Case: a Field *in* different namespace, but made from another share the same data a.initial_value = EmptyStub() a.input_status = EmptyStub() a.validation_error = EmptyStub() a.user_input = EmptyStub() a.parsed_input = EmptyStub() assert a.initial_value is b.initial_value is c.initial_value assert a.input_status is b.input_status is c.input_status assert a.validation_error is b.validation_error is c.validation_error assert a.user_input is b.user_input is c.user_input assert a.parsed_input is b.parsed_input is c.parsed_input
def fields(self, fields): fields.operand_a = IntegerField(label='A', required=True) fields.operand_b = IntegerField(label='B', required=True) fields.operator = ChoiceField([ Choice('plus', Field(label='+')), Choice('divide', Field(label='÷')) ], required=True)
def fields(self, fields): fields.amount = IntegerField(label='Total amount', required=True) fields.amount_or_percentage = ChoiceField([ Choice('amount', Field(label='Amount')), Choice('percentage', Field(label='Percentage')) ], label='Allocate using', required=True)
def new_field(self): choices = [ Choice(1, Field(label='One')), Choice(2, Field(label='Two')) ] field = ChoiceField(choices) field.bind('field', self) return field
def __init__(self, view): super().__init__(view) table = Table(view, caption_text='All my friends', summary='Summary for screen reader') table.with_data( [StaticColumn(Field(label='Row Number'), 'row'), StaticColumn(Field(label='Alpha'), 'alpha')], table_fixture.data ) self.add_child(table)
def field_metadata(self, fixture): """Fields provide metadata about their contents""" field = Field(default=2, required=True, label='A field') field.bind('fieldname', fixture.model_object) vassert( field.label == 'A field' ) vassert( field.required ) vassert( field.variable_name == 'fieldname' ) vassert( field.get_model_value() == 2 )
def meaning_of_required(self, fixture): """Making a Field required means adding a RequiredConstraint to it""" # Case: construction with default value for required field = Field() vassert( not field.required ) # Case: construction with required=True field = Field(required=True) vassert( field.required ) vassert( field.get_validation_constraint_named(RequiredConstraint.name) )
def tailored_access_make_inputs_security_sensitive(self, fixture): """An Input is sensitive if explicitly set as sensitive, or if its Fields has non-defaulted mechanisms for determiing access rights.""" form = Form(fixture.view, 'some_form') field = Field(default=3, readable=Allowed(True)) field.bind('field_name', EmptyStub()) input_widget = TextInput(form, field) vassert(input_widget.is_security_sensitive)
def __init__(self, view): super(MainWidget, self).__init__(view) table = Table(view) table.with_data([ StaticColumn(Field(label='Another Row Number'), 'row_another'), StaticColumn(Field(label='Row Number'), 'row'), scenario.total_column ], table_fixture.data, footer_items=[EmptyStub(total=123)]) self.add_child(table)
def equal_to_constraint(self, fixture): other_field = Field(label='other') equal_to_constraint = EqualToConstraint(other_field, '$label, $other_label') other_field.set_user_input('should be equal to this string', ignore_validation=True) #case: valid input with expected(NoException): equal_to_constraint.validate_parsed_value('should be equal to this string' ) #case: invalid input with expected(EqualToConstraint): equal_to_constraint.validate_parsed_value('this is not equal')
def re_binding_behaviour_of_field_index(self, fixture): """FieldIndexes wont bind a field if it already is bound.""" model_object1 = EmptyStub() model_object2 = EmptyStub() bound_field = Field() bound_field.bind('bound_field', model_object2) vassert( bound_field.is_bound ) vassert( bound_field.bound_to is model_object2 ) index = FieldIndex(model_object1) index.new_name_for_bound_field = bound_field vassert( index.new_name_for_bound_field.name is 'bound_field' ) vassert( bound_field.bound_to is model_object2 )
def test_re_binding_behaviour_of_field_index(fixture): """FieldIndexes wont bind a field if it already is bound.""" model_object1 = EmptyStub() model_object2 = EmptyStub() bound_field = Field() bound_field.bind('bound_field', model_object2) assert bound_field.is_bound assert bound_field.bound_to is model_object2 index = FieldIndex(model_object1) index.new_name_for_bound_field = bound_field assert index.new_name_for_bound_field.name is 'bound_field' assert bound_field.bound_to is model_object2
def __init__(self, view): super(WidgetWithSubResource, self).__init__(view) factory = ParameterisedSubResource.factory( 'uniquename', {'path_param': Field(required=True)}, 'arg to factory', factory_kwarg='kwarg to factory') view.add_resource_factory(factory)
def events(self, events): events.upload_file = Event(label=_('Upload'), action=Action(self.upload_file)) events.remove_file = Event(label=_('Remove'), action=Action(self.remove_file, ['filename']), filename=Field(required=True))
def fields(self, fields): fields.name = Field(label='Name', required=self.can_be_added(), writable=Action(self.can_be_added)) fields.email_address = EmailField(label='Email', required=True, writable=Action(self.can_be_edited))
def __init__(self, view, address_book_ui): super().__init__(view) self.rows = QueryAsSequence(Session.query(Address).order_by( Address.id), map_function=lambda address: Row(address)) self.add_child(H(view, 1, text='Addresses')) def make_link_widget(view, row): return A.from_bookmark( view, address_book_ui.get_edit_bookmark(row.address, description='Edit')) columns = [ StaticColumn(Field(label='Name'), 'name', sort_key=Address.name), StaticColumn(EmailField(label='Email'), 'email_address', sort_key=Address.email_address), StaticColumn(IntegerField(label='Zip'), 'zip_code', sort_key=Address.zip_code), DynamicColumn('', make_link_widget) ] table_layout = TableLayout(striped=True) data_table = DataTable(view, columns, self.rows, caption_text='All my friends', summary='Summary for screen reader', table_layout=table_layout, css_id='address_data') self.add_child(data_table)
def test_checked_arguments(web_fixture, remote_method_fixture, argument_scenarios): """A CheckedRemoteMethod checks and marshalls its parameters using Fields.""" fixture = argument_scenarios def callable_object(anint=None, astring=None): fixture.method_kwargs = {'anint': anint, 'astring': astring} return '' remote_method = CheckedRemoteMethod(web_fixture.view, 'amethod', callable_object, MethodResult(), idempotent=fixture.idempotent, anint=IntegerField(), astring=Field(), disable_csrf_check=True) wsgi_app = remote_method_fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) if fixture.idempotent: browser.open( '/_amethod_method?anint=5&astring=SupercalifraGilisticexpialidocious' ) else: browser.post('/_amethod_method', { 'anint': '5', 'astring': 'SupercalifraGilisticexpialidocious' }) assert fixture.method_kwargs == { 'anint': 5, 'astring': 'SupercalifraGilisticexpialidocious' }
def __init__(self, view, address_book_ui): super(AddressBookPanel, self).__init__(view) self.rows = self.initialise_rows() self.add_child(H(view, 1, text='Addresses')) form = self.add_child(Form(view, 'address_table_form')) self.define_event_handler(self.events.delete_selected) def make_link_widget(view, row): return A.from_bookmark( view, address_book_ui.get_edit_bookmark(row.address, description='Edit')) def make_checkbox_widget(view, row): return PrimitiveCheckboxInput(form, row.fields.selected_by_user) def make_delete_selected_button(view): return Button(form, self.events.delete_selected) columns = [ StaticColumn(Field(label='Name'), 'name'), StaticColumn(EmailField(label='Email'), 'email_address'), DynamicColumn('', make_link_widget), DynamicColumn(make_delete_selected_button, make_checkbox_widget) ] table = Table(view, caption_text='All my friends', summary='Summary for screen reader') table.use_layout(TableLayout(striped=True)) table.with_data(columns, self.rows) form.add_child(table)
def checked_arguments(self, fixture): """A CheckedRemoteMethod checks and marshalls its parameters using Fields.""" def callable_object(anint=None, astring=None): fixture.method_kwargs = {'anint': anint, 'astring': astring} return '' remote_method = CheckedRemoteMethod('amethod', callable_object, MethodResult(), immutable=fixture.immutable, anint=IntegerField(), astring=Field()) wsgi_app = fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) if fixture.immutable: browser.open( '/_amethod_method?anint=5&astring=SupercalifraGilisticexpialidocious' ) else: browser.post('/_amethod_method', { 'anint': '5', 'astring': 'SupercalifraGilisticexpialidocious' }) vassert(fixture.method_kwargs == { 'anint': 5, 'astring': 'SupercalifraGilisticexpialidocious' })
def fields(self, fields): fields.greyed_out_field = Field( label='Some data', default= 'a value you\'re allowed to see, but not edit, so it is greyed out', readable=Action(self.allowed_to_see), writable=Action(self.allowed_to_write))
def events(self, events): events.an_event = Event( label='click me', action=Action(self.handle_event, ['one_argument', 'another_argument']), one_argument=IntegerField(), another_argument=Field())
def add_allocation_table(self): def make_amount_input(view, allocation): return self.make_allocation_input(allocation, allocation.fields.amount) def make_percentage_input(view, allocation): return self.make_allocation_input(allocation, allocation.fields.percentage) def make_percentage_total(view, investment_order): return self.make_total_widget( investment_order.total_allocation_percentage) def make_amount_total(view, investment_order): return self.make_total_widget( investment_order.total_allocation_amount) columns = [ StaticColumn(Field(label='Fund'), 'fund', footer_label='Totals') ] columns.append( DynamicColumn('Percentage', make_percentage_input, make_footer_widget=make_percentage_total)) columns.append( DynamicColumn('Amount', make_amount_input, make_footer_widget=make_amount_total)) table = Table(self.view).with_data( columns, self.investment_order.allocations, footer_items=[self.investment_order]) self.add_child(table)
def fields(self, fields): fields.email_address = EmailField(label='Email address', required=True) fields.text = Field(label='Comment', required=True) fields.uploaded_files = FileField(allow_multiple=True, max_size_bytes=4 * 1000 * 1000, max_files=4, accept=['text/*'])
def grouped_choices(self): self.all_choices = [Choice(1, IntegerField(label='One')), Choice('2', Field(label='Two'))] self.groups = [ChoiceGroup('', self.all_choices)] self.choices = self.groups self.valid_inputs = ['1', '2'] self.input_to_value_map = {'1': 1, '2': '2'} self.expected_validation_constraint = AllowedValuesConstraint
def wrong_args_to_input(fixture): """Passing the wrong arguments upon constructing an Input results in an error.""" with expected(IsInstance): PrimitiveInput(fixture.form, EmptyStub()) with expected(IsInstance): PrimitiveInput(EmptyStub(), Field())
def test_when_initial_value_is_read(): """The initial_value of a Field is set upon first activate_global_field_data_store""" ExecutionContext().install() state_dict = {} a = Field() a.bind('x', a) a.x = 'initial value for a' assert not a.initial_value a.activate_global_field_data_store(state_dict) assert a.initial_value == a.x a.x = 'changed value' a.activate_global_field_data_store(state_dict) assert a.initial_value != a.x
def new_columns(self): return [ StaticColumn(IntegerField(label='Row Number'), 'row', sort_key=lambda i: i.row), StaticColumn(Field(label='Alpha'), 'alpha', sort_key=lambda i: i.alpha), ]
def test_fields_have_access_rights(web_fixture): """Fields have access rights for reading and for writing. By default both reading and writing are allowed. This default can be changed by passing an Action (which returns a boolean) for each kind of access which will be called to determine whether that kind of access is allowed. """ fixture = web_fixture def not_allowed(): return False # Case: the default field = Field() assert field.can_read() assert field.can_write() # Case: tailored rights field = Field(readable=Action(not_allowed), writable=Action(not_allowed)) field.bind('field_name', fixture) assert not field.can_read() assert not field.can_write()
def test_table_layout_header_options(web_fixture, layout_scenarios): """TableLayout can style a table header row.""" data = [DataItem(1, 'T'), DataItem(2, 'H'), DataItem(3, 'E')] column_definitions = [ StaticColumn(Field(label='Row Number'), 'row'), StaticColumn(Field(label='Alpha'), 'alpha') ] layout = TableLayout(heading_theme=layout_scenarios.theme) table = Table(web_fixture.view).with_data(column_definitions, data) table.use_layout(layout) if layout_scenarios.theme is not None: assert layout.widget.thead.get_attribute( 'class') == '%s' % layout_scenarios.expected_css_class else: assert not layout.widget.thead.has_attribute('class')