How can I create a class method using AppleScriptObjC - applescript-objc

I'm trying to override the +initialize method of a class using ASOC, but I cannot find a way to override a class method. Is it even possible?
Not to let any confusion possible about the language I'm talking about, here's some code:
script FLAppDelegate
property parent: class "NSObject"
-- -- Class Methods -- --
-- Insert code here
end script

I've done some tests, and as far as I can tell, weird as it is, methods defined using AppleScriptObjC are both class and instance methods.
Let's say I have an AppleScriptObjC file:
script iTunesController
property parent: class "NSObject"
on playpause()
tell application id "com.apple.iTunes" to playpause
end playpause
end script
In an Objective-C method, both:
- (void)callASOC
{
iTunesControllerInstance = [NSClassFromString(#"iTunesController") new];
[iTunesControllerInstance playpause];
[iTunesControllerInstance release];
}
and
- (void)callASOC
{
[NSClassFromString(#"iTunesController") playpause];
}
will call the playpause handler in the AppleScriptObjC file. The latter formulation will generate a warning a compile time, but works.
I was not able to find any documentation confirming or refuting this.

Thanks to #Friziab who reminded me of the NSClassFromString
So I could call a AppleScriptObjC method in my AppDelegate.applescript from another class (script) (NSView subclass)
I don't use AppleScriptObjC so there may be a proper way of doing it but this worked
current application's NSClassFromString("AppDelegate")'s popWindow()

Related

Intellij: How to run all main() methods in a folder?

In IntelliJ there is a feature that runs all unit tests in a folder.
Is there any possibility to run all main() methods in the same way?
Not that I am aware of.
Workaround with wrapper class:
Create a class with a main method and call every main method in that method.
If these classes with main methods changes a lot, you could use this Reflection Library with the following code to scan for classes with a main method:
Reflections reflections = new Reflections("your.package.with.main.classes");
Set<Class<? extends Object>> allClasses =
reflections.getSubTypesOf(Object.class);
The allClasses set contains all classes in that package.
The following code would filter for classes that have a main method:
Set<Class> mainClasses = allClasses.stream()
.filter(clazz ->
Arrays.stream(clazz.getMethods())
.anyMatch(method ->
method.getName().equals("main")))
.collect(Collectors.toSet());
Calling the main method should not be problem anymore.
PS: A filtering for static and public modifier would be a good idea as well.

Reading appsettings.json directly, or accessing IOptions<T> from an Extension method

I have an extension method which is used to read a particular claim from the current ClaimsPrincipal. But I also need to check this value against a list of items which I have in the appsettings.json.
I had this working by using a ConfigurationBuilder() to read the appsettings directly in much the same way as the startup does, although instead of using
.SetBasePath(Directory.GetCurrentDirectory())
as I do in the startup, I was using
.SetBasePath(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location))
Which although isn't pretty, works fine.
However, when the Unit tests are run none of the following get me to where the appsettings are
Directory.GetCurrentDirectory()
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
and I cannot see a way of getting the IHostingEnvironment or something similar into the extension method to read out the appsettings, or indeed to ditch the ConfigurationBuilder() and get at IOptions in the extension method, in such a way that the unit test and the running code will work correctly.
I assume there must be a way of doing this? Although I expect that I should simply not be trying at all and lift the check against the list of items into another class entirely...
Putting business logic that may ever require dependencies into static methods is not recommended. This makes it difficult to inject dependencies into them. Options are few:
Redesign the static method into a service so dependencies can be injected through the constructor. (Recommended)
public class Foo : IFoo
{
private readonly IOptions<FooOptions> optionsAccessor;
public Foo(IOptions<FooOptions> optionsAccessor)
{
this.optionsAccessor = optionsAccessor ??
throw new ArgumentNullException(nameof(optionsAccessor));
}
public void DoSomething()
{
var x = this.optionsAccessor;
// Same implementation as your static method
}
}
Inject the dependencies as parameters of the extension method.
public static void DoSomething(this object o, IOptions<FooOptions> optionsAccessor)
{
// Implementation
}
Redesign the static method to be a facade over an abstract factory like this example.

PHPUnit: mock non-existing classes

Is it possible to create a mock of non-existing class in PHPUnit?
Let's assume I have some class that creates instance of another class, for example:
class TaskRunner
{
public function runTasks()
{
// Run through some loop to get tasks and store each in $taskName
// Get task instance by given task name
$task = $this->getTaskInstance($taskName);
if ($task instanceof AbstractTask) {
$task->run();
}
}
protected function getTaskInstance($taskName)
{
// Just an example
return new $taskName();
}
}
I would like to run unit test for runTasks method to check if created task instace extends some abstract class.
Is there any possibility to NOT to create sample class in a filesystem to check the inheritance constraint?
Thanks for all!
Yes, it is possible to stub/mock classes that do not exist with PHPUnit. Simply do
$this->getMockBuilder('NameOfClass')->setMethods(array('foo'))->getMock();
to create an object of non-existant class NameOfClass that provides one method, foo(), that can be configured using the API as usual.
Since PHPUnit 9, you shall replace :
'NameOfClass' by \stdClass::class
setMethods by addMethods
$this->getMockBuilder(\stdclass::class)->addMethods(array('foo'))->getMock();
The accepted answer is perfect, except that since PHPUnit 9 there is an issue, if you need to mock a class that is required to be of a certain instance. In that case \stdclass::class cannot be used.
And using
$this->getMockBuilder('UnexistentClass')->addMethods(['foo'])->getMock();
will result in Class UnexistentClass does not exist, because addMethod checks the given methods against the given class methods.
In case anybody else is having the same issue, luckly setMethods still works, so this still works in PHPUnit 9
$this->getMockBuilder('UnexistentClass')->setMethods(['foo'])->getMock();
Note though that setMethods will be removed in PHPUnit 10
Hopefully at that time there will be a fix for this issue. Like for example checking if allowMockingUnknownTypes is set to true. If that check is implemented this will then work too:
$this->getMockBuilder('UnexistentClass')->allowMockingUnknownTypes()
->addMethods(['foo'])->getMock();

Ember: adding a mixin to a class after it's been created

I want to add a mixin to an Ember class which has already been created. (The class is defined in a library, actually Ember itself; it's LinkView).
I see that we can do mixin.apply(obj), but this applies the mixin to an instance of the class. I want to add the mixin to the class, so it's automatically mixed-in to all newly created objects.
I attempted to override the init method of the class, using reopenClass, and do mixin.apply(this) there, to apply the mixin to the instance, and then call the original init method, but this does not seem to work because the mixin wiring is set up in the init method and it's already too late by the time I can get to it.
reopenClass does not seem to accept a mixin argument like extend does. Its code seems to suggest that it's doing something with mixins, but whatever it is it doesn't work:
a = Ember.Object.extend().reopenClass(Ember.Mixin.create({mixval: 1});
a.create().get('mixval'); // undefined
I know that I could create my own class with MyLinkView = Ember.LinkView.extend(mixin, ..., but unfortunately the original class name is referenced explicitly within the library, so I really would prefer to figure out how to extend that original class with my mixin.
I experimented with Ember.LinkView = Ember.LinkView.extend(mixin, .... This somehow seems dangerous, although it seems to work. But in this particular case it doesn't help me since the reference within the Ember code (in the definition of the {{link-to}} helper) is to an internal version of the class, not the fully qualified Ember.LinkView.
Any ideas?
The solution is simply
Klass = Parent.extend({init: {...}});
Mixin = Ember.Mixin.create({init: {...}});
Klass.reopen(mixin);
Everything works as expected, including the super chain. In other words, a call to Klass.create().init() will call the mixin's init, and a call to super from there will call the original Klass#init.
In the course of researching this question, I discovered something interesting about reopen. Even if the argument is not a mixin, it is treated as one (internally, it actually creates a temporary one). This means that if you do
Klass.reopen({
init: function() {
this._super.apply(this, arguments);
}
});
The call to super is actually calling the original init, not the init in the parent class. In other words, specifying init in a reopen does not replace the existing init on the class, it more or less layers on top of it. I can't see this behavior documented anywhere in the Ember docs, but it does seem useful in the right situation.

fake directories for .net unit testing

I'm trying to create a unit test for a code similar to this:
foreach (string domainName in Directory.GetDirectories(server.Path))
{
HandleDomainDirectory(session, server, domainName);
}
The problem is that I'm using the System.IO.Directory class in my code.
How can I create a testing method that won't be dependent on any folder I have on my hard disk.
In other words, How can I fake the response of "Directory.GetDirectories(server.Path)"?
(Please note, I do control the "server" object in my class, therefore i can give any path i want)
Thanks.
Rather than calling Directory.GetDirectories(server.Path) directly, you could create an interface like IDirectoryResolver with a single method that takes a path string and returns the list of directories. The class containing your code above would then need a property or field of type IDirectoryResolver, which can be injected through the constructor or a setter.
For your production code, you would then create a new class that implements the IDirectoryResolver interface. This class could use the Directory.GetDirectories method in its implementation of the interface method.
For unit testing, you could create a MockDirectoryResolver class which implements IDirectoryResolver (or use a mocking library to create a mock instance for the interface). The mock implementation can do whatever you need it to do.
You would inject a wrapper class.
public class DirectoryFetcher
{
public virtual List<string> GetDirectoriesIn(string directory)
{
return Directory.GetDirectories(directory);
}
}
And then inject that:
foreach(string directory in _directoryFetcher.GetDirectoriesIn(server.Path))
{
// Whatever
}
You can then Mock that guy at the injection point (this example uses Moq, and constructor injection):
Mock<DirectoryFetcher> mockFetcher = new Mock<DirectoryFetcher>();
mockFetcher.Setup(x => x.GetDirectoriesIn("SomeDirectory")).Returns(new List<string>
{
"SampleDirectory1",
"SampleDirectory2"
});
MyObjectToTest testObj = new MyObjectToTest(mockFetcher.Object);
// Do Test
When communicating with the outside world, such as file system, databases, web services etc. , you should always consider using wrapper classes like the others before me suggested. Testability is one major argument, but an even bigger one is: The out side world changes, and you have no control over it. Folders move, user rights changes, new disk drives appears and old ones are removed. You only want to care about stuff like that in one place. Hence, the wrapper -- let's call it DirectoryResolver like Andy White suggested ealier.
So, wrap your file system calls, extract an interface, and inject that interface where you need to communicate with the file system.
The best solution I've found was to use Moles. The code is very specific, and must do very specific thing. Wrapping it with wrapper class will be redundant. The only reason I needed wrapper class is in order to write tests. Moles allows me to write the tests without any wrapper class :)