Force autofixture to pass argument to specific constructor - autofixture

I have to use a specific constructor with auto fixture customization.
The application logic requires to change the temperature unit through the constructor. Otherwise the temperature values will be converted and i can't determine the minimum temperature. Is it possible to modify the used constructor parameter?
Update
This seems to be a work around for me:
var tempUnit = new Fixture().Create<TemperatureUnit>();
var temperatureFixture = new Fixture();
//...
temperatureFixture.Customizations.Add(new RandomNumericSequenceGenerator(Convert.ToInt64(GetMinTemperatureForUnit(tempUnit)), long.MaxValue));
//workaround to force autofixture to create weather with unit
weatherFixture.Register<TemperatureUnit>(() => tempUnit);
weatherFixture.Customize<Weather>(weather => weather.FromFactory(new MethodInvoker(new GreedyConstructorQuery()))
.With(x => x.Temperature, temperatureFixture.Create<double>())
.Without(x => x.TempUnit)

Related

StencilJS unit testing keyboard event?

I want to write unit tests for my custom web-components in stencilJs but have no idea how to do it the right way. Here's what I did so far!
.tsx
...
valueFormat(event: Event): void {
const val = (event.target as HTMLInputElement).value;
const format = Number.parseInt(val, 10);
const newVal = format.toLocaleString(undefined, {
minimumFractionDigits: 2,
});
this.value = newVal;
}
.spec.tsx
it('should format value', async () => {
const comp = new MyComponent();
const spy = jest.spyOn(comp, 'valueFormat');
comp.myInputEvent.emit();
expect(spy).toHaveBeenCalled();
});
I want to test the case, when I type a number in the input field that it format it. So my valueFormat() method, I spying on should be called when a Keyboard event is firing. I hope you can help me out!
If you want to test it with Event in mind, I would strongly recommend you to use newSpecPage(https://stenciljs.com/docs/unit-testing) - as this will allow you to construct your component DOM in memory and allow you to test its logic (so you can easily trigger event like click, keyboard or trigger input value change which I assume where your valueFormat() method get called/binded?)
Another approach is to move formatting logic to separate function which takes just input value as an argument like:
formatInputValue(value: string) {
const format = Number.parseInt(value, 10);
const newVal = format.toLocaleString(undefined, {
minimumFractionDigits: 2,
});
return newVal;
}
then you could easily unit test this method by simply constructing component and then calling the method with whatever the value you want to test with (this is useful if you want to test edge cases like null, empty value, non numeric value etc.)
Personally I wouldn't bother creating function as conversion logic seem to be simple - also one advantage of doing testing via DOM (using newSpecPage()) is that if you ever want to change your formatting logic, amount of test code you need to update could be quite small, meaning your test code is bit more maintainable (again just my personal opinion, it's all depends on how complex the formatting logic or the expected input be)

Best approach in moving data from one array to a new array in angular ts

.subscribe((dataChart) => {
// console.log(dataChart)
var forxaxis = []
var cd = [dataChart]
// console.log(cd)
cd.forEach(element => {
forxaxis.push(element.strRequestDate)
console.log(forxaxis)
});
},
Im trying to move my data in the first array into a new array so that I can use it with chart.js. but it didnt work.
dataChart contain 2 column of data. i insert dataChart into an array called cd. then i tried to push one of the column from dataChart which is called strRequestDate into a new array called forxaxis but it just didnt work as per expected. the result is as shown in the image attached.
this is how the data look like. it was called by using sharepoint API
error and the data
You can use array.map property here, so you don't need to push data manually from one array to another
I have taken sample data in dataChart array for demonstration purpose only.
let dataChart = [{strRequestId: 1, strRequestDate: 'ABC'}, {strRequestId: 1, strRequestDate: 'PQR'}];
let forxaxis = dataChart.map(x => x.strRequestDate);
console.log(forxaxis);
Demo
Output:

Overwrite properties in angular forEach

I imagine this is an easy thing to do, but I wasnt able to find the information I was looking for through google. I have popupProperties which is just default stuff. I then call to the service which returns specific overrides depending on the popup. How can I iterate through all of the service's overrides and apply them to the popupProperties?
var popupProperties = getDefaultPopupProperties();
var popupOverrides= popupService.getPopupOverrides(currPopupId);
angular.forEach(popupOverrides, function(popupProperty, propertyName){
//replace defaults with popupData's properties
});
You should have a look at the solution of Josh David Miller which uses the extend method of angular (documentation).
var defaults = {name:'John',age:17,weight:55};
var overrides = {name:'Jack',age:28,color:'brown'};
var props = angular.extend(defaults, overrides);
// result
props: {
name:'Jack',
age:28,
weight:55,
color:'brown'
}
The values are copied in the defaults variable. There is no need of using the return value (var props =).
I presume you mean both functions are returning objects with a number of properties (as opposed to an array).
If so, the following should work - just JavaScript, nothing AngularJS specific:
for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
See this question for more details How can I merge properties of two JavaScript objects dynamically?

Ordering an observable collection with Reactiveui

I am having some difficulty with ordering an observable collection in my ViewModel.
Here is my situation:
In my view model, I have the following list:
public List<TicketModel> Tickets
{
get { return _Tickets.Value; }
set
{
{
this.RaiseAndSetIfChanged(c => c.Tickets, value);
}
}
}
private ObservableAsPropertyHelper<List<TicketModel>> _Tickets;
This list is populated using a ReactiveAsyncCommand:
LoadTickets.RegisterAsyncFunction(x => loadTickets())
.ToProperty(this, x => x.Tickets);
All works so far.
I have another command, SortByCommand which gets called whenever the user wants to sort a collection. The command looks like this:
SortByCommand = new ReactiveCommand(this.WhenAny(c => c.Tickets, ((tickets) => tickets.Value != null && tickets.Value.Count > 0)));
SortByCommand.Subscribe(c => sortTickets((SortByModel)c));
The command also calls a function that orders the collection using an order by clause:
private void sortTickets(SortByModel model)
{
Tickets = Tickets.OrderBy(model.Selector).ToList();
}
Whenever the sortTickets function is called, there is an exception thrown which says:
Unable to cast object of type 'ReactiveUI.ObservableAsPropertyHelper`1[System.Collections.Generic.List`1[Bugmine.Modules.MyPage.Models.TicketModel]]' to type 'System.Collections.Generic.List`1[Bugmine.Modules.MyPage.Models.TicketModel]'.
I have several questions:
1) Why can't I set directly the Tickets model? Do I need to first convert the result of the OrderBy to some sort of observable collection?
2) Is there a better way of doing this?
EDIT: Clarification
The approach I am taking right now is:
The Tickets collection gets reset every x seconds.
As soon as the sortTickets function is called, I will sort and reset this collection by:
Tickets = Tickets.OrderBy(c => c.Name).ToList(); //for example
When the Tickets collection is loaded again, I will check if it should be sorted and sort it before setting the Tickets property.
This feels a bit hacky because I am basically setting the collection at two points - upon loading and upon sorting. Moreover, upon loading I am using the ReactiveUI helper -> ToProperty:
LoadTickets.RegisterAsyncFunction(x => loadTickets())
.ToProperty(this, x => x.Tickets);
Whereas, upon sorting I am doing that myself:
Tickets = Tickets.OrderBy(model.Selector).ToList();
I am wondering if there is a better way to do the sorting using the ReactiveUI approach which I already use upon loading.
Thanks in advance!
Another way to solve this is via CreateDerivedCollection:
SortedTickets = Tickets.CreateDerivedCollection(
x => new TicketViewModel(x),
orderer: (l,r) => SortModel.Selector(l, r), // Returns CompareTo() result
signalReset: this.WhenAny(x => x.SortModel, x => x.Value)); // Reorder on SortModel change
Note that this breaks down if Tickets is set repeatedly (which in this case it is) - you might change your model to initializing Tickets in the ctor, then Clearing and Adding all the items, i.e.
LoadTickets.RegisterAsyncFunction(x => loadTickets())
.Subscribe(x => {
// TODO: Make sure Tickets is a ReactiveCollection
Tickets.Clear();
Tickets.AddRange(x); // Will trigger resorting of SortedTickets
});
Just had a look on Ana's blog http://blog.paulbetts.org/index.php/2010/07/05/reactivexaml-series-implementing-search-with-observableaspropertyhelper/
//
// This is the canonical way to make a read-only property whose value
// is backed by an IObservable
//
ObservableAsPropertyHelper<List<FlickrPhoto>> _Photos;
I think the read-only is the important point there.
Instead you could try using a normal observable where you can use OnNext to push in the new value
private Observable<List<TicketModel>> _Tickets = new Observable<Lis<TicketModel>>();
_Tickets.OnNext(newValue);
Or use a ObservableForProperty<> and just use the property normally
public List<TicketModel> _Tickets { get;set;}
private Observable<List<TicketModel>> _ticketsObservable= ObservableForProperty<..>(x=>x.Tickets);
Both of these methods expose an Observable which we can use later in the sort.
Why not try handling the two inputs into your sort in the same way, then it wont feel so hacky. That way you'll also have an
public SortModel SortModel {get;set;}
Your sort command implementation becomes
SortByCommand.Subscribe(c => _Sort = c));
but then you subsribe to both ticket changes AND sort criteria changes in one, see http://rxwiki.wikidot.com/101samples#toc44 for CombineLatest
new ObservableForProperty<..>(x=>x.SortModel)
.CombineLatest(_ticketsObservable)
.Subscribe( (x,y)=>
{
//Refactor to SortMethod
_tickets = y.OrderBy(x.Selector);
});
I'm pretty sure that the result of OrderBy(..) is an IEnumerable instead of an ObservableCollection. Fortunately though, it has a constructor that can do the conversion, i.e.
Tickets = new ObservableCollection<...>(Tickets.OrderBy(...));
"Better" can be very subjective measure. Firstly you haven't explained the full lifespan of the Tickets collection and the tickets it contains, so we can't really tell.
You might consider using a SortedTickets field/property instead of overwriting your tickets property which you might find you wouldn't need to be an observable collection as you would know when it needs to NotfyProperryChanged from the Tickets observable. It all depends on how frequently your tickets is likely to change.
P.S. Also make sure you have tested what happens to your sorted list when you add another ticket as you can't just

Passing data from CakePHP component to a helper

I need to share data between a component and helper. I'm converting my self-made payment service formdata generator to a CakePHP plugin and I'd like to be able to fill in the payment data from the controller(using a component) and use a helper to print out the data.
Everything I've tried so far have felt a little too hacky, so let me ask you: Is there any elegant way to pass data from a component to a helper?
edit:
I solved this particular situation by adding the original formadata class instance to ClassRegistry during the component initialization. This way the helper too can access the instance using ClassRegistry.
However, this only works for objects, so the question remains open.
Having a similar problem, I found this solution to work best for me.
You could use the helper's __construct method in pair with $controller->helpers array.
Since the Helper::_construct() is called after the Component::beforeRender, you can modify the $controller->helpers['YourHelperName'] array to pass the data to your helper.
Component code:
<?php
public function beforeRender($controller){
$controller->helpers['YourHelperName']['data'] = array('A'=>1, 'B'=>2);
}
?>
Helper code:
<?php
function __construct($View, $settings){
debug($settings);
/* outputs:
array(
'data' => array(
'A' => (int) 1,
'B' => (int) 2
)
)
*/
}
?>
I am using CakePHP 2.0, so this solution should be tested for earlier versions.
Is there any elegant way to pass data from a component to a helper?
Yes, the same way you pass any data to the helper. In your view.
Inside your component I would do something like the following. The beforeRender() action is a CakePHP component callback.
public function beforeRender(Controller $controller) {
$yourVars = 'some data';
$goHere = 'other stuff';
$controller->set(compact('yourVars', 'goHere'));
}
Then in your view you can pass the data off to your helpers just like normal.
// view or layout *.ctp file
$this->YourHelper->yourMethod($yourVars);
$this->YourHelper->otherMethod($goHere);
In addition to what #Vanja, you can also do this just prior to instantiating a new view in your controller:
// In your controller method
// must be set prior to instantiating view
$this->helpers['YourHelperName']['paramsOrAnyName'] = ['var' => $passed_var];
$_newView = new View($this);
$return_result = $_newView->render($element_to_view, $layout);

Resources