jBehave is it possible to capture pattern with multiple choices? - jbehave

I have the following two almost-identical Steps that verify if a property is either null or not:
#Then("groupId of $allocationName is not null")
public void thenGroupIdOfAllocationIsNotNull(String allocationName) {
// Some logic here
...
assertNotNull(...)
}
#Then("groupId of $allocationName is null")
public void thenGroupIdOfAllocationIsNull(String allocationName) {
// Some logic here
...
assertNull(...)
}
I feel like there must be some better way to handle this null vs non-null use case instead of duplicating the Steps. Is there a way to capture the pattern as in
#Then("groupId of $allocationName {is|is not} null")
public void thenGroupIdOfAllocationIsNull(String allocationName, boolean isNot) {
// Some logic here
...
isNot ? assertNotNull(...) : assertNull(...);
}
How do I achieve that with jBehave?

Enum could be used to provide options:
#Then("groupId of '$allocationName' $nullEqualityCheck null")
public void checkGroupIdOfAllocation(String allocationName, NullEqualityCheck nullEqualityCheck) {
// Some logic here
...
nullEqualityCheck.check(...);
}
public enum NullEqualityCheck {
IS {
public void check(...) {
assertNull(...)
}
},
IS_NOT {
public void check(...) {
assertNotNull(...)
}
};
public abstract void check(...);
}

Related

Custom assertThatThrownBy

after reading this article I was sure to write my own Assertions but I failed. :-(
We have an interface which looks like this:
public class ApplicationException extends RuntimeException {
public String enhancedStatus() {
return getClass().getSimpleName();
}
}
I wrote my own EnhancedStatusAssert like described in the artile.
public class EnhancedStatusAssert extends AbstractAssert<EnhancedStatusAssert, ApplicationException> {
public EnhancedStatusAssert(ApplicationException actual) {
super(actual, EnhancedStatusAssert.class);
}
public static EnhancedStatusAssert assertThat(ApplicationException actual) {
return new EnhancedStatusAssert(actual);
}
public EnhancedStatusAssert hasEnhancedCause(String enhancedStatus) {
isNotNull();
// check condition
if (!actual.enhancedStatus().equals(enhancedStatus)) {
failWithMessage("Expected enhanced status to be <%s> but was <%s>", enhancedStatus, actual.enhancedStatus());
}
return this;
}
}
Which works fine but then I have trouble to override assertThatThrownBy
assertThatThrownBy(() -> { throw new ApplicationException()})
.isInstanceOf(ApplicationException.class)
.hasEnhancedCause("cause");
What is the way to get it to run?
Thanks,
Markus
Try using asInstanceOf https://assertj.github.io/doc/#assertj-core-3.13.0-asInstanceOf you can write your own InstanceOfAssertFactory for your ApplicationException.
If you only have one field to check you can extract it with ... extracting and chain assertions on the extracted value.

Creating a hot observable and adding things to it

I am trying to create a hot observable where I can add stuff to it. Here's an outline of the basic class
public class MyObservable
{
public IObservable<string> Stream;
public MyObservable()
{
Observable.Create...?
}
public void AddString(string eventDescription)
{
//Add to Stream
}
}
Somewhere else in the code I want to be able to do something like
var ob = new MyObservable();
MyObservable.Add("User created");
Then somewhere else something like:
ob.Stream.Subscribe(Console.WriteLine);
I am not really sure how I am supposed to add strings to the observable
edit: I've tried doing something like this, but I'm not sure if maybe I'm not doing things in the way it's supposed to be done
private IObserver<string> _observer;
public void Add(string e)
{
if(Stream == null)
{
Stream = Observable.Create<string>(
(IObserver<string> observer) =>
{
_observer = observer;
observer.OnNext(e);
return Disposable.Empty;
});
}
else
{
_observer.OnNext(e);
}
}
You should do a little more reading on the contracts of observables and observers
Regardless, what you are looking for is a Subject, which implements both the Observable and Observer interfaces.
If you still want to wrap it it would look like so:
public class MyObservable
{
private Subject<string> subject;
public IObservable<string> Stream
{
get { return this.subject.AsObservable();
}
public MyObservable()
{
subject = new Subject<string>();
}
public void AddString(string eventDescription)
{
//Add to Stream
this.subject.OnNext(eventDescription);
}
}

How can I retrieve a value from IsolatedStorage in other class?

I have two classes. First is using for store boolean value from ToggleSwitchButton by using IsolatedStorage.
Like this...
private void tglSwitch_Checked(object sender, RoutedEventArgs e)
{
System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings["EnableLocation"] = true;
}
private void tglSwitch_Unchecked(object sender, RoutedEventArgs e)
{
System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings["EnableLocation"] = false;
}
The second class will use the boolean value from the first class to do something.
Like this...
if(booleanValFromFirst){
//Do something
}
else{
//Do something
}
Thanks.
Is this, what you want?
if ((bool)System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings["EnableLocation"] == true)
P.S. I would recommend for you to create a single class for all values, stored in Application Settings and work with it.
Like this:
public static class SettingsManager
{
private static IsolatedStorageSettings appSettings;
public static IsolatedStorageSettings AppSettings
{
get { return SettingsManager.appSettings; }
set { SettingsManager.appSettings = value; }
}
public static void LoadSettings()
{
// Constructor
if (appSettings == null)
appSettings = IsolatedStorageSettings.ApplicationSettings;
// Generate Keys if not created
if (!appSettings.Contains(Constants.SomeKey))
appSettings[Constants.SomeKey] = "Some Default value";
// generate other keys
}
}
Then you can work with that class instance
Initialize it at your startup class as SettingsManager.LoadSettings();
an then in any class just call for it:
if ((bool)SettingsManager.AppSettings[Constants.SomeBoolKey])
doSomething();

How to detect file changes in Intellij-idea?

I want to build a simple idea plugin, which will detect the changes of a kind of file, then convert them to another format.
Current, I use such code to do this:
VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
#Override
public void contentsChanged(VirtualFileEvent event) {
// do something
}
});
It works, but not efficient.
I found this article says:
The most efficient way to listen to VFS events is to implement the BulkFileListener interface and to subscribe with it to the VirtualFileManager.VFS_CHANGES topic.
But I can't find any example to implement it. How to do that?
I guess you'll have found the answer by now, but for others it seems to work like this
public class A implements ApplicationComponent, BulkFileListener {
private final MessageBusConnection connection;
public A() {
connection = ApplicationManager.getApplication().getMessageBus().connect();
}
public void initComponent() {
connection.subscribe(VirtualFileManager.VFS_CHANGES, this);
}
public void disposeComponent() {
connection.disconnect();
}
public void before(List<? extends VFileEvent> events) {
// ...
}
public void after(List<? extends VFileEvent> events) {
// ...
}
...
}

Refactoring two basic classes

How would you refactor these two classes to abstract out the similarities? An abstract class? Simple inheritance? What would the refactored class(es) look like?
public class LanguageCode
{
/// <summary>
/// Get the lowercase two-character ISO 639-1 language code.
/// </summary>
public readonly string Value;
public LanguageCode(string language)
{
this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
}
public static LanguageCode TryParse(string language)
{
if (language == null)
{
return null;
}
if (language.Length > 2)
{
language = language.Substring(0, 2);
}
try
{
return new LanguageCode(language);
}
catch (ArgumentException)
{
return null;
}
}
}
public class RegionCode
{
/// <summary>
/// Get the uppercase two-character ISO 3166 region/country code.
/// </summary>
public readonly string Value;
public RegionCode(string region)
{
this.Value = new RegionInfo(region).TwoLetterISORegionName;
}
public static RegionCode TryParse(string region)
{
if (region == null)
{
return null;
}
if (region.Length > 2)
{
region = region.Substring(0, 2);
}
try
{
return new RegionCode(region);
}
catch (ArgumentException)
{
return null;
}
}
}
It depends, if they are not going to do much more, then I would probably leave them as is - IMHO factoring out stuff is likely to be more complex, in this case.
Unless you have a strong reason for refactoring (because you are going to add more classes like those in near future) the penalty of changing the design for such a small and contrived example would overcome the gain in maintenance or overhead in this scenario. Anyhow here is a possible design based on generic and lambda expressions.
public class TwoLetterCode<T>
{
private readonly string value;
public TwoLetterCode(string value, Func<string, string> predicate)
{
this.value = predicate(value);
}
public static T TryParse(string value, Func<string, T> predicate)
{
if (value == null)
{
return default(T);
}
if (value.Length > 2)
{
value = value.Substring(0, 2);
}
try
{
return predicate(value);
}
catch (ArgumentException)
{
return default(T);
}
}
public string Value { get { return this.value; } }
}
public class LanguageCode : TwoLetterCode<LanguageCode> {
public LanguageCode(string language)
: base(language, v => new CultureInfo(v).TwoLetterISOLanguageName)
{
}
public static LanguageCode TryParse(string language)
{
return TwoLetterCode<LanguageCode>.TryParse(language, v => new LanguageCode(v));
}
}
public class RegionCode : TwoLetterCode<RegionCode>
{
public RegionCode(string language)
: base(language, v => new CultureInfo(v).TwoLetterISORegionName)
{
}
public static RegionCode TryParse(string language)
{
return TwoLetterCode<RegionCode>.TryParse(language, v => new RegionCode(v));
}
}
This is a rather simple question and to me smells awefully like a homework assignment.
You can obviously see the common bits in the code and I'm pretty sure you can make an attempt at it yourself by putting such things into a super-class.
You could maybe combine them into a Locale class, which stores both Language code and Region code, has accessors for Region and Language plus one parse function which also allows for strings like "en_gb"...
That's how I've seen locales be handled in various frameworks.
These two, as they stand, aren't going to refactor well because of the static methods.
You'd either end up with some kind of factory method on a base class that returns an a type of that base class (which would subsequently need casting) or you'd need some kind of additional helper class.
Given the amount of extra code and subsequent casting to the appropriate type, it's not worth it.
Create a generic base class (eg AbstractCode<T>)
add abstract methods like
protected T GetConstructor(string code);
override in base classes like
protected override RegionCode GetConstructor(string code)
{
return new RegionCode(code);
}
Finally, do the same with string GetIsoName(string code), eg
protected override GetIsoName(string code)
{
return new RegionCode(code).TowLetterISORegionName;
}
That will refactor the both. Chris Kimpton does raise the important question as to whether the effort is worth it.
I'm sure there is a better generics based solution. But still gave it a shot.
EDIT: As the comment says, static methods can't be overridden so one option would be to retain it and use TwoLetterCode objects around and cast them, but, as some other person has already pointed out, that is rather useless.
How about this?
public class TwoLetterCode {
public readonly string Value;
public static TwoLetterCode TryParseSt(string tlc) {
if (tlc == null)
{
return null;
}
if (tlc.Length > 2)
{
tlc = tlc.Substring(0, 2);
}
try
{
return new TwoLetterCode(tlc);
}
catch (ArgumentException)
{
return null;
}
}
}
//Likewise for Region
public class LanguageCode : TwoLetterCode {
public LanguageCode(string language)
{
this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
}
public static LanguageCode TryParse(string language) {
return (LanguageCode)TwoLetterCode.TryParseSt(language);
}
}