I have a question for writing Unit test case for the internal function in angular service - unit-testing

getMortgageCreditScore() {
let underwriting = this._pageService.getMainData();
let validborrowers = underwriting.borrowers.filter((element) => element.expDate == null);
if (validborrowers.length > 0) {
if (validborrowers.length == 1) {
// Scenario 1:
// If there is only one borrower on the loan then
// 'Borrower Score' field value will be used as ""Mortgage Credit Score"" irrespective of ""Use Primary Wage Earner's Credit Score"" checkbox is checked or Not checked.
underwriting.mtgCreditRating = validborrowers[0].creditRating;
underwriting.creditRatingBorrowerId = validborrowers[0].borrSkSeq;
} else {
if (underwriting.miscInfo.uwCredScoreOverrideFlag == 'Y') {
// Scenario 3:
// If more than one Borrower exists on the loan and ""Use Primary Wage Earner's Credit Score"" checkbox is checked then
// system will fetch 'Borrower Score' field value of the borrower having maximum income. If income is same for all borrowers, it will fetch the highest credit score of all borrowers.
// This borrower score will be used as ""Mortgage Credit Score"" field value.
let maxIncomeBorrVal = validborrowers.reduce((prev, curr) =>
(prev.grossIncomeInfo.totMonthlySelfEmpIncome > curr.grossIncomeInfo.totMonthlySelfEmpIncome ? prev : curr)
);
let maxIncomeBorr = validborrowers.filter((element) => element.grossIncomeInfo.totMonthlySelfEmpIncome == maxIncomeBorrVal.grossIncomeInfo.totMonthlySelfEmpIncome);
if (maxIncomeBorr.length > 0) {
if (maxIncomeBorr.length == 1) {
underwriting.mtgCreditRating = maxIncomeBorr[0].creditRating;
underwriting.creditRatingBorrowerId = maxIncomeBorr[0].borrSkSeq;
} else {
let maxInomeCreditBorrVal = maxIncomeBorr.reduce((prev, curr) =>
(prev.creditRating > curr.creditRating ? prev : curr)
);
underwriting.mtgCreditRating = maxInomeCreditBorrVal.creditRating;
underwriting.creditRatingBorrowerId = maxInomeCreditBorrVal.borrSkSeq;
}
}
} else {
//Scenario 2:
// If more than one Borrower exists on the loan and ""Use Primary Wage Earner's Credit Score"" checkbox is not checked then
// system will compare the 'Borrower Score' field value of all borrowers to find the minimum value . This minimum value will be used as ""Mortgage Credit Score"" field value.
let minBorr = validborrowers.reduce((prev, curr) =>
(prev.creditRating < curr.creditRating ? prev : curr)
);
underwriting.mtgCreditRating = minBorr.creditRating;
underwriting.creditRatingBorrowerId = minBorr.borrSkSeq;
}
}
}
}
I am unable to write the test case for this function. Can you please help me to write the test case for this function

Related

How to update a variable maintaining the length of a list in a cascade-like structure?

class CoinData {
var _controller = StreamController<Map<String,dynamic>>();
.....
Stream<Map<String,dynamic>> getAllCurrentRates() {
int numAssets = 0;
int counter = 0;
this.listAllAssets()
.then((list) {
if (list != null) {
numAssets = list.length;
List<Map<String, dynamic>>.from(list)
.where((map) => map["type_is_crypto"] == 1)
.take(3)
.map((e) => e["asset_id"].toString())
.forEach((bitCoin) {
this.getCurrentRate(bitCoin)
.then((rate) => _controller.sink.add(Map<String,dynamic>.from(rate)))
.whenComplete(() {
if (++counter >= numAssets) _controller.close();
});
});
}
});
return _controller.stream;
}
.....
}
The length of returned list is around 2500 and this value is assumed by numAssets, however as you see that list is modified later and therefore its length is less, then the evaluation (++counter >= numAssets) is incorrect. So, is it possible to fix that code maintaining its current structure?
.take(3) is temporal, it shall be removed later.

What the event handler if I want to input the value of Time when I change it?

On screen CRCase, I added new field UsrFinishDate and it will generate when I assign the owner for the case and I allowed users to change DateTime of UsrFinishDate if they want. For my purpose are:
For the default value of UsrFinishDate will get from SLAETA when I assign User, it will be calculated.
If owners want to add more days over the SLA so they can change the DateTime on UsrFinishDate and it should get the new Date and current time when they change. But about my problem, it's not calculated correctly because it got time at 12:00 AM or 12:00 PM all the time while I'm changing UsrFinishDate and time it still got the same current time even user have already changed it.
Below is my coding:
protected void CRCase_UsrFinishDate_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e, PXFieldDefaulting InvokeBaseHandler)
{
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
CRCase row = e.Row as CRCase;
CRCaseExt rowExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);
if (row == null || row.AssignDate == null) return;
if (row.ClassID != null && row.Severity != null)
{
var severity = (CRClassSeverityTime)PXSelect<CRClassSeverityTime,
Where<CRClassSeverityTime.caseClassID, Equal<Required<CRClassSeverityTime.caseClassID>>,
And<CRClassSeverityTime.severity, Equal<Required<CRClassSeverityTime.severity>>>>>.
Select(Base, row.ClassID, row.Severity);
if (severity != null && severity.TimeReaction != null)
{
e.NewValue = ((DateTime)row.AssignDate).AddMinutes((int)severity.TimeReaction);
e.Cancel = true;
}
}
if (row.Severity != null && row.ContractID != null)
{
var template = (Contract)PXSelect<Contract, Where<Contract.contractID, Equal<Required<CRCase.contractID>>>>.Select(Base, row.ContractID);
if (template == null) return;
var sla = (ContractSLAMapping)PXSelect<ContractSLAMapping,
Where<ContractSLAMapping.severity, Equal<Required<CRCase.severity>>,
And<ContractSLAMapping.contractID, Equal<Required<CRCase.contractID>>>>>.
Select(Base, row.Severity, template.TemplateID);
if (sla != null && sla.Period != null)
{
e.NewValue = ((DateTime)row.AssignDate).AddMinutes((int)sla.Period);
e.Cancel = true;
}
}
}
protected void CRCase_UsrFinishDate_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
var row = e.Row as CRCase;
CRCaseExt rowExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);
if(rowExt != null)
{
System.DateTime today = (DateTime)rowExt.UsrFinishDate;
System.TimeSpan duration = new System.TimeSpan(0, 0, 0, 0);
rowExt.UsrFinishDate = today.Add(duration);
}
}
It seems not correct at all. Please help!!!
Could you please describe your usage scenario? Especially this information will be helpful:
What date do you want to store in this field?
What do you expect to see there? Date? Time?
DAC field definition and attributes
What do you mean under "duration" field?
Thanks.

Domain switcher button for different languages

I want to create a dropdown menu With English or German as the options in Javascript / jQuery that checks that:
check if on a domain - say happy.com/pizza
if german is selected on dropdown
redirect user to
happy.de/pizza
and I could have a list
if happy.com/pizza got to happy.de/pizza
happy.com/coke got to happy.de/coke
happy.com/juice got to happy.de/juice
etc etc.
I have written the code yet but how would one go about this?
Thanks!
I have written some code but I just need a little help please:
In this scenario I am on the www.something.com/beer page and want it to go to the German Beer Page!
<select>
<option value="1">English</option>
<option value="2">German</option>
</select>
if(value == 2) && is current domain www.something.com/beer{
window.top.location.href = 'www.something.de/beer';
}else if(value == 2) && is current domain www.something.com/cheese{
window.top.location.href = 'www.something.de/cheese';
}else{
do nothing
}
How do I get this to check the value of the dropdown and the domain is currently on?
Here is my Jsfiddle
http://jsfiddle.net/msasz2an/
Thanks again!
function current(arr) {
// discuss at: http://phpjs.org/functions/current/
// original by: Brett Zamir (http://brett-zamir.me)
// note: Uses global: php_js to store the array pointer
// example 1: transport = ['foot', 'bike', 'car', 'plane'];
// example 1: current(transport);
// returns 1: 'foot'
this.php_js = this.php_js || {};
this.php_js.pointers = this.php_js.pointers || [];
var indexOf = function (value) {
for (var i = 0, length = this.length; i < length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
};
// END REDUNDANT
var pointers = this.php_js.pointers;
if (!pointers.indexOf) {
pointers.indexOf = indexOf;
}
if (pointers.indexOf(arr) === -1) {
pointers.push(arr, 0);
}
var arrpos = pointers.indexOf(arr);
var cursor = pointers[arrpos + 1];
if (Object.prototype.toString.call(arr) === '[object Array]') {
return arr[cursor] || false;
}
var ct = 0;
for (var k in arr) {
if (ct === cursor) {
return arr[k];
}
ct++;
}
// Empty
return false;
}

ConcurrentHashMap in JDK7 code explanation (scanAndLockForPut)

The source codes of the method scanAndLockForPut in ConcurrentHashMap in JDK7 says:
private HashEntry<K,V> scanAndLockForPut(K key, int hash, V value) {
HashEntry<K,V> first = entryForHash(this, hash);
HashEntry<K,V> e = first;
HashEntry<K,V> node = null;
int retries = -1; // negative while locating node
while (!tryLock()) {
HashEntry<K,V> f; // to recheck first below
if (retries < 0) {
if (e == null) {
if (node == null) // speculatively create node
node = new HashEntry<K,V>(hash, key, value, null);
retries = 0;
}
else if (key.equals(e.key))
retries = 0;
else
e = e.next;
}
else if (++retries > MAX_SCAN_RETRIES) {
lock();
break;
}
else if ((retries & 1) == 0 &&
(f = entryForHash(this, hash)) != first) {
e = first = f; // re-traverse if entry changed
retries = -1;
}
}
return node;
}
I understand what the codes mean, but what I don't is this else if entry:
else if ((retries & 1) == 0 && (f = entryForHash(this, hash)) != first)
My question is:
Why do we have to do "(retries & 1) == 0"?
EDIT:
I kind of figure it out. It's all because the constant MAX_SCAN_RETRIES:
static final int MAX_SCAN_RETRIES = Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;
In single core processor, MAX_SCAN_RETRIES = 1. So the second time the thread steps into the loop "while(tryLock)", it doesn't have to check whether the first node was changed.
However, in multi cores processor, this will behave like checking whether the first node is changed every 2 times in the while loop.
Is the above explanation correct?
Let's break this down:
1:
(retries & 1) == 0
This returns 1 for odd numbers, 0 for even numbers. Basically, to get past, there's a 1 in 2 chance, if the number is even.
2:
f = entryForHash(this, hash)
f is a temporary variable used to store the value of the latest entry in the segment.
3:
(/* ... */) != first
Checks if the value changed. If it did, it would move the current entry to the start, and re-iterate the linked nodes again in attempt to acquire the lock.
I've asked this question on the concurrency-interest mailing list, and the author(Doug Lea) himself replied:
Yes. We need only ensure that staleness is eventually detected.
Alternating the head-checks works fine, and simplifies use of
the same code for both uni- and multi- processors.
link
So I think this is the end of this question.
I think there are some bugs for the method!
first let us see the put method:
final V put(K key, int hash, V value, boolean onlyIfAbsent) {
HashEntry<K,V> node = tryLock() ? null :
scanAndLockForPut(key, hash, value);//1. scanAndLockForPut only return
// null or a new Entry
V oldValue;
try {
HashEntry<K,V>[] tab = table;
int index = (tab.length - 1) & hash;
HashEntry<K,V> first = entryAt(tab, index);
for (HashEntry<K,V> e = first;;) {
if (e != null) {
K k;
if ((k = e.key) == key ||
(e.hash == hash && key.equals(k))) {
oldValue = e.value;
if (!onlyIfAbsent) {
e.value = value;
++modCount;
}
break;
}
e = e.next;
}
else {
// 2. here the node is null or a new Entry
// and the node.next is the origin head node
if (node != null)
node.setNext(first);
else
node = new HashEntry<K,V>(hash, key, value, first);
int c = count + 1;
if (c > threshold && tab.length < MAXIMUM_CAPACITY)
rehash(node);
else
setEntryAt(tab, index, node);//3. finally, the node become
// the new head,so eventually
// every thing we put will be
// the head of the entry list
// and it may appears two equals
// entry in the same entry list.
++modCount;
count = c;
oldValue = null;
break;
}
}
} finally {
unlock();
}
return oldValue;
}
step: 1. scanAndLockForPut only return null or a new Entry.
step: 2. the node eventualy a new Entry, and the node.next is the origin head node
step: 3. finally, the node become the new head,so eventually every thing we put will be the head of the entry list and it may appears two equals entry in the same entry list when the concurrentHashMap works in a concurrent environment.
That is my opinion, and I am not exactly sure about whether it is right or not. So I hope you all give me some advice,thanks a lot!!

Day(s) of week selection from QT checkbox to Postgresql

I have a group of checkboxes representing the days of a week in my Qt application GUI and I select one or many days, and depending on which boxes are checked, pass a query string to PostgreSQL in order to display certain data on those days -e.g. if I checked monday and wednesday, extract (dow from timestamp) = 1 or extract(dow from timestamp) = 3 should be added to my query. I have just typed a crude solution -though haven't tested yet as I write this-, but I was wondering if there is a shorter -and more elegant- approach that I'm missing out here. The code is as below: -the queryAdditionCalltimePart and queryAdditionCallStampPart strings are later added to the relevant parts of my main query's QString before the main query is executed-
bool checkboxArray[7];
bool mult = false;
checkboxArray[0] = this->ui->checkBoxMonday->isChecked();
checkboxArray[1] = this->ui->checkBoxTuesday->isChecked();
checkboxArray[2] = this->ui->checkBoxWednesday->isChecked();
checkboxArray[3] = this->ui->checkBoxThursday->isChecked();
checkboxArray[4] = this->ui->checkBoxFriday->isChecked();
checkboxArray[5] = this->ui->checkBoxSaturday->isChecked();
checkboxArray[6] = this->ui->checkBoxSunday->isChecked();
QString queryAdditionCalltimePart = "";
QString queryAdditionCalStampPart = "";
int count = 0;
queryAdditionCalltimePart.append("(");
queryAdditionCalStampPart.append("(");
for(int i = 0; i < 7; i++)
{
if(checkboxArray[i] == true)
{
count++;
}
}
int x = 0;
for(int i = 0; i < 7; i++)
{
if(checkboxArray[i] == true)
{
queryAdditionCalltimePart.append("(SELECT EXTRACT(DOW FROM calltime) = '" +QString::number(i+1)+"')");
queryAdditionCalStampPart.append("(SELECT EXTRACT(DOW FROM cal.stamp) = '" +QString::number(i+1)+"')");
}
if(count > 1 && checkboxArray[i] == true)
{
if(x == count - 1)
{
}
else
{
queryAdditionCalltimePart.append("OR");
queryAdditionCalStampPart.append("OR");
x++;
}
}
}
queryAdditionCalltimePart.append(")");
queryAdditionCalStampPart.append(")");
You can add properties to any widget in Qt, http://qt-project.org/doc/qt-4.8/qobject.html#setProperty. The property can have any information that you want.
In your particular case, it would be cleaner to attach the SQL string as a property for each checkbox.
this->ui->checkBoxMonday->setProperty("sql",
"(SELECT EXTRACT(DOW FROM calltime) = '" +QString::number(i+1)+"') OR ";
Once you receive the user input, simply append the check box properties and remove the final OR.