Widget testing TextFormField obscureText value - flutter-test

I cannot seem to find a way to widget test whether a TextFormField has obscureText set true or false.
I know that TextFormField is a wrapper around TextField, and obscureText is a property of TextField, but cannot think of a way to access obscureText within my test.
So, when I try to access obscureText I get the message: The getter 'obscureText' isn't defined for the type 'TextFormField'
Anyone know how to test obscureText property for a TextFormField?
testWidgets(
'show and hide password fields',
(
WidgetTester tester,
) async {
await tester.pumpWidget(
materialWrapper(
child: emailSignUpScreen,
),
);
final Finder passwordTextFormField = find.byKey(
const Key(
'passwordTextFormField',
),
);
final TextFormField input =
tester.widget<TextFormField>(passwordTextFormField);
expect(input.obscureText, true);
},
);

TextFormField uses EditableText to obscure it, you can just do:
final passwordTextFormField = find.descendant(
of: find.byKey(const Key('passwordTextFormField')),
matching: find.byType(EditableText),
);
final input = tester.widget<EditableText>(passwordTextFormField);
expect(input.obscureText, isTrue);

Related

action dispatch does not work after passing value in event handler function

I am learning redux and mock the teacher's code,I just change a little,but I do not know why it can not work,and I want to try plenty of ways to adjust it,but it is too little too try and nowhere could start.Below is the code causing bug I guess because the project could not work while I write a little in it.The below is almost 100% with Dan Abramov's versionhttps://embed.plnkr.co/github/eggheadio-projects/getting-started-with-redux/master/23-react-redux-extracting-container-components-visibletodolist-addtodo?show=script,preview
const Deeplists = ({ store }) => {
const [_, forceUpdate] = React.useReducer((x) => x + 1, 0);
store.subscribe(forceUpdate);
return (
<Lists
todos={deepertodos(
store.getState().todos,
store.getState().visibilityFilter
)}
onTodoClick={id=> store.dispatch({ type: "TOGGLE_TODO", id })}
/>
);
};
This is my project link:https://codepen.io/nutkin/pen/PopOamN?editors=0010
you need to avoid to use store.dispatch method and replace with connect

How to check for null widget value in dart ternary operator to display default image if null?

Hello I need some help with my flutter code
I'm loading my data from json and passing the data from one screen to another screen.
I want to use a ternary operator to check for null but keep getting errors.
I want to load a default image if there is no data, I'm getting error - failed expression: a boolean expression must not be null.
Below is a snippit of my code inside a stateful widget
widget.image contains the data for the image
class DetailScreen extends StatefulWidget {
//load json data to each section, using index provided from list page.
final herbName;
final index;
final image;
final text;
DetailScreen({this.herbName,this.index,this.image,this.text});
#override
_DetailScreenState createState() => _DetailScreenState();
}
//the code below is located inside State
BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30.0)),
color: Colors.redAccent,
image: DecorationImage(
fit: BoxFit.cover,
image: **widget.image ? NetworkImage("http://images.neopets.com/altador/altadorcup/signup_full.gif")
:
NetworkImage(widget.image),**
)),
You can try these
1. image: NetworkImage(widget.image ?? "http://images.neopets.com/altador/altadorcup/signup_full.gif")
2. image: widget.image == null ? NetworkImage("http://images.neopets.com/altador/altadorcup/signup_full.gif") : NetworkImage(widget.image);
You are getting that error because widget.image is a String (and you didn't compare it to anything). The ternary operation works with Boolean

Passing parameters from Command to Converter

I defined a new type of model element as a plug-in; let's refer to it as Foo. A Foo node in the model should translate to a section element in the view. So far, so good. I managed to do that by defining simple conversion rules. I also managed to define a new FooCommand that transforms (renames) selected blocks to Foo.
I got stuck trying to have attributes on those Foo model nodes be translated to attributes on the view elements (and vice-versa). Suppose Foos have an attribute named fooClass which should map to the view element's class attribute.
<Foo fooClass="green-foo"> should map to/from <section class="green-foo">
I can successfully receive parameters in FooCommand, but I can't seem to set them on the blocks being processed by the command:
execute(options = {}) {
const document = this.editor.document;
const fooClass = options.fooClass;
document.enqueueChanges(() => {
const batch = options.batch || document.batch();
const blocks = (options.selection || document.selection).getSelectedBlocks();
for (const block of blocks) {
if (!block.is('foo')) {
batch.rename(block, 'foo');
batch.setAttribute(block, 'fooClass', fooClass);
}
}
});
}
Below is the code for the init function in the Foo plugin, including the model→view and view→model conversions:
init() {
const editor = this.editor;
const doc = editor.document;
const data = editor.data;
const editing = editor.editing;
editor.commands.add('foo', new FooCommand(editor));
doc.schema.registerItem('foo', '$block');
buildModelConverter().for(data.modelToView, editing.modelToView)
.fromElement('foo')
.toElement(modelElement => {
const fooClass = modelElement.item.getAttribute('fooClass'));
return new ContainerElement('section', {'class': fooClass});
});
buildViewConverter().for(data.viewToModel)
.fromElement('section')
.toElement(viewElement => {
let classes = Array.from(viewElement.getClassNames());
let modelElement = new ModelElement('foo', {'fooClass': classes[0]});
return modelElement;
});
}
When I try to run the command via
editor.execute('foo', { fooClass: 'green-foo' })
I can see that the green-foo value is available to FooCommand, but the modelElement in the model→view conversion, on the other hand, has no fooClass attribute.
I'm sure I'm missing the point here and misusing the APIs. I'd be really thankful if someone could shed some light on this issue. I can provide more details, as needed.
Follow-up after initial suggestions
Thanks to #Reinmar and #jodator for their suggestion regarding configuring the document schema to allow for the custom attribute. I really thought that would have taken care of it, but no. It may have been a necessary step anyway, but I'm still unable to get the attribute value from the model element during the model→view conversion.
First, let me add an important piece of information I had left out: the CKEditor5's version I'm working with is 1.0.0-alpha2. I am aware several of the APIs are bound to change, but I would still like to get things working with the present version.
Model→view conversion
If I understand it correctly, one can either pass a string or a function to the toElement call. A question about using the latter: what exactly are the parameters passed to the function? I assumed it would be the model element (node?) to be converted. Is that the case? If so, why is the attribute set on that node via batch.setAttribute (inside a document.enqueueChanges) not available when requested? Should it be?
A sequencing problem?
Additional testing seems to indicate there's some kind of order-of-execution issue happening. I've observed that, even though the attribute is not available when I first try to read it from the modelElement parameter, it will be so if I read it again later. Let me try to illustrate the situation below. First, I'll modify the conversion code to make it use some dummy value in case the attribute value is not available when read:
buildModelConverter().for(data.modelToView, editing.modelToView)
.fromElement('foo')
.toElement(modelElement => {
let fooClass = modelElement.item.getAttribute('fooClass') || 'naught';
let viewElement = new ContainerElement('section');
viewElement.setAttribute('class', fooClass);
return viewElement;
});
Now I reload the page and execute the following instructions on the console:
c = Array.from(editor.document.getRoot().getChildren());
c[1].is('paragraph'); // true
// Changing the node from 'paragraph' to 'foo' and adding an attribute
// 'fooClass' with value 'green-foo' to it.
editor.document.enqueueChanges(() => {
const batch = editor.document.batch();
batch.rename(c[1], 'foo');
batch.setAttribute(c[1], 'fooClass', 'green-foo');
return batch;
});
c[1].is('paragraph'); // false
c[1].is('foo'); // true
c[1].hasAttribute('fooClass'); // true
c[1].getAttribute('fooClass'); // 'green-foo'
Even though it looks like the expected output is being produced, a glance at the generated view element shows the problem:
<section class="naught"/>
Lastly, even if I try to reset the fooClass attribute on the model element, the change is not reflected on the view element. Why is that? Shouldn't changes made via enqueueChanges cause the view to update?
Sorry for the very long post, but I'm trying to convey as many details as I can. Here's hoping someone will spot my mistake or misunderstanding of how the CKEditor 5's API actually works.
View not updating?
I turned to Document's events and experimented with the changesDone event. It successfully addresses the "timing" issue, as it consistently triggers only after all changes have been processed. Still, the problem of the view not updating in response to a change in the model remains. To make it clear, the model does change, but the view does not reflect that. Here is the call:
editor.document.enqueueChanges(() => editor.document.batch().setAttribute(c[1], 'fooClass', 'red-foo'));
To be 100% sure I wrote the whole feature myself. I use the 1.0.0-beta.1 API which is completely different than what you had.
Basically – it works. It isn't 100% correct yet, but I'll get to that.
How to convert an element+attribute pair?
The thing when implementing a feature which needs to convert element + attribute is that it requires handling the element and attribute conversion separately as they are treated separately by CKEditor 5.
Therefore, in the code below you'll find that I used elementToElement():
editor.conversion.elementToElement( {
model: 'foo',
view: 'section'
} );
So a converter between model's <foo> element and view's <section> element. This is a two-way converter so it handles upcasting (view -> model) and downcasting (model -> view) conversion.
NOTE: It doesn't handle the attribute.
Theoretically, as the view property you could write a callback which would read the model element's attribute and create view element with this attribute set too. But that wouldn't work because such a configuration would only make sense in case of downcasting (model -> view). How could we use that callback to downcast a view structure?
NOTE: You can write converters for downcast and upcast pipelines separately (by using editor.conversion.for()), in which case you could really use callbacks. But it doesn't really make sense in this case.
The attribute may change independently!
The other problem is that let's say you wrote an element converter which sets the attribute at the same time. Tada, you load <section class=ohmy> and gets <foo class=ohmy> in your model.
But then... what if the attribute will change in the model?
In the downcast pipeline CKEditor 5 treats element changes separately from attribute changes. It fires them as separate events. So, when your FooCommand is executed on a heading it calls writer.rename() and we get the following events in DowncastDispatcher:
remove with <heading>
insert:section
But then the attribute is changed too (writer.setAttribute()), so we also get:
setAttibute:class:section
The elementToElement() conversion helper listens to insert:section event. So it's blind to setAttribute:class:selection.
Therefore, when you change the value of the attribute, you need the attributeToAttribute() conversion.
Sequencing
I didn't want to reply to your question before we released 1.0.0-beta.1 because 1.0.0-beta.1 brought the Differ.
Before 1.0.0-beta.1 all changes were converted immediately when they were applied. So, rename() would cause immediate remove and insert:section events. At this point, the element that you got in the latter one wouldn't have the class attribute set yet.
Thanks to the Differ we're able to start the conversion once all the changes are applied (after change() block is executed). This means that the insert:section event is fired once the model <foo> element has the class attribute set already. That's why you could write a callback-based converters... bur you shouldn't :D
The code
import { downcastAttributeToAttribute } from '#ckeditor/ckeditor5-engine/src/conversion/downcast-converters';
import { upcastAttributeToAttribute } from '#ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
class FooCommand extends Command {
execute( options = {} ) {
const model = this.editor.model;
const fooClass = options.class;
model.change( writer => {
const blocks = model.document.selection.getSelectedBlocks();
for ( const block of blocks ) {
if ( !block.is( 'foo' ) ) {
writer.rename( block, 'foo' );
writer.setAttribute( 'class', fooClass, block );
}
}
} );
}
}
class FooPlugin extends Plugin {
init() {
const editor = this.editor;
editor.commands.add( 'foo', new FooCommand( editor ) );
editor.model.schema.register( 'foo', {
allowAttributes: 'class',
inheritAllFrom: '$block'
} );
editor.conversion.elementToElement( {
model: 'foo',
view: 'section'
} );
editor.conversion.for( 'upcast' ).add(
upcastAttributeToAttribute( {
model: 'class',
view: 'class'
} )
);
editor.conversion.for( 'downcast' ).add(
downcastAttributeToAttribute( {
model: 'class',
view: 'class'
} )
);
// This should work but it does not due to https://github.com/ckeditor/ckeditor5-engine/issues/1379 :(((
// EDIT: The above issue is fixed and will be released in 1.0.0-beta.2.
// editor.conversion.attributeToAttribute( {
// model: {
// name: 'foo',
// key: 'class'
// },
// view: {
// name: 'section',
// key: 'class'
// }
// } );
}
}
This code works quite well, except the fact that it converts the class attribute on any possible element that has it. That's because I had to use very generic downcastAttributeToAttribute() and upcastAttributeToAttribute() converters because of a bug that I found (EDIT: it's fixed and will be available in 1.0.0-beta.2). The commented out piece of code is how you it should be defined if everything worked fine and it will work in 1.0.0-beta.2.
It's sad that we missed such a simple case, but that's mainly due to the fact that all our features... are much more complicated than this.

Customize DateTimeField in Vaadin 8

In DateTimeField component, it displays both date (year, month, day) and hour (hour, minute, second).
Now i don't want to get date. Any idea to only allow to show and get time ( hour:minute:second) ?
tl;dr
No built-in way to display time-of-day only, as of Vaadin 8.1.
You can make your own.
Details
The existing DateTimeField]() widget supports only the legacy GregorianCalendar class which is a combination of a date and a time-of-day plus a time zone. So not useful for time-of-day only values.
Unfortunately, as of Vaadin 8.1, it seems the bundled field widgets have not yet been updated for the java.time types such as the java.time.LocalTime you would want.
As a workaround for the lack of an intelligent LocalTime-savvy field, I suggest either:
Try the date-time-fields Add-on.An add-on is an extension you can add to your Vaadin project, to deliver some nugget of Vaadin-related functionality. An add-on may be visual widget related, or may be non-visual backend feature. If visual such as this, you may need to do a rebuild of your project to cause the widgetset to be re-created. Perhaps a Maven clean and install (not sure as the technique for this keeps changing with various Vaadin releases).
Make your own. Use a regular text field. Write a validator to verify user input parses as a LocalTime object. You have a choice of writing a Vaadin-specific validator or a standard Bean Validation validator. See How to add Validators in Vaadin 8?
Example
Here is some rough code for creating your own LocalTime-savvy field. This is by no means complete, but may help point you in the right direction.
final Label whenLabel = new Label( "when?" );
final TextField whenField = new TextField( );
whenField.setCaption( "When:" );
whenField.setValueChangeMode( ValueChangeMode.BLUR );
whenField.addValueChangeListener( new HasValue.ValueChangeListener < String >( )
{
static final long serialVersionUID = 201710132100L;
#Override
public void valueChange ( HasValue.ValueChangeEvent < String > valueChangeEvent )
{
String input = whenField.getValue( );
System.out.println( "input: " + input );
try
{
// DateTimeFormatter f = DateTimeFormatter.ISO_LOCAL_TIME; // Constant ISO_LOCAL_TIME is for time-of-day in standard ISO 8601 format.
// DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( Locale.CANADA_FRENCH ); // Automatically localize.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( Locale.US ); // Automatically localize.
LocalTime localTime = LocalTime.parse( input , f );
String timeIso8601 = localTime.toString( );
whenLabel.setValue( timeIso8601 );
} catch ( DateTimeParseException e )
{
whenLabel.setValue( e.getClass().getCanonicalName() );
System.out.println( "ERROR - failed to parse input: " + input );
}
}
} );
In my solution I used a TextField and added a custom validator to the relevant binder:
.withValidator(this::validateTime, "Invalid time")
I implemented the validate method as follows:
private boolean validateTime(final String timeString) {
try {
LocalTime.parse(timeString);
return true;
} catch (final DateTimeParseException e) {
return false;
}
}
now Vaadin 14.2.x provided new DateTimePicker component to solve this problem.
https://vaadin.com/releases/vaadin-14

Additional parameters of GUILayout.Label

The Unity manual does not give examples of the params in the following particular version of GUILayout.Label (or is it somewhere else that I cannot seem to find?)
public static void Label(Texture image, GUIStyle style, params GUILayoutOption[] options);
So, I am wondering how to change the font size of the following code that I am dealing with:
I have a normal OnGUI() in an Editor file:
GUILayout.BeginHorizontal( displayStyle1 );
GUILayout.Label( "Has title?" );
if ( hasTitle )
{
if( GUILayout.Button( "yes", GUILayout.Width(40) ) )
{
hasTitle = true;
}
GUILayout.EndHorizontal();
}
and I have my own MyOnGUI() in an Executor file:
if( fieldInput.HasTitle )
{
GUILayout.BeginHorizontal( displayStyle1 );
GUILayout.Label( fieldInput.Title, displayStyle1 );
GUILayout.EndHorizontal();
}
Once you press yes and enter the title in the Editor, what you get after the Executor runs needs to be in bigger font, so I thought I should modify this line:
GUILayout.Label( fieldInput.Title, displayStyle1 );
therefore, I need to see an example of how to specify a bigger font as 3rd parameter...
Is this possible? Is it the right way of directly changing font size without modifying the set styles?
var style= GUI.skin.GetStyle("label");
style.fontSize = 24; // whatever you set
GUILayout.Label( fieldInput.Title, style);

Resources