I am following Testing in Jetpack Compose Codelab but I am unable to print the Semantics tree using the printToLog function on a node. I am using this code inside the androidTest package.
import androidx.compose.ui.test.printToLog
...
//testing function
#Test
fun rallyTopAppBarTest() {
val allScreen = RallyScreen.values().toList()
testRule.setContent {
//the component be tested in isolation goes here
RallyTopAppBar(
allScreens = allScreen,
onTabSelected = {},
currentScreen = RallyScreen.Accounts
)
}
testRule.onRoot().printToLog("currentLabelExists")
....
}
I have checked my LogCat with both Debug and Verbose filtering using "currentLabelExists" tag but the Semantics Tree is not printing on the log.
Any ideas on what I might be missing out.
I can see the semantics tree.
Check if Android Studio Logcat has "No Filters"
Edit
It seems to be a bug as I can sometimes see the logs even if I select "Show only selected application".
Since I just ran into the same problem:
The SemanticsTree seems to appear only when you run your tests in Debug Mode
Related
There is a special case in our code where we need to call setText with getText of the same TextView. SonarLint warn this with kotlin:S1656, to suppress it we use #SuppressWarnings annotation but it does not work. It started showing an error to the IDE and the warning from SonarLint still there. //NOSONAR is not working as well
No action is available as well for suppressing it.
Can you put the SuppressWarnings annotation before your method?
// Sonarlint plugin version 6.8.0.50884
#SuppressWarnings("kotlin:S1656")
fun yourMethod() {
// ...
withContext(coroutineDispatcherMain) {
// Set the text again to fix images overlapping text
htmlTextView.text = htmlTextView.text
}
}
I also wonder that if htmlTextView.invalidate() would work for you.
UPDATE:
SuppressWarnings annotation is also available for LOCAL_VARIABLE but I think the problem is more complicated in kotlin code.
If you examine the byte code of these lines below, you can see that some.num = ... is some.setNum(...) in byte code.
Sonar plugin's code analyser may not handle this kind of kotlin specific codes.
class Sonar {
private val some = Something(0)
private var member = 0
#Deprecated("...")
fun myNumber(): Int = 1
fun doThat() {
// local variable working
#SuppressWarnings("kotlin:S1874") // Code annotated as deprecated should not be used
val localNum = myNumber()
// not working
#SuppressWarnings("kotlin:S1874")
some.num = myNumber()
// not working
#SuppressWarnings("kotlin:S1874")
member = myNumber()
// ...
}
}
I found the docs for the issue to confirm its the right number: https://rules.sonarsource.com/kotlin/RSPEC-1656
Also read the source at https://github.com/SonarSource/sonarlint-intellij but not much help.
It seems like "// NOSONAR" is what you want (I know you said you tried it, but did you have the space? And have it at the end of the line?)
htmlTextView.text = htmlTextView.text // NOSONAR
Just a guess here, but you could also try:
#SuppressWarnings("RSPEC:S1656")
lastly to check suppress is working you can ignore everything:
#SuppressWarnings("all")
htmlTextView.text = htmlTextView.text
Big discussion here: Turning Sonar off for certain code
This article also gives you options to choose from: https://docs.codescan.io/hc/en-us/articles/360012109711-Ignoring-violations
When I work with android studio it shows hints very often, I have 2 questions about it:
1) Why do android studio when I press enter (in scenario like on screenshot) makes just
noteRef.get()
.addOnSuccessListener {}
}
instead of
noteRef.get()
.addOnSuccessListener { documentSnapshot -> }
}
Is there a way generate { documentSnapshot -> } automatically?
2) Second problem: imagine, I have code like this:
var planetMarsSize = 0
var planetEarthSize=0
planetMarsSize = 5
for example I made mistake in this code and have to make "planetEarthSize = 5" instead of "planetMarsSize = 5" so i place cursor between "Mars" and "size", delete "Mars" and start tipping "Earth" - in this case Android studio shows me a hint to autocomplete text, I press enter. At the end text become "planetEarthSizeSize = 5" so android studio shows error. How can I make android studio to autocomplete "planetEarthSize" instead of "planetEarthSizeSize"?
Video of problem: https://photos.app.goo.gl/qAbcxtZsV4URwWwR8
1) The only difference between the two methods is that in the second, you can choose the name of the parameter. In the first one, you can access the parameter with it
2) You can press TAB on your keyboard to overwrite the whole variable name (it actually says this in the little dialog that pops up :) )
There are an update in the end of the question. Now I've got to turn on and turn off the error with one line change in a tiny project with all code transcribed below.
The answer of Alexey Romanov is brilliant. Check in the end of the question. it's an amazing and unknown feature of Android Studio environment.
I've found a very kinky error in Kotlin using updated Android 3.4.2.
First I've run my test code in my computer (not Android) using main modules in any kotlin file in my only module. It always works for me, but it has started to give an error that I comment below and then another error that don't allow to run the main module anymore.
Searching in Stack Overflow, one user as claimed that the last described error ends when one uses test files under java folder (Not Android test files)
However is has continued to give the first error, which I commented above, which I managed to reduce to the following schematic example:
class Cl(
var a:Int=0
)
var vCl = arrayListOf<Cl>()
And the main module is:
fun main(){
println("start")
vCl.clear() // error points to this line
println("ok")
}
I just point to fun main() line in test file and click the green icon.
The error message
Exception in thread "main" java.lang.ExceptionInInitializerError
Suddenly the error stops when I've changed one global statement from one file to another file (in the top part, outside any class or function).
var timings = TimingLogger("MyTag", "Your")
It's crazy. I'm freaking out!
Update:
=======
I've made newerror, a new tiny project with one module to reproduce the error decribed in this question. Below is the complete code:
Gradle: No change after project creation.
AndroidManifest.xml: No change after project creation.
activity_main.xml: It is bare bone because all my views are dinamically created:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/myLayout"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=
"br.com.greatsolutions.paulo.myerror.MainActivity">
</RelativeLayout>
The MainActivity.kt code:
package br.com.greatsolutions.paulo.myerror
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
The compiler.kt code
package br.com.greatsolutions.paulo.myerror
import android.util.TimingLogger
var timings = TimingLogger("MyTag", "Your")
class Cl(
var a:Int=0
)
var vCl = arrayListOf<Cl>()
Finally the test.kt code:
package br.com.greatsolutions.paulo.myerror
fun main(){
println("start")
vCl.clear()
println("ok")
}
The complete error message when I run test.kt code in my computer (not in Android):
start
Exception in thread "main" java.lang.ExceptionInInitializerError
at br.com.greatsolutions.paulo.myerror.TestKt.main(test.kt:5)
at br.com.greatsolutions.paulo.myerror.TestKt.main(test.kt)
Caused by: java.lang.RuntimeException: Stub!
at android.util.TimingLogger.<init>(TimingLogger.java:59)
at br.com.greatsolutions.paulo.myerror
.CompilerKt.<clinit>(compiler.kt:5)
... 2 more
And, again, if I put the below declaration inside MainActivity.kt and run the test.kt again in my computer ...
var timings = TimingLogger("MyTag", "Your")
... and the error is gone!
start
ok
For those who want to see to believe:
Conclusion: Now I know how to avoid this crazy error, but I don't understand why it works! Ih theory, the source file that I use to make my declarations should be interchangeable, because all files are in the same module!
Solution of puzzle
Alexey Romanov has hit the nail on the head!
I've researched a little bit more and I've found that Android Studio only executes the declarations in a file if any variable of the scope was used in a computer test.
When
var timings = TimingLogger("MyTag", "Your")
is inside MainActivity.kt, no error is shown.
After I put in this file the following code:
open class Fool(val a:Int=5){
init { println("fool") }
}
class SuperFool(a:Int=8):Fool(a) {
init { println("what a big fool") }
}
var v = SuperFool()
When I put println(v.a) my code in test.kt becomes:
package br.com.greatsolutions.paulo.myerror
fun main(){
println("start")
println(v.a) // new line
vCl.clear()
println("ok")
}
And it gives the same error than before! Take out this line and no error again!
The solution is if one has any declaration of some variable in an Android class in your projet you MUST use lateinit and just initializate in other point of code that will not run in test execution.
In this case one can do
lateinit var timings:TimingLogger
And put the initialization in other place (inside onCreate in MainActivity class, for instance. In my case, immediately before the 1st. call addSplit, one of the methods from TimingLogger class
timings = TimingLogger("MyTag", "Your")
Now my test code gently prints
start
fool
what a big fool
ok
The problem has nothing to do with Kotlin; you can't just use Android classes in code running directly on your computer and not in an emulator, because the versions in the standard jar will crash on first use. They are just there to provide class files with the same names and method signatures as will exist on the device, so that your code can compile (not run!).
Use Robolectric to get a usable-for-JVM-tests version of the Android library.
if I put the below declaration inside MainActivity.kt and run the test.kt again in my computer
Then your test doesn't use any Android classes (see below for details).
It is worth remembering that, within the same module, all declarations, regardless of what file they are in, are executed.
That's wrong. What happens with top-level val/var/fun declarations in Kotlin is that they get wrapped into a single class for each file, so your code works like this:
// compiler.kt
package br.com.greatsolutions.paulo.myerror
object CompilerKt { // you can actually see the name in the stack trace
var timings = TimingLogger("MyTag", "Your")
val vCl = arrayListOf<Cl>()
}
class Cl(
var a:Int=0
)
// test.kt
package br.com.greatsolutions.paulo.myerror
object TestKt {
fun main(){
println("start")
CompilerKt.vCl.clear()
println("ok")
}
}
So calling TestKt.main() forces loading and initialization of CompilerKt because you reference vCl there. This includes calling the constructor TimingLogger("MyTag", "Your") which thrown an exception when the stub library is used.
Calling TestKt.main() does not load MainActivity (which you can confirm by adding some print to that file), so if you move var timings there, nothing in the stub library gets called.
Your missing a an quote on your first line.
I'm confused about the warning in Android Device Monitor that showing me an error about View needed some unique key but the Yellow Box doesn't appears in my screen,
The warning error makes me confused to debugging the apps,
Is there a way how to hide the warning message?
Edited
My question Completely different about This
Reason :
console.disableYellowBox = true is just hide the warning on my screen not in Android Device Monitor like this:
add the following code in your index.js file
console.disableYellowBox = true
// put these lines inside index.js
import {YellowBox} from 'react-native';
YellowBox.ignoreWarnings(['Warning: ...']);
console.disableYellowBox = true;
I am using the Ionic Framework to build a mobile app for Android/iOS. I was able
to build the project for android (ionic build android). When I run the app, it will be only a white screen, that's because there is an error (when you use GapDebug, you can run apps on your phone and you will be able to debug, and see errors). Now if I run it on the desktop browser there really is NO error and everything is working. Below is the error that is shown in GapDebug:
Now when you check the code in service.js line 394:
There's nothing wrong with the code right? If I try to change line 394 to something like key : self.currentUser, there will be NO error and the app will work. What seems to be the problem here?
Not sure why you are making an object's attribute a list? If you want the key to be childQuestionSnapshot.key then remove the square brackets.
If you are trying to update a list of objects, you can do something similar to the below:
var test = [{key: 'thisguy'},{key: 'thatguy'},{key: 'myguy'}]
test.forEach(function(item){
item['key']='newguy'
})
console.log(test)
Do this instead
var updateObj = {};
updateObj[childQuestionSnapshot.key] = self.currentUser;
applicantRef.update(updateObj, function() {
console.log("applicant answers updated");
});