I'm trying something quite basic in Rebol. I want to have a simple instance hierarchy - a question base instance and some question sub-instances. And I want to have some instance attributes protected.
What I'm doing now is:
_question: make object! [
id: none
type: none
text: none ]
question-text: make _question [
type: 'text
new: func [
id' [integer!]
text' [string!]
] [
make self [
id: id'
text: text'
protect [ id type text ]
]
]
]
But then this fails:
qt1: question-text/new 1 "q-text1"
qt2: question-text/new 2 "q-text2"
Once I make the second instance qt2, I get:
Script Error: Word id is protected, cannot modify
Next idea is then to move the protected fields out of _question and put them into question_text - even if I wouldn't like that. But that just leads to the same error.
Note: I'm currently doing this with Rebol2, but would ideally also get my things running in Rebol3 and in Red. And I would like to avoid hacks (sure - that's vague, things like Python getitem()/setitem() tricks would be fine). Then I'd prefer to have the fields unprotected.
There are some binding considerations here. This works, but is subject to the quirky nature of Rebol 2's 'protect function and contexts:
new: func [
id' [integer!]
text' [string!]
/local object
][
object: make self []
object/id: id'
object/text: text'
protect bind [ id type text ] 'object
object
]
Related
I am trying to fetch the specifice object from my json files. For now I can fetch any tag instead of the "p" tag from it. you can please have look at the screenshot I have attached.
Click to open the json file
this is how I'm trying to fetch p tag:
'use strict';
const fs = require('fs');
var data = JSON.parse(fs.readFileSync('./me.json'));
data.Document.Decision.forEach(x => {
console.log(x.Texte_Integral.p);
});
This is a weird way of organizing your block, I recommend rewriting/reorganizing the JSON so it is more easily accessible.
There are a few things you have to know before this answer makes sense:
Array indexes
[] resembles an array, you can access each index by doing array[index], for example:
let arr = ['zero', 'one', 'two'];
console.log(arr[0]); //expected output: 'zero'
Bracket Notation
In JavaScript, there are two ways to access a variable's value, either by dot notation or bracket notation. As far as I know, the only differences these have are just the ability to use dynamic input and characters you can't usually use inside a variable's name, for example:
let obj = {
var1: "this is variable1",
var2: {
var3: "this is variable3 inside variable2"
}
}
console.log(obj.var1) //expected output: "this is variable1"
console.log(obj[`var1`]) // expected output: "this is variable1"
console.log(obj.var2.var3) //expected output: "this is variable3 inside variable2"
console.log(obj[`var2`].var3) // expected output: "this is variable3 inside variable2"
console.log(obj[`var2`]["var3"]) // expected output: "this is variable3 inside variable2"
Bracket notation also works inside objects, thus why the variable names inside as a string, like "Document", works.
let obj2 = {
"var1": 1,
["var2"]: 2,
var3: 3
};
console.log(obj2["var1"]) // expected output: 1
// console.log(obj2"var1") is INVALID and does not work
console.log(obj2["var2"]) // expected output: 2
console.log(obj2.var3) // expected output: 3
Coming to the solution
data.Document.Decision.forEach(x => {
console.log(x.Texte_Integral[0].p)
});
This returns ["ASDFDSFDSFSD"], if we wanted to use it as a string and not an array (remember the brackets) then we would access the first index of the array. This would be done by adding [0] at the end.
❕ Solution
data.Document.Decision.forEach(x => {
console.log(x.Texte_Integral[0].p[0])
});
Future Information
About stackoverflow, next time, please share code via code blocks and not screenshots. Thank you for coming to ask your question, we just want it to be easier for us to both understand and access the code! I had to type the whole thing out myself, which could've been easily avoided by just copy/paste-ing the code. If you don't know how to do certain things in the textbox, see the formatting help page.
I'm testing to see that if a user has a currency of "EUR" and another currency of "GBP" displayed at the top of the page, I'm then expecting that a link containing the text "EUR" and another link containing text "GBP" is present further down the page. This is contained in a div called "nav-tabs au-target"
When I run my script I get the following error:
Expected [ true, true ] to be [ true, true ]
This is my page object file:
if(text.indexOf("EUR") >-1 && text.indexOf("GBP") >-1){
expect(element.all(by.linkText("EUR"&&"GBP")).isDisplayed())
.toBe([true, true]);
console.log("EUR AND GBP buyer");}
I've tried to see if "nav-tabs au-target" contains link text "EUR" and "GBP" instead of element.all but struggling to get it to work
Thanks
That is probably not a problem with Protactor or your app but rather with incorrect usage of a Jasmine's API.
In particular:
expect(actualValue).toBe(expectedValue)
will do following check:
actualValue === expectedValue
which won't work for objects or arrays.
For object or arrays, you should use toEqual instead of toBe which will perform a deep comparison between two values.
You can see this in action in the following fiddle.
SuiteScript v1.
Searching on the item record type.
customrecord_sp_ecom_item_infoseo is a custom record type with a field called custrecord_sp_ecom_item_seo that references an item record. It also has a field called custrecord_sp_ecom_description, which is of type text.
I want to search for the items where the word "frozen" appears in custrecord_sp_ecom_description in the linked customrecord_sp_ecom_item_infoseo record and I want to use filter expressions.
Here's my expression:
[
[
"customrecord_sp_ecom_item_infoseo.custrecord_sp_ecom_description",
"contains",
"frozen"
]
]
And here's the error I get:
{"error" : {"code" : "SSS_INVALID_SRCH_FILTER_JOIN", "message" : "An nlobjSearchFilter contains an invalid join ID, or is not in proper syntax: custrecord_sp_ecom_description."}}
If I change the expression to:
[
[
"isonline",
"is",
true
]
]
then it works fine, albeit with the wrong results. So I know filter expressions can work, there's just something wrong with my expression.
How can I make it work?
When using the dot syntax for joins in filter expressions, the prefix of the dot is the ID of the field you are joining through, not the ID of the record type you are joining to (as it looks like you have here).
So, if I am searching Invoices, but I want to filter on the Sales Rep from the related Sales Order, it would look something like:
[
[ 'createdfrom.salesrep', 'anyof', salesReps]
]
Notice that it's not salesorder.salesrep, but rather createdfrom.salesrep because the createdfrom field is what links the record I am searching (Invoices) to the record I am joining (Sales Order). The same applies when using custom records. Your join will be something like custrecord_fieldid.custrecord_sp_ecom_description rather than using the record type.
There | are | so many | Spock | spec examples of how to use its labels, such as:
// when -> then label combo
def "test something"() {
when:
// blah
then:
// blah blah
}
Such label combinations as:
when -> then
given -> when -> then
expect
given -> expect
But nowhere can I find documentation on what the legal/meaningful combinations of these labels are. For instance, could I have:
def "do something"() {
when:
// blah
expect:
// blah
}
Could I? I do not know. What about:
def "do something else"() {
when:
// blah
then:
// blah
expect:
// blah
where:
// blah
}
Could I? Again, I do not know. But I wonder.
I am actually an author of one of the tutorials you have mentioned. I think the best to answer your question would be to really understand what particular labels are for. Maybe then it would be more obvious why certain combinations make sense and other do not. Please refer to original documentation http://spockframework.github.io/spock/docs/1.0/spock_primer.html. It explains really well all labels and their purpose. Also it comes with this diagram:
Which I hope should already tell you a lot. So for instance having both when and expect labels makes not much sense. The expect label was designed to substitute both when and then. The reasoning behind it is well explained in the documentation:
An expect block [...] is useful in situations where it is more natural to describe stimulus and expected response in a single expression.
Spock itself will not allow you to use this combination. If you try to execute following code.
def "test"() {
when:
println("test")
expect:
1==1
}
You will receive an error message like this.
startup failed:
/Users/wooki/IdeaProjects/mylibrary/src/test/groovy/ExampleTest.groovy:
13: 'expect' is not allowed here; instead, use one of: [and, then] #
line 13, column 9.
To my surprise the second of your examples works. However I believe there is really not much gain of using expect here instead of and as I would normally do.
def "do something else"() {
when:
// stimulus
then:
// 1st verification
and:
// 2nd verification
where:
// parametrization
}
The only reason to have expect or and after then is to separate code responsible for verifying the result of executing the code inside when label. For instance to group verifications that are somehow related to each other, or even to separate single verifications but to have a possibility of giving them a description using strings that can be attached to labels in Spock.
def "do something else"() {
when:
// stimulus
then: "1 is always 1"
1 == 1
and: "2 is always 2"
2 == 2
}
Hence, since you are already stating that verification part of the test began (using then block) I would stick to and label for separating further code.
Regarding where label. It works sort of as a loop indicator. So whatever combinations of labels you use before you could always put at the end the where label. This one is not really a part of a single test run, it just enforces the test to be run a number of times.
As well it is possible to have something like this:
def "test"() {
given:
def value
when:
value = 1
then:
value == 1
when:
value = 2
then:
value == 2
}
Using the above, just make sure that your test is not "testing too much". Meaning that maybe a reason why you use two groups of when-then makes a perfect excuse for this test to be actually split into two separate tests.
I hope this answered at least some of your questions.
In this code snippet, fields-types in the end is modified by the to-camel-case function, vs. being passed as a local variable to the parent function:
fields-types: ["First Name" "string" "Last Name" "string" "Age" "int"]
to-camel-case: function [name] [
name/1: lowercase name/1
replace/all name space ""
]
fill-template-body: func [
field-labels-types [block!] /local vars fields-names-types
] [
vars: [member-name member-type]
field-names-types: copy []
foreach [field-label field-type] field-labels-types [
append field-names-types to-camel-case field-label
append field-names-types field-type
]
]
fill-template-body fields-types
Execution gives:
>> fill-template-body fields-types
== ["firstName" "string" "lastName" "string" "age" "int"]
>> fields-types
== ["firstName" "string" "lastName" "string" "age" "int"]
>>
Whereas I would want that fields-types to stay invariant:
fields-types: ["First Name" "string" "Last Name" "string" "Age" "int"]
Of course I can try to circumvent this by modifying to-camel-case to use a copy of name, but that is not something I think I should have to do.
Is there something like the var and val keywords in Scala?
Variable is an ugly word in REBOL, everything - even words - are values. This isn't some semantic newspeak, it's helpful in understanding the way in which REBOL flows.
I think of values as being contained within one giant array in memory, where REBOL (the language) uses words and their contexts to reference and interact with the values. Most REBOL functions operate without duplicating these values:
head lowercase next uppercase str: "abcd"
remove back tail str
This is one of REBOL's most efficient features - you don't need copies for intermediary processes, to require such is wasteful. Think of that array growing where every time you use replace, uppercase or to-camel-case a value is duplicated. Whole processes can be built on the premise of modification rather than duplication - indeed a context can be built without necessarily having to return a value:
remove-spaces: use [space mark][
space: charset " ^-"
[any [mark: space (remove mark) | skip]]
]
parse/all str: "Should Be No Spaces" remove-spaces
The trick then becomes knowing where to copy values, and I think happens to intersect with REBOL's gift for concise expression:
parse/all link: copy title: "An Article on REBOL" remove-spaces
print ["(" link ")" title]
to-camel-case copy field-label
And of course, modification has its limitations. Sometimes it is cleaner building from scratch.
Your camel case function operates on the original value so if you want to preserve the original value, you need to copy it, and return the altered value. Since your function acts on a template it needs to copy the template right??
So, something like this should work:
fill-template-body: func[ labels [block!] /local field-labels-types vars fields-names-types][
field-labels-types: copy labels
..