Is there a "correct" folder where to place test resources in dart? - dart

I have a simple dart class I am trying to test.
To test it I need to open a txt file, feed the content to an instance of the class and check that the output is correct.
Where do I place this txt file? The txt file is useless outside of testing.
Also, related, how do I acess its directory consistently? I tried placing it in the test folder, but the problem is that:
System.currentDirectory
Returns a different directory if I am running the test on its own or the script calling all the other test dart files on at a time

I check if System.currentDirectory is the directory containing the pubspec.yaml file, if not I move the current directory upwards until I found the directory containing the pubpsec.yaml file and then continue with the test code.

Looks like package https://pub.dev/packages/resource is also suitable for this now.

I have still not found a definitive answer to this question. I've been looking for something similar to the testdata directory in Go and the src/test/resources directory in Java.
I'm using Android studio and have settled on using a test_data.dart file at the top of my test directory. In there I define my test data (mostly JSON) and then import it into my individual tests. This doesn't help if you need to deal with binary files but it has been useful for my JSON data. I'll also inject the JSON language with //language=json so I can open the fragment in a separate window to format.
//language=json
const consolidatedWeatherJson = '''{
"consolidated_weather": [
{
"id": 4907479830888448,
"weather_state_name": "Showers",
"weather_state_abbr": "s",
"wind_direction_compass": "SW",
"created": "2020-10-26T00:20:01.840132Z",
"applicable_date": "2020-10-26",
"min_temp": 7.9399999999999995,
"max_temp": 13.239999999999998,
"the_temp": 12.825,
"wind_speed": 7.876886316914553,
"wind_direction": 246.17046093256732,
"air_pressure": 997.0,
"humidity": 73,
"visibility": 11.037727173307882,
"predictability": 73
}
]
}
''';
Using the Alt + Enter key combination will bring up the Edit JSON Fragment option. Selecting that open the fragment in a new editor and any changes made there (formatting for example) will be updated in the fragment.
Not perfect but it solves my issues.

Related

How to change Xcode project file and folder target membership and visibility using command line/bash script? [duplicate]

Is there a way to change file's target membership in Xcode project via command line?
Here's what I'm trying to do via Xcode's UI:
I also had to do this for CI. After lots of digging, I do not believe this is common enough for anyone to have written a tool to help with doing.
The only conclusion I came to was to edit the project.pbxproj file directly, which is never a great thing to do. None of the tools which claim to do this were of any help until I found this stackoverflow answer on editing the project.pbxproj file. Essentially, you can convert the project.pbxproj file into a JSON format using plutil -convert json project.pbxproj and use a JSON manipulation tool to make those files as headers then point them to be headers of whichever target you would like.
When converting the project.pbxproj into JSON format, be aware that Xcode will no longer be able to show you the project navigator for that project. It will still build and run, however, so this is really only useful if you're planning to do this right before building (such as for CI).
(EDIT: As of July 2022, Xcode will now properly read a JSON version of its .pbxproj to allow you to view your files in the project navigator. I'm not sure which version introduced this, but it is at least now possible with later versions of Xcode.)
The format project.pbxproj as JSON has nearly all the important data under the "objects" key. The file you want to be a header already has an entry with the key being the UUID for the file and a path value you can use to relate the UUID to your file. Here's an example of that format:
// UUID for your file
"65TYSSDXHSLP4UUOAD9D40C322AAGHM9": {
"path": "MyHeader.h", // Your file's name
"isa": "PBXFileReference",
"includeInIndex": "1",
"lastKnownFileType": "sourcecode.c.h",
"sourceTree": "<group>"
}
There's another entry to declare this file as a header, which has its own UUID and a reference to the UUID of your file:
// UUID for your file as a header
"YU3BSD39O9PT5RESDFV741D1": {
"isa": "PBXBuildFile",
"fileRef": "65TYSSDXHSLP4UUOAD9D40C322AAGHM9", // UUID for your file MyHeader.h
"settings": {
"ATTRIBUTES": [
"Public" // could also be Project or Private
]
}
}
Then finally, your target has a list of header files where you will want the UUID for the header reference to go.
"A82GAE9A5HUIO063IOPQAAQIUFGSNXZ": {
"isa": "PBXHeadersBuildPhase",
"buildActionMask": "2147483647",
"files": [
"YU3BSD39O9PT5RESDFV741D1" // UUID for your file as a header
],
"runOnlyForDeploymentPostprocessing": "0"
}
Again, changing the project.pbxproj file directly is never a great idea, but until there's a better tool for making these changes without using Xcode, it's the best I could find. If anyone else is aware of something I'm not, please let me know.

Is there any way of loading local resource files in dart? (not flutter)

I want to load the bytes of a file into a variable while testing my flutter application.
I can't use the assets directory as those are bundled with the app and require WidgetsFlutterBinding.ensureInitialized();
I tried searching the file manually with the path package, but this did not seem to work and was rather hacky. That is why i'm searching for a more official approach.
I was thinking way to complicated ...
As Chuck Batson commented, you can just use the path from the projects root for passing it into the (dart:io) File:
File loadResource(String relativePath) {
final filePath = path.join("test", "resources", relativePath);
return File(filePath);
}
(Notice: The above code makes use of the path package for constructing a file path.)

Load multiple JS files in Firefox Extension

I am creating an extension for Firefox using JPM. In the package.json file, we have this line for the entry point...
"main": "index.js"
How do I change it, or what else can I do, to include more JS files in my extension? I am basically porting a Chrome extension where I have 2-3 JS files.
I tried the following, but it didn't work.
"main": ["index.js", "file2.js"]
"main": [{"index.js", "file2.js"}]
"main": "index.js,file2.js"
To clarify a bit more, both of these files are meant to run in the background and are not content scripts.
As far as I know, through the package.json file you can specify only one main.jsscript .
As the developers' documentation says:
Minimally you'll have a single module implemented by a script called "main.js", but you can include additional modules in lib, and import them using the require() function. To learn how to implement and import your own modules, see the tutorial on Implementing Reusable Modules.
So, you can create your own library in the lib directory, let's say test.js following the documentation and included to your main.js. Take a look at an example of this:
test.js:
vat test = function() {console.log("I'm a module");};
exports.test = test;
and in your main.js:
var test = require('./test');
test.test();
I had the same problem. If you put your 'file2.js' in the 'data' directory you can add the line
var x = require('./data/file2.js');
in the 'main.js' file. Then call your function like:
x.yourFunc();
Be sure to export your functions in file2.js with an assignment to the exports variable for each function:
exports.func1 = function() { return yourFunc(); }

What tools support editing project.pbxproj files?

I want to edit project.pbxproj straight up using command line (for CI server script)
what tools can allow me to do this?
I used to use PlistBuddy to edit the output Info.plist; however, what i really want to do is to edit this user defined field, which is used in multiple places, and i really don't want to have to hunt that down in every plist location
project.pbxproj is an old-style ASCII property list file, too. So you can use /usr/libexec/PlistBuddy to edit it.
Print some User-Defined key's value like this,
# Get the key A83311AA20DA4A80004B8C0E in your project.pbxproj
# LZD_NOTIFICATION_SERVICE_BUNDLE_ID is defined by me,
# Replace key paths with your own.
/usr/libexec/PlistBuddy -c 'print :objects:A83311AA20DA4A80004B8C0E:buildSettings:LZD_NOTIFICATION_SERVICE_BUNDLE_ID' LAAppAdapter.xcodeproj/project.pbxproj
Set its value like this,
/usr/libexec/PlistBuddy -c 'set :objects:A83311AA20DA4A80004B8C0E:buildSettings:LZD_NOTIFICATION_SERVICE_BUNDLE_ID com.dawnsong.notification-service' LAAppAdapter.xcodeproj/project.pbxproj
UPDATE
PlistBuddy will automatically convert project.pbxproj into a xml-format plist file since macOS Catalina (or some earlier version). It's better to move the setting item into xcconfig file instead since xcconfig is much smaller and simpler than project.pbxproj and not easy to make mistakes when editing with perl script.
I know this has been answered for a while, but since the original question is about tools supporting the manipulation of .pbxproj files, and many other people may be looking for the same information, here's how I do it. It took me quite a while to figure this out because I was very unfamiliar with Xcode when I started attempting this, so I hope this saves others the hours of grief I had to put in.
You can use the plutil command to transform the .pbxproj file from the legacy .plist format into an XML or JSON format you will be able to manipulate more easily. I'm using JSON. To do so, just run:
plutil -convert json project.pbxproj
This will convert the format of project.pbxproj, but be aware that -contrary to common sense- the output won't be another file with a JSON extention such as project.json. What will happen is that project.pbxproj will be converted to JSON format, but retain it's cryptic .pbxproj extension. So even though the file's format has been changed, Xcode will still pick it up and use it in its new JSON format.
Then you can change project.pbxproj with ease using any JSON manipulation tool of your choosing. I'm using Groovy's JsonSlurper class in a Groovy script.
Note I also explored the XML option, but I found the project.pbxproj file in XML format to be cumbersome to parse. The elements are not properly nested to allow for traversing the tree with ease. It's plagued with:
<key>someKey</key>
<dict>
<!--More elements which provide configuration for the key above-->
</dict>
So it's positional in nature. You have to look for the key element corresponding to the setting you want to manipulate and then jump to the dict element just after it. Which means you have to mount the children of each XML element into an array, in order to index them.
Here are 3 open-source tools which implement .pbxproj file editing:
https://github.com/CocoaPods/Xcodeproj (Ruby based)
https://github.com/apache/cordova-node-xcode (NodeJS based)
https://github.com/kronenthaler/mod-pbxproj (Python based)
Personally, I made the best experience with the NodeJS based tool. So far it has covered all our needs reliably.
In the following is listed an example javascript file update-project.js which sets the developer team ID, app entitlements, adds a GoogleService-Info.plist file to the project and checks it as part of the build target. Take it as an inspiration and adapt the scripts and its paths to your needs:
const fs = require('fs')
const xcode = require('xcode')
if (process.argv.length !== 3) {
console.error("Please pass the development team ID as the first argument")
process.exit(1)
}
const developmentTeamId = process.argv[2]
const path = 'ios/App/App.xcodeproj/project.pbxproj'
const project = xcode.project(path)
project.parse(error => {
const targetKey = project.findTargetKey('App')
const appGroupKey = project.findPBXGroupKey({path: 'App'})
project.addBuildProperty('CODE_SIGN_ENTITLEMENTS', 'App/App.entitlements')
project.addBuildProperty('DEVELOPMENT_TEAM', developmentTeamId)
project.addFile('App.entitlements', appGroupKey)
project.removeFile('GoogleService-Info.plist', appGroupKey)
const f = project.addFile('GoogleService-Info.plist', appGroupKey, {target: targetKey})
f.uuid = project.generateUuid()
project.addToPbxBuildFileSection(f)
project.addToPbxResourcesBuildPhase(f)
fs.writeFileSync(path, project.writeSync())
})
Above script can be executed with
yarn run update-project <arguments...>
given that update-project is registered in package.json:
{
...,
"scripts": {
...
"update-project": "node update-project.js"
},
...
}

system.io.directorynotfound -> But it works in Console

My files are referenced like so (it's all relative):
// WHERE YOU KEEP THE PAGE TITLE XML
public static string myPageTitleXML = "xml/pagetitles.xml";
and
using (StreamReader r = new StreamReader(myPageTitleXML))
{ //etc.. . .etc....etc..
}
I get system.io.directorynotfound, and "this problem needs to be shut down", when I double click the executable. But running it from the console works like a charm. What's wrong here?
I played around with attempting to set Environment.CurrentDirectory but couldn't get anything to work. Why should I have to do that anyway? It defeats the purpose of a relative path no?
responding.. .
"application" does not exist in the current context, i'll keep trying what people have mentioned, this is not a windows.form
testing
Path.GetDirectoryName(Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), myPageTitleXML); gives error URI formats are not supported, as does Path.GetFullPath(). Server.MapPath results in an error as well, this is currently offline
Well assuming this directory is somewhere under the directory in which your code is executing, it sounds like you can use ..
Application.ExecutablePath()
or
Application.StartUpPath()
.. to get an idea as to what your application is seeing when it goes in search of an 'xml' directory with the 'pagetitles.xml' file in it.
If the directory returned by one of these methods does not point where you thought it did, you'll need to move the location of your application or the location of this folder so that it is within the same directory as the app.
Hope this gets you on the right path.
So, when you run it from double clicking the executable, is there a file named pagetitles.xml in a folder named xml, where xml is a folder in the same location as the executable?
It's certainly possible to use relative paths like this, but I wouldn't really recommend it. Instead, maybe use something like:
string fileToOpen = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), myPageTitleXML);
using (StreamReader r = new StreamReader(fileToOpen))
{
//etc.. . .etc....etc..
}
Is this ASP.NET code? If so then you probably need to do MapPath("xml/pagetitles.xml")

Resources